diff --git a/frame.js b/frame.js index 0fa8bc7f..6e3eda9d 100644 --- a/frame.js +++ b/frame.js @@ -18,10 +18,8 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can._path = location.href can.onengine.signal(can, chat.ONMAIN, can.request()), can.base.isFunc(cb) && cb(can) }) - can.onappend.topic(can, "dark", {topic: "black", plugin: "black", legend: "#212121", input: "#212121", output: "#0d1117", table: "black", - hover: "#212121", border: "gray", label: "silver", text: "white", warn: "red", notice: "blue"}), - can.onappend.topic(can, "light", {topic: "white", plugin: "aliceblue", legend: "lavender", input: "white", output: "white", table: "aliceblue", - hover: "aliceblue", border: "transparent", label: "black", text: "black", warn: "red", notice: "blue"}) + can.onappend.topic(can, html.DARK), can.onappend.topic(can, html.LIGHT, {panel: "white", plugin: "aliceblue", legend: "lavender", input: "white", output: "white", table: "aliceblue", + hover: "aliceblue", border: "transparent", label: "black", text: "black", info: "blue", warn: "red"}) }, _search: function(event, can, msg, panel, cmds, cb) { var sub, mod = can, fun = can, key = ""; can.core.List(cmds[1].split(ice.PT), function(value) { fun && (sub = mod, mod = fun, fun = mod[value], key = value) }) @@ -110,15 +108,14 @@ Volcanos(chat.ONDAEMON, {_init: function(can, name) { if (can.user.isLocalFile) exit: function(can, msg, sub) { can.user.close() }, }) Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { - meta.name = can.core.Split(meta.name||"", "\t .\n").pop() - meta.type != chat.PANEL && meta.type != chat.INPUT && meta.index && (meta.name = meta.index.replaceAll(ice.PT, ice.SP)) + meta.index && (meta.name = meta.index), meta.name = can.core.Split(meta.name||"", "\t .\n").pop() field = field||can.onappend.field(can, meta.type, meta, target)._target var legend = can.page.SelectOne(can, field, html.LEGEND) var option = can.page.SelectOne(can, field, html.FORM_OPTION) var action = can.page.SelectOne(can, field, html.DIV_ACTION) var output = can.page.SelectOne(can, field, html.DIV_OUTPUT) var status = can.page.SelectOne(can, field, html.DIV_STATUS) - meta.type != chat.PANEL && meta.type != html.INPUT && can.page.Append(can, option, [{view: [[html.ITEM, html.ICON], html.DIV, "\u2715"], onclick: function(event) { sub.onaction.close(event, sub) }}]) + meta.index && can.page.Append(can, option, [{view: [[html.ITEM, html.ICON], html.DIV, "\u2715"], onclick: function(event) { sub.onaction.close(event, sub) }}]) var sub = Volcanos(meta.name, {_root: can._root||can, _follow: can.core.Keys(can._follow, meta.name), _target: field, _legend: legend, _option: option, _action: action, _output: output, _status: status, _history: [], _inputs: {}, _outputs: [], Status: function(key, value) { if (can.base.isObject(key)) { return can.core.Item(key, sub.Status), key } @@ -137,18 +134,17 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { Clone: function() { meta.args = can.page.SelectArgs(can) can.onappend._init(can, meta, list, function(sub) { can.base.isFunc(cb) && cb(sub, true), can.onmotion.delay(can, sub.Focus) }, target) }, - }, list, function(sub) { sub.Conf(meta), meta.feature = can.base.Obj(meta.feature, {}) - can.onappend.style(sub, meta.index? meta.index.split(ice.PT): meta.name), can.onappend.style(sub, meta.style), can.onappend.style(sub, sub.Mode()) + }, list, function(sub) { meta.feature = can.base.Obj(meta.feature, {}), sub.Conf(meta) + can.onappend.style(sub, meta.index? meta.index.split(ice.PT): meta.name), can.onappend.style(sub, sub.Conf(ctx.STYLE)), can.onappend.style(sub, sub.Mode()) sub._trans = can.base.Copy(sub._trans||{}, can.core.Value(sub, [chat.ONACTION, chat._TRANS])) can.core.Item(meta.feature, function(key, cb) { cb.help && sub.user.trans(sub, kit.Dict(key, cb.help)) }) meta.msg && can.onmotion.delay(can, function() { var msg = sub.request(); msg.Copy(can.base.Obj(meta.msg)) sub.onappend._output(sub, msg, meta.display||msg.Option(ice.MSG_DISPLAY)||meta.feature.display) }), meta.inputs && sub.onappend._option(sub, meta, sub._option, meta.msg) sub._legend && (sub._legend.onclick = function(event) { - can.user.carte(event, sub, sub.onaction, sub.onaction.list.concat([[ctx.ACTION].concat(can.core.Item(meta.feature._trans))]), function(event, button, meta) { - if (can.request(event).RunAction(event, can.core.Value(sub, chat._OUTPUTS_CURRENT), [ctx.ACTION, button])) { return } - can.request(event).RunAction(event, sub, [ctx.ACTION, button]) || sub.runAction(event, button) - }) + can.user.carte(event, sub, sub.onaction, sub.onaction.list.concat([[ctx.ACTION].concat(can.core.Item(meta.feature._trans))]), function(event, button) { can.misc.Event(event, sub, function(msg) { + msg.RunAction(event, can.core.Value(sub, chat._OUTPUTS_CURRENT), [ctx.ACTION, button]) || msg.RunAction(event, sub, [ctx.ACTION, button]) || sub.runAction(event, button) + }) }) }), can.base.isFunc(cb) && cb(sub) }); return sub }, @@ -163,8 +159,8 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { sub.run = function(event, cmds, cb, silent) { var msg = can.request(event, kit.Dict(chat._TOAST, ice.PROCESS)) msg.RunAction(event, sub, cmds) || msg.RunAction(event, can.core.Value(can, chat._OUTPUTS_CURRENT), cmds) || can.Update(event, can.Input(cmds, !silent), cb, silent) }, can._inputs[item.name] = sub, sub.sup = can - can.core.ItemCB(sub.onaction, function(key, cb) { sub._target[key] = function(event) { cb(can.request(event)._event, sub) } }) - can.core.ItemCB(item, function(key, cb) { sub._target[key] = function(event) { cb(can.request(event)._event, sub) } }) + can.core.ItemCB(sub.onaction, function(key, cb) { sub._target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, sub) })} }) + can.core.ItemCB(item, function(key, cb) { sub._target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, sub) })} }) skip? next(): can.core.CallFunc([sub.onaction, chat._INIT], {can: sub, meta: item, cb: next, target: sub._target}); (item.action||can.core.Value(meta, [ctx.FEATURE, ctx.INPUTS])) && can.onappend.figure(sub, item, sub._target, function(_sub, value) { can.onmotion.focus(can, sub._target, value), can.onmotion.delay(can, function() { can.Update() }) @@ -173,17 +169,20 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { } can.core.Next(can.base.getValid(can.core.Value(can, [chat.ONIMPORT, mdb.LIST]), can.base.Obj(meta.inputs, []))||[], add) }, _action: function(can, list, action, meta) { meta = meta||can.onaction||{}, action = action||can._action, can.onmotion.clear(can, action) - function run(event, button) { var cb = meta[button]||meta[chat._ENGINE]; cb? can.core.CallFunc(cb, {event: event, can: can, button: button}): can.run(event, [ctx.ACTION, button].concat(can.sup.Input()), function(msg) { - if (can.core.CallFunc([can, chat.ONIMPORT, ice.MSG_PROCESS], {can: can, msg: msg})) { return } + function run(event, button) { can.misc.Event(event, can, function(msg) { + var cb = meta[button]||meta[chat._ENGINE]; cb? can.core.CallFunc(cb, {event: event, can: can, button: button}): can.run(event, [ctx.ACTION, button].concat(can.sup.Input()), function(msg) { + if (can.core.CallFunc([can, chat.ONIMPORT, ice.MSG_PROCESS], {can: can, msg: msg})) { return } + }) }) } return can.core.List(can.page.inputs(can, can.base.getValid(can.base.Obj(list), can.core.Value(can, [chat.ONACTION, mdb.LIST]), meta != can.onaction? can.core.Item(meta): [])||[]), function(item) { can.base.isUndefined(item) || can.onappend.input(can, item == ""? /* 1.空白 */ {type: html.BR}: can.base.isString(item)? /* 2.按键 */ {type: html.BUTTON, name: item, value: can.user.trans(can, item, meta._trans), onclick: function(event) { run(event, item) }, onkeydown: function(event) { if (event.key == lang.ENTER) { target.click() }}}: - item.length > 0? /* 3.列表 */ {type: html.SELECT, name: item[0], values: item.slice(1), onchange: function(event) { var button = item[event.target.selectedIndex+1] + item.length > 0? /* 3.列表 */ {type: html.SELECT, name: item[0], values: item.slice(1), onchange: function(event) { can.misc.Event(event, can, function(msg) { + var button = item[event.target.selectedIndex+1] meta[item[0]]? can.core.CallFunc(meta[item[0]], [event, can, item[0], button]): meta[button] && can.core.CallFunc(meta[button], [event, can, button]) - }}: /* 4.其它 */(item.type == html.BUTTON && (item.value = item.value||can.user.trans(can, item.name, meta._trans), item.onclick = item.onclick||function(event) { + }) }}: /* 4.其它 */(item.type == html.BUTTON && (item.value = item.value||can.user.trans(can, item.name, meta._trans), item.onclick = item.onclick||function(event) { run(event, item.name) }), item), "", action) }), meta @@ -193,8 +192,8 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { if (can.base.isFunc(meta.feature[cmds[1]])) { return meta.feature[cmds[1]](can, msg, cmds.slice(2)) } return can.user.input(event, can, meta.feature[cmds[1]], function(args) { can.Update(can.request(event, {_handle: ice.TRUE}, can.Option()), cmds.slice(0, 2).concat(args)) }) } - return can.onengine._plugin(event, can, msg, can, cmds, cb) || can.run(event, cmds, cb||function(msg) { if (silent) { return } - if ((msg._can == can || msg._can == can.core.Value(can, chat._OUTPUTS_CURRENT)) && can.core.CallFunc([can, chat.ONIMPORT, ice.MSG_PROCESS], {can: can, msg: msg})) { return } + return can.onengine._plugin(event, can, msg, can, cmds, cb) || can.run(event, cmds, cb||function(msg) { if (silent) { return } var _can = can._fields? can.sup: can + if (_can == (msg._can._fields? msg._can._fields.sup: msg._can._fields) && can.core.CallFunc([_can, chat.ONIMPORT, ice.MSG_PROCESS], {can: _can, msg: msg})) { return } if (cmds && cmds[0] == ctx.ACTION) { if (can.base.isIn(cmds[1], mdb.CREATE, mdb.INSERT, mdb.IMPORT) || msg.Length() == 0 && msg.Result() == "") { return can.user.toastSuccess(can, cmds[1]), can.Update() } } can.onappend._output(can, msg, meta.display||msg.Option(ice.MSG_DISPLAY)||meta.feature.display) }) @@ -229,54 +228,57 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }) }, - topic: function(can, topic, color, style, list) { const SOLID = " solid 1px", RADIUS = "border-radius", GLASS = "transparent" + topic: function(can, topic, color, style, list) { const PANEL_STYLE = "panel-style", PLUGIN_STYLE = "plugin-style" const LEGEND_STYLE = "legend-style", INPUT_STYLE = "input-style", INPUT_HOVER_STYLE = "input-hover-style", OUTPUT_STYLE = "output-style", GLASS_STYLE = "glass-style" const TABLE_HEAD_STYLE = "table-head-style", TABLE_HEAD_HOVER_STYLE = "table-head-hover-style", TABLE_ROW_HOVER_STYLE = "table-row-hover-style", TABLE_CELL_HOVER_STYLE = "table-cell-hover-style" const ITEM_HOVER_STYLE = "item-hover-style", CARTE_ITEM_HOVER_STYLE = "carte-item-hover-style", CARTE_ITEM_STYLE = "carte-item-style" - const PANEL_STYLE = "panel-style", PLUGIN_STYLE = "plugin-style" - function _bg(color) { var res = {"background-color": color}, arg = arguments; for (var i = 1; i < arg.length; i += 2) { res[arg[i]] = arg[i+1] } return res } - function _fg(color) { var res = {"color": color}, arg = arguments; for (var i = 1; i < arg.length; i += 2) { res[arg[i]] = arg[i+1] } return res } - function _b_r(size) { return {"border-radius": size} } - style = style||kit.Dict(LEGEND_STYLE, _bg(color.legend), + const SOLID = " solid 1px", RADIUS = "border-radius", GLASS = "transparent", INPUT_COLOR = "#212121", OUTPUT_COLOR = "#0d1117" + function _bg(color) { return kit.Dict(html.BACKGROUND_COLOR, color, can.core.List(arguments).slice(1)) } + function _fg(color) { return kit.Dict(html.COLOR, color, can.core.List(arguments).slice(1)) } + function _b_r(size) { return kit.Dict(RADIUS, size) } + color = kit.Dict( + html.PANEL, cli.BLACK, html.PLUGIN, cli.BLACK, html.LEGEND, INPUT_COLOR, html.INPUT, INPUT_COLOR, html.OUTPUT, OUTPUT_COLOR, html.TABLE, cli.BLACK, + html.HOVER, INPUT_COLOR, html.BORDER, cli.GRAY, html.LABEL, "silver", html.TEXT, cli.WHITE, log.INFO, cli.BLUE, log.WARN, cli.RED, color, + ), style = kit.Dict(LEGEND_STYLE, _bg(color.legend), INPUT_STYLE, _bg(color.input, html.COLOR, color.label, RADIUS, "5px", "outline", html.NONE, "box-shadow", html.NONE), INPUT_HOVER_STYLE, _fg(color.text), OUTPUT_STYLE, _bg(color.output), GLASS_STYLE, _bg(GLASS), TABLE_HEAD_STYLE, _bg(color.table, html.COLOR, color.label), TABLE_HEAD_HOVER_STYLE, _bg(color.table, html.COLOR, color.text), - TABLE_ROW_HOVER_STYLE, _bg(color.table), TABLE_CELL_HOVER_STYLE, _bg(color.hover), ITEM_HOVER_STYLE, _bg(color.hover, html.COLOR, color.text), CARTE_ITEM_HOVER_STYLE, _bg(color.input, html.COLOR, color.text), - PANEL_STYLE, _bg(color.topic, html.COLOR, color.label), PLUGIN_STYLE, _bg(color.plugin, RADIUS, "10px"), - ), list = list||[{type: "", style: _fg(color.label)}, - {type: html.LEGEND, style: [INPUT_STYLE, TABLE_HEAD_STYLE, LEGEND_STYLE]}, {type: html.LEGEND, style: [INPUT_HOVER_STYLE]}, + TABLE_ROW_HOVER_STYLE, _bg(color.table), TABLE_CELL_HOVER_STYLE, _bg(color.output), + ITEM_HOVER_STYLE, _bg(color.hover, html.COLOR, color.text), CARTE_ITEM_HOVER_STYLE, _bg(color.input, html.COLOR, color.text), + PANEL_STYLE, _bg(color.panel, html.COLOR, color.label), PLUGIN_STYLE, _bg(color.plugin, RADIUS, "10px"), style, + ), list = [{type: "", style: _fg(color.label)}, + {type: html.LEGEND, style: [INPUT_STYLE, LEGEND_STYLE]}, {type: html.LEGEND, style: [INPUT_HOVER_STYLE]}, {type: html.SELECT, style: [INPUT_STYLE]}, {type: html.SELECT, style: [INPUT_HOVER_STYLE]}, {type: html.INPUT, style: [INPUT_STYLE]}, {type: html.INPUT, style: [INPUT_HOVER_STYLE]}, - {type: html.INPUT+":not([type=button])", style: _b_r(0)}, {type: html.INPUT+":not([type=button])", name: [html.HOVER], style: {border: color.notice+SOLID}}, + {type: html.INPUT+":not([type=button])", style: _b_r(0)}, {type: html.INPUT+":not([type=button])", name: [html.HOVER], style: {border: color.info+SOLID}}, {type: html.TEXTAREA, style: [INPUT_STYLE]}, {type: html.TEXTAREA, style: _b_r(0)}, {type: html.FORM_OPTION, list: [{type: html.DIV_ITEM, name: [html.SELECT], style: [GLASS_STYLE]}]}, {type: html.FORM_OPTION, list: [{type: html.DIV_ITEM, name: [html.HOVER], style: [GLASS_STYLE]}]}, {type: html.DIV_ACTION, list: [{type: html.DIV_ITEM, name: [html.SELECT], style: [GLASS_STYLE]}]}, {type: html.DIV_ACTION, list: [{type: html.DIV_ITEM, name: [html.HOVER], style: [GLASS_STYLE]}]}, - {type: html.DIV_OUTPUT, style: [OUTPUT_STYLE]}, {type: html.DIV_STATUS, style: _fg(color.label)}, + {type: html.DIV_OUTPUT, style: [OUTPUT_STYLE]}, {type: html.DIV_STATUS, style: kit.Dict(_bg(color.plugin), _fg(color.label))}, + {type: html.DIV_CODE, style: {border: color.border+SOLID}}, {type: html.DIV_ITEM, name: [html.SELECT], style: [ITEM_HOVER_STYLE]}, {type: html.DIV_ITEM, style: [ITEM_HOVER_STYLE]}, {type: html.DIV_TABS, list: [{type: html.DIV, style: _bg(color.plugin)}]}, {type: html.DIV_TABS, list: [{type: html.DIV, name: [html.HOVER], style: [OUTPUT_STYLE]}]}, {type: html.DIV_TABS, list: [{type: html.DIV, name: [html.HOVER], style: _fg(color.text)}]}, {type: html.DIV_TABS, list: [{type: html.DIV, name: [html.SELECT], style: [OUTPUT_STYLE]}]}, - {type: html.DIV_PATH, style: [OUTPUT_STYLE]}, {type: html.DIV_CODE, style: {border: color.border+SOLID}}, - {type: html.DIV_PATH, list: [{type: html.SPAN, style: [ITEM_HOVER_STYLE]}]}, + {type: html.DIV_PATH, style: [OUTPUT_STYLE]}, {type: html.DIV_PATH, list: [{type: html.SPAN, style: [ITEM_HOVER_STYLE]}]}, {type: html.DIV_PLUG, list: [{type: html.LEGEND, style: [OUTPUT_STYLE]}]}, {type: html.DIV_PLUG, list: [{type: html.LEGEND, name: [html.SELECT], style: [PLUGIN_STYLE]}]}, {type: "div.zone>div.item", style: [TABLE_HEAD_STYLE]}, {type: "div.zone>div.item", style: [TABLE_HEAD_HOVER_STYLE]}, {type: "div.zone>div.list>div.zone>div.item", style: [TABLE_HEAD_STYLE]}, {type: "div.zone>div.list>div.zone>div.item", style: [TABLE_HEAD_HOVER_STYLE]}, {type: "div.zone div.item>div.name", name: [html.HOVER], style: _fg(color.text)}, - {type: "tr.line.select", style: [ITEM_HOVER_STYLE]}, {type: "tr.line", style: [ITEM_HOVER_STYLE]}, {type: "tr.line>td.line", style: [OUTPUT_STYLE]}, - {type: html.TABLE_LAYOUT, list: [{type: html.DIV_TOGGLE, style: [ITEM_HOVER_STYLE]}]}, + {type: "tr.line.select", style: [ITEM_HOVER_STYLE]}, {type: "tr.line", style: [ITEM_HOVER_STYLE]}, + {type: "tr.line>td.line", style: [OUTPUT_STYLE]}, {type: "tr.line.select>td.line", style: [ITEM_HOVER_STYLE]}, {type: html.TABLE_CONTENT, list: [{type: html.TR, style: [TABLE_ROW_HOVER_STYLE]}]}, {type: html.TABLE_CONTENT, list: [{type: html.TH, style: [TABLE_HEAD_STYLE]}]}, {type: html.TABLE_CONTENT, name: [html.ACTION], list: [{type: html.TD+":last-child", style: [TABLE_HEAD_STYLE]}]}, {type: html.TABLE_CONTENT, list: [{type: html.TD, name: [html.SELECT], style: [TABLE_CELL_HOVER_STYLE]}]}, {type: html.TABLE_CONTENT, list: [{type: html.TD, style: [TABLE_CELL_HOVER_STYLE]}]}, {type: html.H1, style: [ITEM_HOVER_STYLE]}, {type: html.H2, style: [ITEM_HOVER_STYLE]}, {type: html.H3, style: [ITEM_HOVER_STYLE]}, - {type: html.LABEL, style: _fg(color.label)}, {type: html.A, style: _fg(color.notice)}, - {type: html.FIELDSET_FLOAT, style: [PLUGIN_STYLE]}, - {type: html.FIELDSET_PANEL, style: [PANEL_STYLE]}, {type: html.FIELDSET_PANEL, list: [{type: ">"+html.DIV_OUTPUT, style: [PANEL_STYLE]}]}, + {type: html.LABEL, style: _fg(color.label)}, {type: html.A, style: _fg(color.info)}, + {type: html.FIELDSET_PANEL, style: [PANEL_STYLE]}, {type: html.FIELDSET_PANEL+ice.GT+html.DIV_OUTPUT, style: [PANEL_STYLE]}, {type: html.FIELDSET_PANEL, name: [chat.HEADER], list: [{type: html.DIV_OUTPUT, list: [{type: html.DIV, style: [ITEM_HOVER_STYLE]}], }]}, {type: html.FIELDSET_PANEL, name: [chat.FOOTER], list: [{type: html.DIV_OUTPUT, list: [{type: html.DIV, style: [ITEM_HOVER_STYLE]}], }]}, {type: html.FIELDSET_PANEL, name: [chat.FOOTER], list: [{type: html.DIV_OUTPUT, list: [{type: html.DIV_TOAST, style: [TABLE_HEAD_STYLE]}], }]}, @@ -284,28 +286,29 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { {type: html.FIELDSET_PLUGIN, style: [PLUGIN_STYLE]}, {type: html.FIELDSET_PLUGIN, list: [{type: html.DIV_STATUS, style: {"border-top": color.border+SOLID}}]}, {type: html.FIELDSET_STORY, style: [PLUGIN_STYLE]}, {type: html.FIELDSET_STORY, list: [{type: html.DIV_STATUS, style: {"border-top": color.border+SOLID}}]}, {type: html.FIELDSET_INPUT, list: [{type: html.DIV_OUTPUT, style: [PLUGIN_STYLE]}], style: [PLUGIN_STYLE]}, {type: html.FIELDSET_INPUT, style: _b_r(0)}, + {type: html.FIELDSET_INPUT, list: [{type: html.TD, name: [html.SELECT], style: _bg(color.output)}]}, + {type: html.FIELDSET_INPUT, list: [{type: html.TD, name: [html.HOVER], style: _bg(color.hover)}]}, + {type: html.FIELDSET_INPUT, list: [{type: html.TR, name: [html.HOVER], style: _bg(color.output)}]}, + {type: html.FIELDSET_FLOAT, style: [PLUGIN_STYLE]}, {type: html.DIV_FLOAT, style: [PLUGIN_STYLE]}, {type: html.DIV_CARTE, list: [{type: html.DIV_ITEM, style: [TABLE_HEAD_STYLE, CARTE_ITEM_STYLE]}]}, {type: html.DIV_CARTE, list: [{type: html.DIV_ITEM, style: [CARTE_ITEM_HOVER_STYLE]}]}, - {type: html.DIV_FLOAT, style: [PLUGIN_STYLE]}, - ] - function render(pre, list) { return can.core.List(list, function(item) { var type = item.type+can.core.List(item.name, function(name) { return (name==html.HOVER? ice.DF: ice.PT)+name }).join("") - if (!item.name && type.indexOf(".select") == -1 && type.indexOf(":hover") == -1 && can.base.isArray(item.style) && item.style.join(",").indexOf("-hover-") > -1) { type += ":hover" } + ].concat(list); const DF = ":", FS = ";" + function render(pre, list) { return can.core.List(list, function(item) { if (!item) { return } var type = item.type+can.core.List(item.name, function(name) { return (name==html.HOVER? ice.DF: ice.PT)+name }).join("") + if (!item.name && type.indexOf(ice.PT+html.SELECT) == -1 && type.indexOf(ice.DF+html.HOVER) == -1 && can.base.isArray(item.style) && item.style.join(ice.FS).indexOf("-hover-") > -1) { type += ice.DF+html.HOVER } return (item.style? (pre+ice.SP+type+" { "+(can.base.isArray(item.style)? can.core.List(item.style, function(item) { - return can.core.Item(style[item], function(key, value) { return key&&value? key+": "+value: undefined }).join("; ") - }).join("; "): can.core.Item(can.base.Obj(item.style), function(key, value) { return key+": "+value }).join("; "))+" }"): "")+(item.list? render(pre+ice.SP+type, item.list): "") - }).join(ice.NL) } can.page.Append(can, document.head, "style", {"innerText": render("body."+topic, list)}) + return can.core.Item(style[item], function(key, value) { return key&&value? key+DF+value: undefined }).join(FS) + }).join(FS): can.core.Item(can.base.Obj(item.style), function(key, value) { return key+DF+value }).join(FS))+" }"): "")+(item.list? render(pre+ice.SP+type, item.list): "") + }).join(ice.NL) } can.page.Append(can, document.head, ctx.STYLE, {"innerText": render(html.BODY+ice.PT+topic, list)}) }, style: function(can, style, target) { target = target||can._fields||can._target can.base.isObject(style) && !can.base.isArray(style)? can.page.style(can, target, style): can.page.ClassList.add(can, target, style) }, field: function(can, type, item, target) { type = type||html.STORY, item = item||{} var name = can.core.Split(item.nick||item.name||"").pop(), title = !item.help || item.help == name || can.user.language(can) == "en"? name: name+"("+can.core.Split(item.help)[0]+")" - return can.page.Append(can, target||can._output, [{view: [can.base.join([type||"", item.name||"", item.pos||""]), html.FIELDSET], list: [ - (name||title)&&{text: [name == "word"? item.help.split(ice.SP)[0]: title, html.LEGEND]}, {view: [html.OPTION, html.FORM]}, html.ACTION, html.OUTPUT, html.STATUS, - ]}]) + return can.page.Append(can, target||can._output, [{view: [type, html.FIELDSET], list: [{text: [title, html.LEGEND]}, {view: [html.OPTION, html.FORM]}, html.ACTION, html.OUTPUT, html.STATUS]}]) }, - input: function(can, item, value, target, style) { if (item.type == html.BR || item.type == html.HR) { return can.page.Append(can, target, [item]) } - var input = can.page.input(can, can.base.Copy({className: "", type: "", name: ""}, item), value), title = can.Conf(can.core.Keys(ctx.FEATURE, chat.TITLE, item.name))||""; title && (input.title = title) + input: function(can, item, value, target, style) { if ([html.BR, html.HR].indexOf(item.type) > -1) { return can.page.Append(can, target, [item]) } + var input = can.page.input(can, can.base.Copy({className: "", type: "", name: ""}, item), value); input.title = can.Conf(can.core.Keys(ctx.FEATURE, chat.TITLE, item.name))||"" if (item.type == html.SELECT && item.value) { input._init = function(target) { target.value = value||item.value } } if (item.type == html.TEXT) { input.onkeydown = item.onkeydown||function(event) { can.onkeymap.input(event, can), can.onkeymap.selectOutput(event, can), event.key == lang.ENTER && can.onkeymap.prevent(event) @@ -313,29 +316,32 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { 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]) }) } } - return can.page.Append(can, target, [{view: [style||[html.ITEM, item.type]], list: [input]}])[item.name] + return can.page.Append(can, target, [{view: [[html.ITEM, item.type, item.name].concat(style)], list: [input]}])[item.name] }, - table: function(can, msg, cb, target, sort) { if (!msg || msg.Length() == 0) { return } var meta = can.base.Obj(msg.Option(mdb.META)) + table: function(can, msg, cb, target, keys) { if (!msg || msg.Length() == 0) { return } var meta = can.base.Obj(msg.Option(mdb.META)) var table = can.page.AppendTable(can, msg, target||can._output, msg.append, cb||function(value, key, index, line, array) { if (msg.append.length == 2 && msg.append[0] == mdb.KEY && msg.append[1] == mdb.VALUE) { if (key == mdb.VALUE) { key = line.key } line = {}, can.core.List(array, function(item) { line[item.key] = item.value }) - } function run(event, cmd, arg) { return can.run(can.request(event, line, can.Option()), [ctx.ACTION, cmd].concat(arg)) } + } function run(event, cmd, arg) { can.misc.Event(event, can, function(msg) { + can.run(can.request(event, line, can.Option()), [ctx.ACTION, cmd].concat(arg)) + }) } return {text: [value, html.TD], onclick: function(event) { var target = event.target - if (can.page.tagis(target, html.INPUT) && target.type == html.BUTTON) { can.request(event, {height: can.ConfHeight()-4-table.offsetHeight, width: can.ConfWidth()}) + if (can.page.tagis(target, html.INPUT) && target.type == html.BUTTON) { meta && meta[target.name]? can.user.input(can.request(event, {action: target.name}), can, meta[target.name], function(args) { run(event, target.name, args) }): run(event, target.name) } else { can.sup.onimport.change(event, can.sup, key, event.target.innerText) || can.sup.onexport.record(can.sup, value, key, line) } }, ondblclick: function(event) { if ([mdb.KEY, mdb.HASH, mdb.ID].indexOf(key) > -1) { return } var item = can.core.List(can.Conf([ctx.FEATURE, mdb.INSERT]), function(item) { if (item.name == key) { return item } })[0]||{name: key, value: value} - item.run = function(event, cmds, cb) { can.run(can.request(event, line), cmds, cb, true) } + item.run = function(event, cmds, cb) { can.run(can.request(event, line, can.Option()), cmds, cb, true) } can.onmotion.modifys(can, event.target, function(event, value, old) { run(event, mdb.MODIFY, [key, value]) }, item) }} - }); table && can.page.styleClass(can, table, chat.CONTENT), msg.append && msg.append[msg.append.length-1] == ctx.ACTION && can.page.ClassList.add(can, table, ctx.ACTION) - return sort && can.page.RangeTable(can, table, can.core.List(sort, function(key) { return can.page.Select(can, table, html.TH, function(th, index) { if (th.innerHTML == key) { return index } })[0] })), table + }); table && can.onappend.style(can, chat.CONTENT, table), msg.append && msg.append[msg.append.length-1] == ctx.ACTION && can.onappend.style(can, ctx.ACTION, table) + return keys && can.page.RangeTable(can, table, can.core.List(keys, function(key) { return can.page.Select(can, table, html.TH, function(th, index) { if (th.innerHTML == key) { return index } })[0] })), table }, board: function(can, text, target) { text && text.Result && (text = text.Result()); if (!text) { return } var code = can.page.Append(can, target||can._output, [{text: [can.page.Color(text), html.DIV, html.CODE]}]).code - can.page.Select(can, code, html.INPUT_BUTTON, function(target) { target.onclick = function(event) { can.run(can.request(event, can.Option()), [ctx.ACTION, target.name]) } }) - return code.scrollBy && code.scrollBy(0, 10000), code + can.page.Select(can, code, html.INPUT_BUTTON, function(target) { target.onclick = function(event) { can.misc.Event(event, can, function(msg) { + can.run(can.request(event, can.Option()), [ctx.ACTION, target.name]) + }) } }); return code.scrollBy && code.scrollBy(0, 10000), code }, tools: function(can, msg, cb, target) { can.onimport.tool(can, can.base.Obj(msg.Option(ice.MSG_TOOLKIT), []), cb, target) }, layout: function(can, target, type, list) { const FLOW = html.FLOW, FLEX = html.FLEX @@ -349,27 +355,22 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { } else if (can.base.isArray(item)) { append(can.page.Append(can, target, [html.LAYOUT])._target, type==FLOW? FLEX: FLOW, item) } else if (can.base.isObject(item)) { - if (item.index) { - item._index = count++, ui.size[item._index] = item.height||item.width - item.layout = function(width, height) { item.width = width, item.height = height } - can.onappend.plugin(can, item, function(sub) { item.layout = function(width, height) { sub.onimport.size(sub, height, width) } - can._plugins = can.misc.concat(can, can._plugins, [sub]) + if (item.index) { item._index = count++, ui.size[item._index] = item.height||item.width + can.onappend.plugin(can, item, function(sub) { can._plugins = can.misc.concat(can, can._plugins, [sub]) + item.layout = function(width, height) { sub.onimport.size(sub, height, width) } }, target, ui[item._index] = can.onappend.field(can, item.type, {name: item.index, help: item.help}, target)._target) - } else { - can.page.Append(can, target, [item]) - } + } else { can.page.Append(can, target, [item]) } } }); return list } function calc(item, size, total) { return !ui.size[item]? size: ui.size[item] < 1? total*ui.size[item]: ui.size[item] } var defer = []; function layout(type, list, width, height) { var _width = width, _height = height; can.core.List(list, function(item) { if (item == html.CONTENT) { return defer.push(function() { can.page.style(can, ui[item], html.HEIGHT, height, html.WIDTH, width) }) } - if (!can.page.isDisplay(ui[item])) { return } - if (can.base.isObject(item)) { var meta = item; item = (item._index)+"" } + if (!can.page.isDisplay(ui[item])) { return } if (can.base.isObject(item)) { var meta = item; item = item._index } if (type == FLOW) { var h = calc(item, ui[item].offsetHeight, height) if (can.base.isObject(meta)) { meta.layout(width, h) } can.page.style(can, ui[item], html.WIDTH, width), height -= h } else { var w = calc(item, ui[item].offsetWidth||_width/list.length, _width), h = height - if (can.base.isObject(meta)) { h = "", meta.layout(w = _width/list.length, h) } + if (can.base.isObject(meta)) { meta.layout(w = _width/list.length, h) } can.page.style(can, ui[item], html.HEIGHT, h, html.WIDTH, w), width -= w } }), can.core.List(list, function(item) { if (can.base.isArray(item)) { layout(type == FLOW? FLEX: FLOW, item, width, height) } }) } @@ -430,75 +431,65 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { var res = {}; function _cb(sub, meta, skip) { kit.proto(res, sub), cb && cb(sub, meta, skip) } if (meta.inputs && meta.inputs.length > 0 || meta.meta) { can.onappend._plugin(can, {meta: meta.meta, list: meta.list}, meta, _cb, target, field); return res } var value = can.onengine.plugin(can, meta.index); if (value) { can.onappend._plugin(can, value, meta, function(sub, meta, skip) { - _cb(sub, meta, skip), can.onmotion.delay(can, function() { value.meta && value.meta._init && value.meta._init(sub, meta) }) + value.meta && value.meta._init && value.meta._init(sub, meta), _cb(sub, meta, skip) }, target, field); return res } can.runAction({}, ctx.COMMAND, [meta.index], function(msg) { msg.Table(function(value) { can.onappend._plugin(can, value, meta, _cb, target, field) })}); return res }, _plugin: function(can, value, meta, cb, target, field) { can.base.Copy(meta, value, true) - meta.name = meta.name||value&&value.meta&&value.meta.name||"" - meta.type = meta.type||chat.STORY, meta.height = meta.height||can.ConfHeight(), meta.width = meta.width||can.ConfWidth() - meta.args = can.base.getValid(can.base.Obj(meta.args), can.base.Obj(meta.arg), can.base.Obj(value.args), can.base.Obj(value.arg))||[] + meta.type = meta.type||chat.STORY, meta.name = meta.name||value.meta&&value.meta.name||"", meta.height = meta.height||can.ConfHeight(), meta.width = meta.width||can.ConfWidth() meta.inputs = can.base.getValid(meta.inputs, can.base.Obj(value.list))||[], meta.feature = can.base.getValid(meta.feature, can.base.Obj(value.meta))||{} + meta.args = can.base.getValid(can.base.Obj(meta.args), can.base.Obj(meta.arg), can.base.Obj(value.args), can.base.Obj(value.arg))||[] can.onappend._init(can, meta, [chat.PLUGIN_STATE_JS], function(sub, skip) { sub.run = function(event, cmds, cb) { can.runActionCommand(event, sub._index, cmds, cb) } sub._index = value.index||meta.index, can.base.isFunc(cb) && cb(sub, meta, skip) }, target||can._output, field) }, _float: function(can, index, args) { - can.onappend.plugin(can, {mode: chat.FLOAT, index: index, args: args}, function(sub) { + can.onappend.plugin(can, {index: index, args: args, mode: chat.FLOAT}, function(sub) { can.getActionSize(function(left, top, width, height) { sub.onimport.size(sub, sub.ConfHeight(height/2), sub.ConfWidth(width), true) can.onmotion.move(can, sub._target, {left: left||0, top: (top||0)+height/4}) }), sub.onaction.close = function() { can.page.Remove(can, sub._target) } }, can._root._target) }, - figure: function(can, meta, target, cb) { if (meta.action == ice.AUTO || meta.type == html.BUTTON || meta.type == html.SELECT) { return } + figure: function(can, meta, target, cb) { if (meta.type == html.BUTTON || meta.type == html.SELECT) { return } var input = meta.action||mdb.KEY, path = chat.PLUGIN_INPUT+input+nfs._JS; can.require([path], function(can) { function _cb(sub, value, old) { if (value == old) { return } can.base.isFunc(cb)? cb(sub, value, old): can.onmotion.delay(can, function() { can.onmotion.focus(can, target, value||"") }) } - can.core.ItemCB(can.onfigure[input], function(key, on) { var last = target[key]||function(){}; target[key] = function(event) { + can.core.ItemCB(can.onfigure[input], function(key, on) { var last = target[key]||function(){}; target[key] = function(event) { can.misc.Event(event, can, function(msg) { + function show(sub, cb) { can.base.isFunc(cb) && cb(sub, _cb), can.onlayout.figure(event, can, sub._target), can.onmotion.toggle(can, sub._target, true) } can.core.CallFunc(on, {event: event, can: can, meta: meta, cb: _cb, target: target, sub: target._can, last: last, cbs: function(cb) { - function show() { var sub = target._can; can.base.isFunc(cb) && cb(target._can, _cb), can.onlayout.figure(event, can, target._can._target), can.onmotion.toggle(can, target._can._target, true) } - target._can? show(): can.onappend._init(can, {type: html.INPUT, name: input, pos: chat.FLOAT, mode: meta.mode}, [path], function(sub) { sub.Conf(meta) + target._can? show(target._can, cb): can.onappend._init(can, {type: html.INPUT, name: input, style: meta.name, mode: chat.FLOAT}, [path], function(sub) { sub.Conf(meta) sub.run = function(event, cmds, cb) { var msg = sub.request(event) if (meta.range) { for (var i = meta.range[0]; i < meta.range[1]; i += meta.range[2]||1) { msg.Push(mdb.VALUE, i) } cb(msg); return } (meta.run||can.run)(sub.request(event, can.Option()), cmds, cb, true) }, target._can = sub, can.base.Copy(sub, can.onfigure[input], true), sub._name = sub._path = path - sub.hidden = function() { return sub._target.style.display == html.NONE }, sub.close = function() { can.page.Remove(can, sub._target), delete(target._can) } - can.onmotion.delay(can, function() { can.page.style(sub, sub._target, meta.style), show(), can.base.isFunc(meta._init) && meta._init(sub, sub._target) }) + sub.hidden = function() { return !can.page.isDisplay(sub._target) }, sub.close = function() { can.page.Remove(can, sub._target), delete(target._can) } + can.page.style(sub, sub._target, meta.style), can.base.isFunc(meta._init) && meta._init(sub, sub._target), show(sub, cb) }, can._root._target) }}) - } }), can.onfigure[input]._init && can.onfigure[input]._init(can, meta, target, _cb) + }) } }), can.onfigure[input]._init && can.onfigure[input]._init(can, meta, target, _cb) }) }, }) Volcanos(chat.ONLAYOUT, {_init: function(can, target) { target = target||can._root._target; var height = can.page.height(), width = can.page.width() can.page.SelectChild(can, target, can.page.Keys(html.FIELDSET_HEAD, html.FIELDSET_FOOT), function(field) { height -= field.offsetHeight }) - can.page.SelectChild(can, target, html.FIELDSET_LEFT, function(field) { - can.page.styleHeight(can, field, height), can.user.isMobile || (width -= field.offsetWidth) + can.page.SelectChild(can, target, html.FIELDSET_LEFT, function(field) { can.user.isMobile || (width -= field.offsetWidth) can.page.SelectChild(can, field, html.DIV_OUTPUT, function(output) { can.page.styleHeight(can, output, height-html.ACTION_HEIGHT) }) }) can.page.SelectChild(can, target, html.FIELDSET_MAIN, function(field) { - can.page.style(can, field, html.HEIGHT, height, html.WIDTH, width) can.page.SelectChild(can, field, html.DIV_ACTION, function(action) { height -= action.offsetHeight }) can.page.SelectChild(can, field, html.DIV_OUTPUT, function(output) { can.page.styleHeight(can, output, height) }) }), can.onengine.signal(can, chat.ONSIZE, can.request({}, {height: height, width: width})) + can.page.style(can, document.body, kit.Dict(html.OVERFLOW, html.HIDDEN)) }, background: function(can, url, target) { can.page.style(can, target||can._root._target, "background-image", url == "" || url == "void"? "": 'url("'+url+'")') }, figure: function(event, can, target, right) { if (!event || !event.target) { return {} } target = target||can._fields||can._target var rect = event.target == document.body? {left: can.page.width()/2, top: can.page.height()/2, right: can.page.width()/2, bottom: can.page.height()/2}: event.target.getBoundingClientRect() var layout = right? {left: rect.right, top: rect.top}: {left: rect.left, top: rect.bottom} can.getActionSize(function(left, top, width, height) { left = left||0, top = top||0, height = can.base.Max(height, can.page.height()-top) - if (top+height-layout.top > 200) { - layout[html.MAX_HEIGHT] = can.base.Max(top+height-layout.top, can.page.height()/2), layout[html.OVERFLOW] = ice.AUTO - } else if (target.offsetHeight > height) { - layout.top = top, layout[html.MAX_HEIGHT] = height, layout[html.OVERFLOW] = ice.AUTO - } else if (layout.top+target.offsetHeight > top+height) { - layout.top = top+height-target.offsetHeight - } - if (target.offsetWidth > width) { - layout.left = left, layout[html.MAX_WIDTH] = width, layout[html.OVERFLOW] = ice.AUTO - } else if (layout.left+target.offsetWidth > left+width) { - layout.left = left+width-target.offsetWidth - } + if (target.offsetWidth > width/2) { can.page.style(can, target, html.MAX_WIDTH, width) } + if (target.offsetHeight > height/4) { can.page.style(can, target, html.MAX_HEIGHT, height/2) } + if (layout.top+target.offsetHeight > top+height) { layout.top = top+height-target.offsetHeight } + if (layout.left+target.offsetWidth > left+width) { layout.left = left+width-target.offsetWidth } }); return can.onmotion.move(can, target, layout), layout }, @@ -571,12 +562,12 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { hidden: function(can, target, show) { target = target||can._target if (target.length > 0) { return can.core.List(target, function(target) { can.onmotion.hidden(can, target, show) }) } - return can.page.styleDisplay(can, target, show? "": html.NONE), show? target._show && target._show(): target._hide && target._hide(), show + return can.page.ClassList.set(can, target, html.HIDE, !show)? target._hide && target._hide(): target._show && target._show(), show }, toggle: function(can, target, show, hide) { target = target||can._target if (show === true) { return can.onmotion.hidden(can, target, true) } if (show === false) { return can.onmotion.hidden(can, target, false) } - var status = target.style.display == html.NONE; if (status? can.base.isFunc(show) && show(): can.base.isFunc(hide) && hide()) { return !status } - return can.onmotion.hidden(can, target, status) + var status = can.page.isDisplay(target); if (status? can.base.isFunc(hide) && hide(): can.base.isFunc(show) && show()) { return !status } + return can.onmotion.hidden(can, target, !status) }, select: function(can, target, name, which, cb) { var old = can.page.Select(can, target, name, function(target, index) { if (can.page.ClassList.has(can, target, html.SELECT)) { return index } })[0] @@ -675,7 +666,7 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { }, }) Volcanos(chat.ONKEYMAP, {_init: function(can, target) { target = target||document.body - can.onkeymap._build(can), target.onkeydown = function(event) { + can.onkeymap._build(can), target.onkeydown = function(event) { can.misc.Event(event, can, function(msg) { if (can.page.tagis(event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } var msg = can.request(event, {"model": "normal"}); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } if (can.user.isWebview && event.metaKey) { msg.Option("model", "webview"); if (event.key >= "0" && event.key <= "9") { @@ -683,12 +674,12 @@ Volcanos(chat.ONKEYMAP, {_init: function(can, target) { target = target||documen } } can.onengine.signal(can, chat.ONKEYDOWN, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } can._keylist = can.onkeymap._parse(event, can, msg.Option("model"), can._keylist, can._output) - }, target.onkeyup = function(event) { + }) }, target.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { if (can.page.tagis(event.target, html.SELECT, html.INPUT, html.TEXTAREA)) { return } var msg = can.request(event, {"model": "normal"}); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } can.onengine.signal(can, chat.ONKEYUP, msg); if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } can._keylist = can.onkeymap._parse(event, can, msg.Option("model"), can._keylist, can._output) - } + }) } }, _build: function(can) { can.core.Item(can.onkeymap._mode, function(item, value) { var engine = {list: {}} can.core.Item(value, function(key, cb) { var map = engine; for (var i = 0; i < key.length; i++) { @@ -772,6 +763,9 @@ Volcanos(chat.ONKEYMAP, {_init: function(can, target) { target = target||documen if (!can.page.ClassList.set(can, item, html.HIDE, item.innerText.toLowerCase().indexOf(name) == -1)) { for (item = item.parentNode; item != target; item = item.parentNode) { can.page.ClassList.del(can, item, html.HIDE), can.page.ClassList.del(can, item.previousSibling, html.HIDE) + can.page.Select(can, item.previous, "div.switch", function(item) { + can.page.ClassList.add(can, item, "open") + }) } } }), can.onkeymap.selectCtrlN(event, can, target, html.DIV_ITEM+":not(.hide)", function(target) { diff --git a/index.css b/index.css index 27690bcc..2ef2f8ee 100644 --- a/index.css +++ b/index.css @@ -11,7 +11,7 @@ input[name=offend] { width:48px; } input[name=id] { width:48px; } input[name=ID] { width:48px; } input[name=url] { width:320px; } -input[name=cmd] { background-color:black; color:white; width:320px; } +input[name=cmd] { background-color:black; color:white; width:100%; } input[type=button] { background-color:black; color:cyan; } input[type=button][name=restart] { background-color:blue; } input[type=button][name=start] { background-color:blue; } @@ -26,9 +26,11 @@ div.layout.flex>* { float:left; } div.output { position:relative; } div.project div.list { margin-left:10px; } div.project div.item { padding:2px 10px; } -div.project div.item>div.name { padding-left:20px; } -div.project div.switch { margin-top:2px; width:12px; float:left; rotate:90deg; } -div.project div.switch.open { translate:3px -3px; rotate:180deg; } +div.project div.item>div.name { padding-left:15px; } +div.project div.switch { float:left; transition:all 0.3s; } +div.project div.switch.open { rotate:90deg; translate:1px 2px; transition:all 0.3s; } +// div.project div.switch { margin-top:2px; width:12px; float:left; rotate:90deg; } +// div.project div.switch.open { translate:3px -3px; rotate:180deg; } div.project div.zone>div.item { background-color:steelblue; color:white; text-align:center; padding:3px; clear:both; position:relative; } div.project div.zone>div.item>div.icon { margin-left:3px; display:none; float:right; } div.project div.zone:hover>div.name>div.icon { display:block; } @@ -69,7 +71,7 @@ fieldset.full { position:fixed; left:0; top:0; } fieldset.input>legend { display:none; } fieldset.input.key { overflow:auto; } fieldset.input.key div.action { display:none; } -fieldset.input.key.simple div.status { display:none; } +fieldset.input.key.simple div.status { display:block; position:sticky; bottom:0; } fieldset.input.key.simple th { display:none; } fieldset.input.key.simple td { min-width:40px; } fieldset.input.date select { margin-right:0; width:87px; } @@ -130,12 +132,14 @@ fieldset.web.code.git.status div.output table.content { width:100%; } div.tabs { position:relative; } /* display */ form.option, div.action { display:contents; } +form.option.hide, div.action.hide { display:none; } form.option>div.item>label, div.action>div.item>label, .hidden, .hide { display:none; } form.option>div.textarea { width:100%; } form.option>div.textarea>textarea { width:100%; } +form.option>div.cmd { width:100%; } div.action, div.output, div.status, div.project, div.display, div.profile, div.content, table.content, table.content td, div.code, div.plug, div.story, div.toast { overflow:auto; } legend, form.option, form.option>div.item, div.action, div.action>div.item, div.action>div.tabs, div.status>div.item { float:left; } -div.output, div.status, div.item.textarea, div.project div.item, div.content, div.code, div.story[data-type=spark] { clear:both; } +fieldset>div.output, fieldset>div.status, div.item.textarea, div.project div.item, div.content, div.code, div.story[data-type=spark] { clear:both; } div.status>legend { margin-left:2px; margin-right:0; float:right; clear:none; } fieldset.plugin:not(.float):not(.full):not(.cmd) { padding:10px; margin:10px; } fieldset.plugin:not(.float):not(.full):not(.cmd)>legend { float:none; } @@ -231,14 +235,17 @@ body.mobile select { font-size:1.4rem; height:38px; } body.mobile input { font-size:1.2rem; height:38px; } body.mobile textarea { font-size:1.2rem; } body.mobile form.option>div.item { margin:0; height:38px; } +body.mobile form.option>div.item.icon { font-size:32px; padding:0 10px; } +body.mobile form.option>div.item.textarea { height:unset; } body.mobile div.action>div.item { margin:0; height:38px; } body.mobile div.carte div.item { font-size:1.6rem; } body.mobile table.content th { padding:6px; } +body.mobile table.content { width:100%; } body.mobile fieldset:not(.panel):not(.input)>div.action { display:none; } body.mobile fieldset.plugin:not(.float):not(.full):not(.cmd) { margin:10px 0; } body.mobile fieldset.Header { font-size:1.6rem; padding:0; height:3rem; width:100%; position:fixed; top:0; } -body.mobile fieldset.Header div.search { padding:0; height:3rem; width:100%; margin:0; } -body.mobile fieldset.Header div.search>input { background-color:#21181838; color:white; height:53px; width:100%; } +body.mobile fieldset.Header div.output div.search { padding:0; height:3rem; width:100%; margin:0; } +body.mobile fieldset.Header div.output div.search>input { background-color:#21181838; color:white; height:53px; width:100%; } body.mobile fieldset.River { min-width:240px; position:fixed; top:3rem; z-index:10; } body.mobile fieldset.River>div.output { font-size:1.6rem; width:320px; } body.mobile fieldset.Action { margin-top:3rem; margin-bottom:3rem; } diff --git a/lib/core.js b/lib/core.js index 6d2d5e42..82ec3f08 100644 --- a/lib/core.js +++ b/lib/core.js @@ -107,7 +107,9 @@ Volcanos("core", { }, ItemCB: function(meta, cb, can, item) { var list = [] for (var k in meta) { if (k.indexOf("on") == 0 && typeof meta[k] == lang.FUNCTION) { (function(k) { list.push(k) - if (typeof cb == lang.FUNCTION) { cb(k, meta[k]) } else { cb[k] = function(event) { meta[k](event, can, item) } } + if (typeof cb == lang.FUNCTION) { cb(k, meta[k]) } else { cb[k] = function(event) { can.misc.Event(event, can, function(msg) { + meta[k](event, can, item) + }) } } })(k) } } return list }, Timer: shy("定时器, value, [1,2,3,4], {delay, interval, length}", function(interval, cb, cbs) { var timer = {stop: false} diff --git a/lib/misc.js b/lib/misc.js index 5922c506..b6737c6d 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -91,6 +91,9 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} if (cmds[0] == ctx.ACTION && meta[cmds[1]]) { return meta[cmds[1]](cmds.slice(2)), true } if (meta[cmds[0]]) { return meta[cmds[0]](cmds.slice(1)), true } }, + Event: function(event, can, cb) { + cb(can.request(event)) + }, Run: function(event, can, dataset, cmds, cb) { var msg = can.request(event) var form = {}; msg.option && msg.option.forEach(function(key) { if ([ice.MSG_HANDLE, ice.MSG_DAEMON].indexOf(key) > -1) { return } @@ -136,9 +139,9 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} can.base.isFunc(onerror)? onerror(socket): socket.close() }, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args) can.base.isFunc(onopen) && onopen(socket) - }, socket.onmessage = function(event) { + }, socket.onmessage = function(event) { can.misc.Event(event, can, function(msg) { try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} } - var msg = can.request(event); msg.Reply = function() { var res = can.request({}, {_handle: ice.TRUE}) + msg.Reply = function() { var res = can.request({}, {_handle: ice.TRUE}) res._target = (msg[ice.MSG_SOURCE]||[]).reverse(), res._source = (msg[ice.MSG_TARGET]||[]).reverse().slice(1)||[] res.append = msg.append, can.core.List(msg.append, function(key) { res[key] = msg[key] }), res.result = (msg.result||[]).concat(can.core.List(arguments)) res.Option(ice.LOG_DISABLE, msg.Option(ice.LOG_DISABLE)) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result||[], msg) @@ -148,7 +151,7 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} msg.Option(ice.LOG_DISABLE) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg) can.core.CallFunc(cb, {event: event, msg: msg, cmd: msg.detail[0], arg: msg.detail.slice(1), cb: function() { msg.Reply() }}) } catch (e) { can.misc.Warn(e), msg.Reply() } - } + }) } }, MergePath: function(can, file, path) { return file.indexOf(ice.PS) == 0 || file.indexOf(ice.HTTP) == 0? file: can.base.Path(path, file) }, MergeCache: function(can, hash) { return can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true) }, diff --git a/lib/page.js b/lib/page.js index a67d9a8f..8c45cc89 100644 --- a/lib/page.js +++ b/lib/page.js @@ -60,13 +60,15 @@ Volcanos("page", {ClassList: { } else if (item.text) { var list = can.core.List(item.text); if (can.base.isArray(list[2])) { list[2] = list[2].join(ice.SP) } data.innerHTML = list[0]||data.innerHTML||"", type = list[1]||html.SPAN, list[2] && can.page.ClassList.add(can, data, list[2]) } else if (item.button) { var list = can.core.List(item.button); type = html.BUTTON, name = name||list[0] - data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) { + data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) { can.misc.Event(event, can, function(msg) { can.base.isFunc(list[1]) && list[1](event, name), can.onkeymap.prevent(event); return true - } + }) } } else if (item.select) { var list = item.select; type = html.SELECT data.name = name = name||list[0][0], data.className = data.className||list[0][0]||"", data.title = can.user.trans(can, data.title||name) item.list = list[0].slice(1).map(function(value) { return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} }) - data.onchange = function(event) { can.base.isFunc(list[1]) && list[1](event, event.target.value, name) } + data.onchange = function(event) { can.misc.Event(event, can, function(msg) { + can.base.isFunc(list[1]) && list[1](event, event.target.value, name) + }) } } else if (item.input) { var list = can.core.List(item.input); type = html.INPUT, name = name||list[0]||"" data.type = data.type||"text", data.name = data.name||name, data.className = data.className||data.name data.onfocus = data.onfocus||function(event) { event.target.setSelectionRange(0, -1) } @@ -84,6 +86,7 @@ Volcanos("page", {ClassList: { if (type == html.INPUT) { data.type == html.BUTTON && (data.value = can.user.trans(can, data.value)) if (data.type == html.TEXT||data.type == html.PASSWORD||!data.type) { data.placeholder = (data.placeholder||data.name||"").split(ice.PT).pop(), data.title = can.user.trans(can, data.title||data.placeholder) + data.placeholder == "" && delete(data.placeholder), data.title == "" && delete(data.title) data.autocomplete = data.autocomplete||"off" } } else if (type == html.TEXTAREA) { data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) } @@ -139,7 +142,9 @@ Volcanos("page", {ClassList: { break default: (function() { var item = can.core.SplitInput(list[i], type||html.BUTTON) - if (item.type == html.SELECT) { item._init = function(target) { target.value = item.value||item.values[0], target.onchange = function(event) { can.run(event) } } } + if (item.type == html.SELECT) { item._init = function(target) { target.value = item.value||item.values[0], target.onchange = function(event) { can.misc.Event(event, can, function(msg) { + can.run(event) + }) } } } item.action && (function() { item._init = function(target) { can.onappend.figure(can, item, target) } })() // item.type == html.BUTTON? _list.push(item.name): _list.push(item) _list.push(item) diff --git a/panel/action.js b/panel/action.js index e1833ea5..fed2e8d2 100644 --- a/panel/action.js +++ b/panel/action.js @@ -73,7 +73,7 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { can.page.Append(can, target, [{view: [[html.TOGGLE, chat.PROJECT]], list: [{text: [gt, html.DIV]}], onclick: function(event) { event.target.innerHTML = toggle()? gt: lt, can.onaction.layout(can, can.Conf(html.LAYOUT)) }}]) - } target.ontouchstart = function(event) { can.onengine.signal(can, chat.ONACTION_TOUCH, can.request(event)) } + } target.ontouchstart = function(event) { can.misc.Event(event, can, function(msg) { can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }) } }, _menus: [ [html.LAYOUT, ice.AUTO, TABS, TABVIEW, HORIZON, VERTICAL, GRID, FREE, FLOW, PAGE], @@ -100,7 +100,7 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { ), onmain: function(can) { can.onimport._share(can, can.misc.Search(can, web.SHARE)) }, onlogin: function(can) { can.ondaemon._init(can); if (!can.Conf(chat.TOOL) && !can.user.mod.isCmd) { return } - can.onengine.signal(can, chat.ONACTION_CMD), window.onresize = function(event) { can.onaction.onresize(can), can.page.styleWidth(can, can._output, can.page.width()) } + can.onengine.signal(can, chat.ONACTION_CMD), window.onresize = function(event) { can.misc.Event(event, can, function(msg) { can.onaction.onresize(can), can.page.styleWidth(can, can._output, can.page.width()) }) } 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) { if (list.length == 1) { item.height = window.innerHeight-2*html.ACTION_HEIGHT } item.type = chat.PLUGIN, item.mode = chat.CMD, item.opts = can.misc.Search(can); return item })).layout(window.innerWidth, window.innerHeight): can.runAction(can.request(), ctx.COMMAND, [], function(msg) { can.core.Next(msg.Table(), function(item, next) { diff --git a/panel/footer.js b/panel/footer.js index cbe45276..928a766f 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -7,7 +7,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { }, _title: function(can, msg, target) { can.user.isMobile || can.core.List(msg.result, function(item) { can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "联系站长"}]) }) }, _state: function(can, msg, target) { can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [NTIP, NCMD, NLOG]).reverse(), function(item) { - can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, can.Conf(item)], list: [ + can.page.Append(can, target, [{view: [[chat.STATE], html.DIV, can.Conf(item)], list: [ {text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", html.SPAN, item]}, ], onclick: function(event) { can.onexport[item](can) }}]) }) }, @@ -19,7 +19,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.runAction(event, ice.RUN, can.core.Split(event.target.value, ice.SP), function(msg) { can.cli && can.cli.close && can.cli.close(), can["cli"] = {}; var ui = can.onexport.float(can, msg, "cli") can.getActionSize(function(left) { can.page.style(can, ui._target, html.LEFT, left+10, html.RIGHT, "", html.BOTTOM, can.onexport.height(can)) }) }) - } }}, "", target, [chat.TITLE, ice.CMD]) }, + } }}, "", target, [chat.TITLE]) }, count: function(can, name) { can.page.Select(can, can._output, can.core.Keys(html.SPAN, name), function(item) { item.innerHTML = can.Conf(name, parseInt(can.Conf(name)||"0")+1+"")+"" }) }, toast: function(can, msg, title, content, fileline, time) { can.onimport._data(can, NTIP, {time: time, fileline: fileline, title: title, content: content}), can.page.Modify(can, can.toast, [time, title, content].join(ice.SP)) }, debug: function(can, msg, _args, fileline, time) { can.onimport._data(can, NLOG, {time: time, fileline: fileline, type: _args[2], content: _args.slice(4).join(ice.SP)}) }, diff --git a/panel/header.js b/panel/header.js index c46a604e..5a9a1ad6 100644 --- a/panel/header.js +++ b/panel/header.js @@ -31,7 +31,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { _search: function(can, msg, target) { can._search = can.onappend.input(can, {type: html.TEXT, name: mdb.SEARCH, onkeydown: function(event) { can.onkeymap.input(event, can) event.key == lang.ENTER && can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: event.target.value||""})) - }}, "", target, [chat.TITLE, mdb.SEARCH]) + }}, "", target, [chat.TITLE]) can.user.isMobile || can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) }) }, _menus: function(can, msg, target) { if (can.user.mod.isPod || can.user.isMobile) { return } diff --git a/plugin/input/img.js b/plugin/input/img.js index 4de7996f..8249136f 100644 --- a/plugin/input/img.js +++ b/plugin/input/img.js @@ -6,9 +6,9 @@ Volcanos(chat.ONFIGURE, {img: { for (var i = 0; i < count; i++) { can.page.Append(can, target.parentNode, [{type: html.DIV, style: { "background-color": "yellow", "float": "left", "clear": i%n == 0? "both": "none", "margin": 1, height: width, width: width, - }, _init: function(target) { images[i] && add(target, images[i]), target.onclick = function(event) { + }, _init: function(target) { images[i] && add(target, images[i]), target.onclick = function(event) { can.misc.Event(event, can, function(msg) { can.user.upload(event, can, function(msg) { add(target, msg.Result()), set() }, true) - } } }]) + })} } }]) } }, }}) diff --git a/plugin/input/key.js b/plugin/input/key.js index ee82f7b4..8d5bb161 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -1,8 +1,12 @@ Volcanos(chat.ONFIGURE, {key: { _show: function(can, msg, cb, target, name) { if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value) { return can.onmotion.hidden(can) } if (msg.append[msg.append.length-1] == ctx.ACTION) { msg.append = msg.append.slice(0, -1) } + if (msg.append[msg.append.length-1] == "cb") { msg.append = msg.append.slice(0, -1) } can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, line) { value = line[key] return {text: [value, html.TD, value == ""? "hr": ""], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) { + can.onmotion.delay(can, function() { + can.close() + }) if (msg.cb && msg.cb[index]) { return msg.cb[index](value) } can._delay_hidden = false, cb(can, value, target.value), msg.Option(ice.MSG_PROCESS) == ice.PROCESS_AGAIN && can.onmotion.delay(can, function() { can._load(event, can, cb, target, name, value) }) }} @@ -22,8 +26,7 @@ Volcanos(chat.ONFIGURE, {key: { meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value) }) }, onblur: function(event, can, sub) { can.onmotion.delay(can, function() { - // sub._delay_hidden || can.onmotion.hidden(can, sub._target), sub._delay_hidden = false - // if (sub) { sub._delay_hidden || sub.close(), sub._delay_hidden = false } + if (sub) { sub._delay_hidden || sub.close(), sub._delay_hidden = false } }, 300) }, onkeydown: function(event, can, meta, cb, target, sub, last) { if (event.key == lang.ENTER && meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event)) { return sub.close() } diff --git a/plugin/local/chat/keyboard.js b/plugin/local/chat/keyboard.js index 22b01cb8..afa1911b 100644 --- a/plugin/local/chat/keyboard.js +++ b/plugin/local/chat/keyboard.js @@ -13,12 +13,12 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) _input: function(can, item, data, target) { item = can.base.isObject(item)? item: {type: html.BUTTON, name: item} if (can.base.isArray(item)) { return can.page.Append(can, target, [{view: "space"}]), can.core.List(item, function(item) { can.onimport._input(can, item, data, target) }) } item._init = item._init||function(target) { switch (target.type) { - case html.TEXT: target.onkeydown = function(event) { if (event.key == lang.ENTER) { + case html.TEXT: target.onkeydown = function(event) { can.misc.Event(event, can, function(msg) { if (event.key == lang.ENTER) { can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION, item.name, target.value], function() {}) - } }; break - case html.BUTTON: target.onclick = function(event) { + } })}; break + case html.BUTTON: target.onclick = function(event) { can.misc.Event(event, can, function(msg) { can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION].concat(item.cmds||item.name), function() {}) - }; break + })}; break } }, can.onappend.input(can, item, "", target) }, }, [""]) diff --git a/plugin/local/chat/location.js b/plugin/local/chat/location.js index f91afde7..751f294a 100644 --- a/plugin/local/chat/location.js +++ b/plugin/local/chat/location.js @@ -30,10 +30,14 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { }, function() { can.user.toastSuccess(can) }) }})}, {name: "explore", _init: function(target, zone) { - zone._search.onkeyup = function(event) { event.key == "Enter" && can.onimport._search0(can, event.target.value) } + zone._search.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { + event.key == "Enter" && can.onimport._search0(can, event.target.value) + }) } }}, {name: "search", _init: function(target, zone) { - zone._search.onkeyup = function(event) { event.key == "Enter" && can.onimport._search(can, event.target.value) } + zone._search.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { + event.key == "Enter" && can.onimport._search(can, event.target.value) + }) } }}, {name: "district", _init: function(target, zone) { can.onimport._province(can, target) @@ -227,7 +231,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { var meta = this.meta, ui = can.onappend.field(can, chat.FLOAT, {}, can._output) can.onappend.plugin(can, meta, function(sub) { sub.run = function(event, cmds, cb) { can.runAction(can.request(event), ice.RUN, [meta.index].concat(cmds), cb) } - sub.onaction.close = function(event) { can.onmotion.hidden(can, sub._target) } + sub.onaction.close = function(event) { can.misc.Event(event, can, function(msg) { + can.onmotion.hidden(can, sub._target) + }) } // can.page.style(can, sub._output, html.MAX_HEIGHT, sub.ConfHeight(can.ConfHeight()/2)) // can.page.style(can, sub._output, html.MAX_WIDTH, sub.ConfWidth(can.ConfWidth()/2)) item._plugin = sub diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index 8b709ce3..7cfea558 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -1,5 +1,6 @@ fieldset.inner>form.option input[name=path] { width:80px; } fieldset.inner>form.option input[name=file] { width:160px; } +fieldset.inner>div.output { overflow:hidden; } fieldset.inner>div.output * { font-size:14px; font-family:monospace; outline:none; } fieldset.inner>div.output legend { font-size:1rem; line-height:2rem; } fieldset.inner>div.output div.content { position:relative; } @@ -82,5 +83,6 @@ tr.line>td.line { text-align:right; padding:0 10px; position:sticky; left:0; } tr.line>td.text { line-height:20px; white-space:pre; padding-left:10px; cursor:text; } body.white tr.line.select { background-color:dimgray; } body.white tr.line:hover { background-color:dimgray; } body.black tr.line.select { background-color:darkblue; } body.black tr.line:hover { background-color:darkblue; } +td.unselectable { -webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; -o-user-select:none; user-select:none; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 87186c48..fac55a04 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -45,7 +45,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl can.page.Append(can, can.ui.tabs, [{view: [[html.ICON, mdb.CREATE], html.DIV, "\u2630"], onclick: function() { can.user.carte(event, can, can.onaction, can.onaction.list) }}]) - can.page.Append(can, can.ui.tabs, [{view: [mdb.TIME], _init: function(target) { + can.user.isMobile || can.page.Append(can, can.ui.tabs, [{view: [mdb.TIME], _init: function(target) { can.core.Timer({interval: 100}, function() { can.page.Modify(can, target, can.user.time(can, null, "%y-%m-%d %H:%M:%S %w")) }) can.onappend.figure(can, {action: "date", _hold: true}, target, function(sub, value) {}) }}]) @@ -74,12 +74,11 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl var carte, list = [{input: ["filter", function(event) { can.onkeymap.selectItems(event, can, carte._target) }], _init: function(target) { can.onmotion.delay(can, function() { target.focus() }) }}] can.core.Item(last, function(key) { list.push(key) }), list.push("") var func = can.onexport.func(can); - (can.parse == nfs.JS || can.parse == nfs.GO) && can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"function")+" / "+can.max+func.percent], onclick: function(event) { + !can.user.isMobile && (can.db.parse == nfs.JS || can.db.parse == nfs.GO) && can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"function")+" / "+can.db.max+func.percent], onclick: function(event) { carte = can.user.carte(event, can, {_style: nfs.PATH}, list.concat(func.list), function(ev, button) { last[button] = true can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.core.Split(button, ice.DF)[1]), can.onmotion.clearFloat(can) }) }}]) - 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) } @@ -90,9 +89,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl can.onaction.exec(event, can) }), "\u25E7": function(event) { can.onmotion.toggle(can, can.ui.project), can.onimport.layout(can) }, - "\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 {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} })) + "\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) }), + }, function(text, cb) { return cb && {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} })) }, tabview: function(can, path, file, line, cb) { var key = can.onexport.keys(can, path, file) function isCommand() { return line == ctx.INDEX || path == ctx.COMMAND } @@ -121,8 +120,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl can.page.SelectChild(can, can.ui._content.parentNode, can.page.Keys(html.DIV_PROFILE, [[[html.IFRAME, html.PROFILE]]]), function(item) { if (can.onmotion.toggle(can, item, item == msg._profile)) { can.ui.profile = msg._profile } }), can.ui.current && can.onmotion.toggle(can, can.ui.current, !isCommand() && !isDream()) - var ls = can.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("文件", ls.join(ice.PS), "类型", can.parse)), can.onimport.layout(can) + 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("文件", ls.join(ice.PS), "类型", can.db.parse)), can.onimport.layout(can) if (!skip) { can.onaction.selectLine(can, can.Option(nfs.LINE), true) } @@ -132,14 +131,13 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl function load(msg) { var skip = false; can.db.tabview[key] = msg can.onimport.tabs(can, [{name: file.split(isCommand()? ice.PT: ice.PS).pop(), text: file}], function(event, tabs) { can._tab = msg._tab = tabs._target, show(skip), skip = true - }, function(item) { can.onengine.signal(can, "tabview.view.delete", msg) + }, function(tabs) { can.onengine.signal(can, "tabview.view.delete", msg) msg._content != can.ui._content && can.page.Remove(can, msg._content), msg._profile != can.ui._profile && can.page.Remove(can, msg._profile) delete(can.ui._content._cache[key]), delete(can.ui._profile._cache[key]), delete(can.ui.display._cache[key]) delete(can._cache_data[key]), delete(can.db.tabview[key]) - }, can.ui.tabs).ondblclick = function(event) { + }, can.ui.tabs).ondblclick = function(event) { can.misc.Event(event, can, function(msg) { can.onaction.clear(event, can) - - } + }) } } if (can.db.tabview[key]) { return !can._msg._tab && !can.isSimpleMode()? load(can.db.tabview[key]): show() } isCommand()||isDream()? load(can.request({}, {index: file, line: line})): can.run({}, [path, file], load, true) @@ -181,6 +179,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl msg.Table(function(item) { item.display = msg.Option(ice.MSG_DISPLAY), item.height = height-2*html.ACTION_HEIGHT, item.width = width item.type = "story" can.onimport.plug(can, item, function(sub) { + can.page.ClassList.del(can, sub._target, html.HIDE) height && sub.ConfHeight(height-2*html.ACTION_HEIGHT), width && sub.ConfWidth(width) sub.onaction._output = function(_sub, _msg) { can.base.isFunc(cb) && cb(_sub, _msg) } sub.onaction.close = function() { can.onmotion.hidden(can, target), can.onimport.layout(can) } @@ -199,10 +198,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl } return can.onmotion.toggle(can, target, true), can.onimport.layout(can), can.user.toastSuccess(can) }, toolkit: function(can, meta, cb) { - can.onimport.plug(can, meta, function(sub) { - can.onappend.style(sub, html.FLOAT) - can.onappend.style(sub, html.HIDE) - can.ui.plug.appendChild(sub._legend), sub._legend.onclick = function(event) { + can.onimport.plug(can, meta, function(sub) { can.onappend.style(sub, [html.FLOAT, html.HIDE]) + can.ui.plug.appendChild(sub._legend), sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) { if (can.page.SelectOne(can, can.ui.plug, ice.PT+html.SELECT, function(target) { can.page.ClassList.del(can, target, html.SELECT); return target }) == event.target) { can.page.ClassList.add(can, sub._target, html.HIDE) } else { @@ -213,7 +210,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl } }) } - }, sub._delay_init = true + }) }, sub._delay_init = true sub.onexport.record = function(sub, value, key, line) { if (!line.file && !line.line) { return } can.onimport.tabview(can, line.path||can.Option(nfs.PATH), can.base.trimPrefix(line.file, nfs.PWD)||can.Option(nfs.FILE), parseInt(line.line)) }, sub.onaction.close = sub.select = function() { return sub._legend.click(), sub } @@ -263,18 +260,20 @@ Volcanos(chat.ONFIGURE, { }) Volcanos(chat.ONSYNTAX, {_init: function(can, msg, cb) { if (can.onmotion.cache(can, function(cache_data) { - can.file && (cache_data[can.file] = {current: can.current, max: can.max, profile_display: can.ui.profile.style.display, display_display: can.ui.display.style.display}) - can.file = can.onexport.keys(can, can.Option(nfs.PATH), can.Option(nfs.FILE)); var p = cache_data[can.file]; if (p) { can.current = p.current, can.max = p.max } - can.page.style(can, can.ui.profile, html.DISPLAY, p? p.profile_display: html.NONE), can.page.style(can, can.ui.display, html.DISPLAY, p? p.display_display: html.NONE) - can.parse = can.base.Ext(can.file), can.Status("模式", mdb.PLUGIN); return can.file + can.db.file && (cache_data[can.db.file] = {max: can.db.max, current: can.current, profile_display: can.ui.profile.className, display_display: can.ui.display.className}) + can.db.file = can.onexport.keys(can, can.Option(nfs.PATH), can.Option(nfs.FILE)); var p = cache_data[can.db.file]; if (p) { + can.db.max = p.max, can.current = p.current, can.ui.profile.className = p.profile_display, can.ui.display.className = p.display_display + } else { can.onmotion.hidden(can, can.ui.profile), can.onmotion.hidden(can, can.ui.display) } + can.db.parse = can.base.Ext(can.db.file), can.Status("模式", mdb.PLUGIN); return can.db.file }, can.ui._content, can.ui._profile, can.ui._display)) { return can.base.isFunc(cb) && cb(msg._content) } if (msg.Option(ctx.INDEX)) { return can.onsyntax._index(can, msg, cb) } function init(p) { - can.max = 0, can.core.List(can.ls = msg.Result().split(ice.NL), function(item) { can.onaction.appendLine(can, item) }) + can.db.max = 0, can.core.List(can.db.ls = msg.Result().split(ice.NL), function(item) { can.onaction.appendLine(can, item) }) + msg._can = can can.base.isFunc(cb) && cb(msg._content = can.ui._content), can.onengine.signal(can, "tabview.view.init", msg) - } can.require(["inner/syntax.js"], function() { can.Conf(chat.PLUG) && (can.onsyntax[can.parse] = can.Conf(chat.PLUG)) - var p = can.onsyntax[can.parse]; !p? can.runAction({}, mdb.PLUGIN, [can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { - init(p = can.onsyntax[can.parse] = can.base.Obj(msg.Result()||"{}")) + } can.require(["inner/syntax.js"], function() { can.Conf(chat.PLUG) && (can.onsyntax[can.db.parse] = can.Conf(chat.PLUG)) + var p = can.onsyntax[can.db.parse]; !p? can.runAction({}, mdb.PLUGIN, [can.db.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { + init(p = can.onsyntax[can.db.parse] = can.base.Obj(msg.Result()||"{}")) }): init(p) }) }, @@ -297,7 +296,7 @@ Volcanos(chat.ONSYNTAX, {_init: function(can, msg, cb) { }, _parse: function(can, line) { line = can.page.replace(can, line||"") function wrap(text, type) { return can.page.Format(html.SPAN, text, type) } - var p = can.onsyntax[can.parse]||{}; p = can.onsyntax[p.link]||p, p.split = p.split||{} + var p = can.onsyntax[can.db.parse]||{}; p = can.onsyntax[p.link]||p, p.split = p.split||{} if (p.prefix && can.core.Item(p.prefix, function(pre, type) { if (can.base.beginWith(line, pre)) { return line = wrap(line, type) } }).length > 0) { return line } if (p.suffix && can.core.Item(p.suffix, function(end, type) { if (can.base.endWith(line, end)) { return line = wrap(line, type) } }).length > 0) { return line } p.keyword && (line = can.core.List(can.core.Split(line, p.split.space||"\t ", p.split.operator||"{[(.,:;!?|&*/+-<=>)]}", {detail: true}), function(item, index, array) { @@ -324,7 +323,7 @@ Volcanos(chat.ONACTION, { _getLineno: function(can, line) { return can.page.Select(can, can.ui.content, "tr.line>td.line", function(td, index) { if (td.parentNode == line || index+1 == line) { return index+1 } })[0] }, appendLine: function(can, value) { var ui = can.page.Append(can, can.ui._content, [{type: html.TR, className: "line", list: [ - {view: [[nfs.LINE, "unselectable"], html.TD, ++can.max], onclick: function(event) { + {view: [nfs.LINE, html.TD, ++can.db.max], onclick: function(event) { can.onaction.selectLine(can, ui.tr) }, ondblclick: function(event) { can.onaction.find(event, can) @@ -363,7 +362,7 @@ Volcanos(chat.ONACTION, { favorLine: function(event, can, value) { can.user.input(event, can, [{name: mdb.ZONE, value: "hi"}, {name: mdb.NAME, value: "hello"}], function(data) { can.runAction(event, code.FAVOR, [ctx.ACTION, mdb.INSERT, mdb.ZONE, data.zone||"", - mdb.TYPE, can.parse, mdb.NAME, data.name||"", mdb.TEXT, (value||"").trimRight(), + mdb.TYPE, can.db.parse, mdb.NAME, data.name||"", mdb.TEXT, (value||"").trimRight(), nfs.PATH, can.Option(nfs.PATH), nfs.FILE, can.Option(nfs.FILE), nfs.LINE, can.Option(nfs.LINE), ], function() { can.user.toastSuccess(can) }) }) @@ -395,11 +394,11 @@ Volcanos(chat.ONACTION, { }, exec: function(event, can) { if (can.base.Ext(can.Option(nfs.FILE)) == nfs.JS) { delete(Volcanos.meta.cache[can.base.Path(ice.PS, ice.REQUIRE, can.Option(nfs.PATH), can.Option(nfs.FILE))]) } - can.runAction(can.request(event, {_toast: "执行中..."}), mdb.ENGINE, [can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.display(can, msg) }) + can.runAction(can.request(event, {_toast: "执行中..."}), mdb.ENGINE, [can.db.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.display(can, msg) }) }, show: function(event, can) { if (can.base.Ext(can.Option(nfs.FILE)) == nfs.JS) { delete(Volcanos.meta.cache[can.base.Path(ice.PS, ice.REQUIRE, can.Option(nfs.PATH), can.Option(nfs.FILE))]) } - can.runAction(can.request(event, {_toast: "渲染中..."}), mdb.RENDER, [can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.profile(can, msg) }) + can.runAction(can.request(event, {_toast: "渲染中..."}), mdb.RENDER, [can.db.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.profile(can, msg) }) }, plug: function(event, can) { function show(value) { input.cancel() @@ -408,7 +407,8 @@ Volcanos(chat.ONACTION, { } var input = can.user.input(event, can, [{type: html.TEXT, name: ctx.INDEX, run: function(event, cmds, cb) { can.run(event, cmds, function(msg) { if (cmds[0] == ctx.ACTION && cmds[1] == mdb.INPUTS && cmds[2] == ctx.INDEX) { var _msg = can.request({}) - can.core.Item(can.db.toolkit, function(index) { _msg.Push(ctx.INDEX, index).Push("cb", show) }), _msg.Push(ctx.INDEX, "") + can.core.Item(can.db.toolkit, function(index) { _msg.Push(ctx.INDEX, index).Push("cb", show) }), _msg.Push(ctx.INDEX, "").Push("cb", show) + can.core.List(msg.index, function() { msg.Push("cb", show) }) _msg.Copy(msg), cb(_msg) } else { cb(msg) } }, true) }}], function(list) { show(list[0]) }) @@ -440,7 +440,7 @@ Volcanos(chat.ONACTION, { can.onmotion.move(can, ui._target) var last = can.onaction._getLineno(can, can.current.line) function find(begin, text) { if (parseInt(text) > 0) { return can.onaction.selectLine(can, parseInt(text)) && meta.close() } - for (begin; begin <= can.max; begin++) { if (can.onexport.text(can, can.onaction._getLine(can, begin)).indexOf(text) > -1) { + for (begin; begin <= can.db.max; begin++) { if (can.onexport.text(can, can.onaction._getLine(can, begin)).indexOf(text) > -1) { return last = begin, can.onaction.selectLine(can, begin, true) } } last = 0, can.user.toast(can, "已经到最后一行") } @@ -480,7 +480,7 @@ Volcanos(chat.ONEXPORT, {list: ["目录", "类型", "文件", "行号", "跳转" }, keys: function(can, path, file) { return [path||can.Option(nfs.PATH), file||can.Option(nfs.FILE)].join(ice.DF) }, line: function(can, line) { return parseInt(can.core.Value(can.page.SelectOne(can, line, "td.line"), "innerText")) }, - position: function(can, index, total) { total = total||can.max; return (parseInt(index))+ice.PS+parseInt(total)+" = "+parseInt((index)*100/total)+"%" }, + position: function(can, index, total) { total = total||can.db.max; return (parseInt(index))+ice.PS+parseInt(total)+" = "+parseInt((index)*100/total)+"%" }, selection: function(can, str) { var s = document.getSelection().toString(), begin = str.indexOf(s), end = begin+s.length for (var i = begin; i >= 0; i--) { if (str[i].match(/[a-zA-Z0-9_.]/)) { s = str.slice(i, end) } else { break } } @@ -494,15 +494,15 @@ Volcanos(chat.ONEXPORT, {list: ["目录", "类型", "文件", "行号", "跳转" } } } var package = "", block = "", current = "", percent = "" 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.max||1))+"%" } } - if (can.parse == nfs.JS) { + 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) { if (_indent == 0 && can.base.beginWith(text, "Volcanos")) { var ls = can.core.Split(text, "\t ({:}),"); block = can.base.trimPrefix(ls[1], "chat.").toLowerCase() if (text.indexOf("_init") > -1) { push(block+ice.PT+"_init"+ice.DF+(index+1)) } } else if (_indent == 4) { var ls = can.core.Split(text, "\t ({:}),"); ls[0] && push(block+ice.PT+ls[0]+ice.DF+(index+1)) } - } else if (can.parse == nfs.GO) { + } else if (can.db.parse == nfs.GO) { var ls = can.core.Split(text, "\t *", "({:})") if (_indent == 0) { switch (ls[0]) { diff --git a/plugin/local/code/inner/debug.js b/plugin/local/code/inner/debug.js index 6fd68b9f..eb4fe1e2 100644 --- a/plugin/local/code/inner/debug.js +++ b/plugin/local/code/inner/debug.js @@ -8,6 +8,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { msg.Push(mdb.TEXT, item.slice(4).join(ice.SP)||"") }), msg.StatusTimeCount(), can.onmotion.clear(can), can.onappend.table(can, msg) can.page.Select(can, can._option, "input[name=name]", function(target) { - target.onkeyup = function(event) { can.onmotion.highlight(can, target.value) } + target.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { + can.onmotion.highlight(can, target.value) + }) } }) }}) diff --git a/plugin/local/code/inner/search.js b/plugin/local/code/inner/search.js index cb9d19ba..0129aefe 100644 --- a/plugin/local/code/inner/search.js +++ b/plugin/local/code/inner/search.js @@ -1,9 +1,10 @@ Volcanos(chat.ONIMPORT, {list: ["main", "filter", "grep:button", "history", "last"], _init: function(can, msg) { can.onmotion.clear(can), can.onappend.table(can, msg) can.onmotion.delay(can, function() { - msg can.page.Select(can, can._option, "input[name=filter]", function(target) { - target.onkeyup = function(event) { can.onmotion.highlight(can, target.value) } + target.onkeyup = function(event) { can.misc.Event(event, can, function(msg) { + can.onmotion.highlight(can, target.value) + }) } }) }) }}) diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js index 21c53b1f..901e7dc9 100644 --- a/plugin/local/code/vimer.js +++ b/plugin/local/code/vimer.js @@ -5,19 +5,22 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onengine.listen(can, "tabview.line.select", function(msg) { can.onaction._selectLine(can) }) can.onengine.plugin(can, can.onplugin), can.base.isFunc(cb) && cb(msg) can.ui.project.onscroll = function() { can.onmotion.clearFloat(can) } - can.isCmdMode() && can.run({}, [ctx.ACTION, ctx.COMMAND].concat(["can.topic", "cli.qrcode", "cli.runtime", "nfs.dir", "web.code.xterm"]), function(msg) { - msg.Table(function(value) { can.onimport.toolkit(can, value) }) + can.isCmdMode() && can.run({}, [ctx.ACTION, ctx.COMMAND].concat(["can.topic", "nfs.dir", "web.code.xterm", "web.code.git.status"]), function(msg) { + msg.Table(function(value) { can.onimport.toolkit(can, value, function(sub) { can.db.toolkit[value.index] = sub }) }) }) }, target) }) }, _input: function(can) { var ui = can.page.Append(can, can.ui.content.parentNode, [ {view: [code.CURRENT, html.INPUT], spellcheck: false, onkeydown: function(event) { - if (event.metaKey) { return can.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) } + if (event.metaKey) { return can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) } if (event.ctrlKey && can.onaction._complete(event, can)) { return } - can.db._keylist = can.onkeymap._parse(event, can, can.mode+(event.ctrlKey? "_ctrl": ""), can.db._keylist, can.ui.current) - if (can.mode == mdb.INSERT) { can.db._keylist = [], can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) } - if (can.mode == mdb.NORMAL) { can.onkeymap.prevent(event), can.Status("按键", can.db._keylist.join("")) } - }, onkeyup: function(event) { can.onaction._complete(event, can) }, onfocus: 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.INSERT) { can.db._keylist = [], can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) } + if (can.db.mode == mdb.NORMAL) { can.onkeymap.prevent(event), can.Status("按键", can.db._keylist.join("")) } + }, onkeyup: function(event) { + if (event.metaKey) { return can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) } + can.onaction._complete(event, can) + }, onfocus: function() { var target = can.ui.complete; can.current.line.appendChild(target), can.onmotion.toggle(can, target, true) }, onclick: function(event) { can.onkeymap._insert(event, can) @@ -151,9 +154,9 @@ Volcanos(chat.ONACTION, { }) return count } - can.onaction._run(event, can, button, [can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { - if (can.parse == nfs.GO) { var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content) - can.max = 0, can.core.List(can.ls = msg.Result().split(ice.NL), function(item) { can.onaction.appendLine(can, item) }) + can.onaction._run(event, can, button, [can.db.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { + if (can.db.parse == nfs.GO) { var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content) + can.db.max = 0, can.core.List(can.db.ls = msg.Result().split(ice.NL), function(item) { can.onaction.appendLine(can, item) }) can.onaction.selectLine(can, line+imports(msg.Result())-imports(msg.Option("content"))) } can.user.toastSuccess(can, button, can.Option(nfs.PATH)+can.Option(nfs.FILE)) }) @@ -197,14 +200,14 @@ Volcanos(chat.ONACTION, { function update() { target._pre = pre, target._end = end, target._index = -1 can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, can.ui.current.offsetLeft, html.MARGIN_TOP, can.current.line.offsetHeight) can.runAction(can.request(event, {text: pre}, can.Option()), code.COMPLETE, [], function(msg) { can.page.Appends(can, target, [{view: ["prefix", html.DIV, pre]}]) - if (can.parse == nfs.JS) { var msg = can.request() + if (can.db.parse == nfs.JS) { var msg = can.request() var ls = can.core.Split(can.core.Split(pre, "\t {(,:)}").pop(), ice.PT) var list = {can: can, msg: msg, target: target, window: window} can.core.ItemKeys(key == ""? list: can.core.Value(list, ls)||can.core.Value(window, ls)||window, function(k, v) { v && msg.Push(mdb.NAME, k).Push(mdb.TEXT, v.toString().split(ice.NL)[0]) }) } - can.core.Item(can.core.Value(can.onsyntax[can.parse], "keyword"), function(key, value) { + can.core.Item(can.core.Value(can.onsyntax[can.db.parse], "keyword"), function(key, value) { msg.Push(mdb.NAME, key) }) can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) { @@ -242,14 +245,14 @@ Volcanos(chat.ONACTION, { _selectLine: function(can) { if (!can.current) { return } 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.mode == mdb.NORMAL && can.onkeymap._normal(can) + can.db.mode == mdb.NORMAL && can.onkeymap._normal(can) 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) } }) }, - rerankLine: function(can, value) { can.max = can.page.Select(can, can.ui.content, "tr>td.line", function(td, index) { return td.innerText = index+1 }).length }, + rerankLine: function(can, value) { can.db.max = can.page.Select(can, can.ui.content, "tr>td.line", function(td, index) { return td.innerText = index+1 }).length }, insertLine: function(can, value, before) { var line = can.onaction.appendLine(can, value) before && can.ui.content.insertBefore(line, can.onaction._getLine(can, before)) return can.onaction.rerankLine(can), can.onaction._getLineno(can, line) @@ -265,7 +268,7 @@ Volcanos(chat.ONACTION, { }) Volcanos(chat.ONEXPORT, {list: ["目录", "模式", "按键", "类型", "文件", "行号", "跳转"]}) Volcanos(chat.ONKEYMAP, { - _model: function(can, value) { can.Status("模式", can.mode = value), can.page.styleClass(can, can.ui.current, [code.CURRENT, can.mode]), can.page.styleClass(can, can.ui.complete, [code.COMPLETE, can.mode, "float"]) }, + _model: function(can, value) { can.Status("模式", 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, "float"]) }, _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) }, @@ -370,7 +373,7 @@ Volcanos(chat.ONKEYMAP, { u: shy("撤销操作", function(can) { var cb = can.db.undo.pop(); cb && cb() }), gg: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count), true }), - G: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count = count>1? count: can.max), true }), + G: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count = count>1? count: can.db.max), true }), zt: shy("将当前行拉到屏幕最上", function(can, count) { return can.current.scroll(can.current.scroll()-(count>1? count: 3)), true }), zz: shy("将当前行拉到屏幕中间", function(can, count) { return can.current.scroll(can.current.scroll()-(count = count>1? count: can.current.window()/2)), true }), zb: shy("将当前行拉到屏幕最下", function(can, count) { return can.current.scroll(can.current.scroll()-can.current.window()+(count>1? count: 5)), true }), @@ -398,7 +401,7 @@ Volcanos(chat.ONKEYMAP, { Enter: shy("换行", function(can, target) { var rest = can.onkeymap.deleteText(target, target.selectionEnd).trimLeft(), text = can.ui.current.value var left = text.substr(0, text.indexOf(text.trimLeft()))||(text.trimRight() == ""? text: "") - var line = can.onaction.selectLine(can), next = rest; for (var i = line; i < can.max; i++) { next += can.onexport.text(can, i).trimLeft(); if (next != "") { break } } + var line = can.onaction.selectLine(can), next = rest; for (var i = line; i < can.db.max; i++) { next += can.onexport.text(can, i).trimLeft(); if (next != "") { break } } function deep(text) { var deep = 0; for (var i = 0; i < text.length; i++) { if (text[i] == "\t") { deep += 4 } else if (text[i] == " ") { deep++ } else { break } } return deep } text.trim() && can.core.List(["{}", "[]", "()", "``"], function(item) { if (can.base.endWith(text, item[0])) { if (can.base.beginWith(next, item[1])) { diff --git a/plugin/local/wiki/draw.js b/plugin/local/wiki/draw.js index 95e62499..4c7aaf2b 100644 --- a/plugin/local/wiki/draw.js +++ b/plugin/local/wiki/draw.js @@ -9,7 +9,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( can.ui = can.onlayout.profile(can), can.page.Modify(can, can.ui.content, msg.Results()||can.onexport.content(can)), can.onmotion.hidden(can, [can.ui.project, can.ui.profile]) can.page.Select(can, can.ui.content, html.SVG, function(target) { can.svg = can.group = can.onimport._block(can, target), can.onimport._group(can, target).click() can.page.Select(can, target, mdb.FOREACH, function(target) { can.onimport._block(can, target), can.page.tagis(target, svg.G) && target.Value(html.CLASS) && can.onimport._group(can, target) }) - can.core.ItemCB(can.onaction, function(key, cb) { target[key] = function(event) { cb(event, can) } }) + can.core.ItemCB(can.onaction, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, can) }) } }) }) }, _block: function(can, target) { diff --git a/plugin/local/wiki/draw/walk_trash.js b/plugin/local/wiki/draw/walk_trash.js index 14b96bd0..0900e13f 100644 --- a/plugin/local/wiki/draw/walk_trash.js +++ b/plugin/local/wiki/draw/walk_trash.js @@ -2,7 +2,7 @@ Volcanos(chat.ONIMPORT, { init: function(can, msg, cb, output, action, option) {output.innerHTML = ""; if (!msg.result || msg.result.length == 0) { var table = can.page.AppendTable(can, msg, output, msg.append); - table.onclick = function(event) {switch (event.target.tagName) { + table.onclick = function(event) { can.misc.Event(event, can, function(msg) { switch (event.target.tagName) { case "TD": can.onimport.which(event, table, msg.append, function(index, key) { can.Option("file", event.target.innerHTML.trim()) @@ -13,7 +13,7 @@ Volcanos(chat.ONIMPORT, { break case "TR": case "TABLE": - }} + } }) } return can.base.isFunc(cb) && cb(msg), table; } diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js index 8532a1cf..9cf2495d 100644 --- a/plugin/local/wiki/word.js +++ b/plugin/local/wiki/word.js @@ -27,7 +27,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( can.page.Select(can, can._output, can.page.Keys(wiki.H2, wiki.H3), function(_target) { can.page.Append(can, target, [{text: [_target.innerHTML, html.LI, _target.tagName], onclick: function() { _target.scrollIntoView() - }}]), _target.onclick = function(event) { target.scrollIntoView() } + }}]), _target.onclick = function(event) { can.misc.Event(event, can, function(msg) { + target.scrollIntoView() + }) } }) }, title: function(can, meta, target) { can.isCmdMode() && target.tagName == "H1" && can.user.title(meta.text) }, @@ -102,12 +104,14 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( chart: function(can, meta, target) { can.page.style(can, target, html.MAX_WIDTH, can.ConfWidth(), html.OVERFLOW, ice.AUTO) if (!meta.fg && !meta.bg) { target.className.baseVal = "story auto" } - target.onclick = function(event) { meta.index && can.runActionCommand(can.request(event, meta), meta.index, [nfs.FIND, event.target.innerHTML]) } - target.oncontextmenu = function(event) { + target.onclick = function(event) { can.misc.Event(event, can, function(msg) { + meta.index && can.runActionCommand(can.request(event, meta), meta.index, [nfs.FIND, event.target.innerHTML]) + }) } + target.oncontextmenu = function(event) { can.misc.Event(event, can, function(msg) { var ui = can.user.carte(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) { can.user.toimage(can, "hi", target) })); can.page.style(can, ui._target, {left: event.clientX, top: event.clientY}) - } + }) } }, image: function(can, meta, target) { can.page.style(can, target, html.MAX_HEIGHT, can.base.Min(can.ConfHeight(), window.innerHeight/2), html.MAX_WIDTH, can.ConfWidth()) }, video: function(can, meta, target) { can.page.style(can, target, html.MAX_HEIGHT, can.base.Min(can.ConfHeight(), window.innerHeight/2), html.MAX_WIDTH, can.ConfWidth()) }, diff --git a/plugin/story/trend.js b/plugin/story/trend.js index 3607a01e..4dde1712 100644 --- a/plugin/story/trend.js +++ b/plugin/story/trend.js @@ -62,7 +62,9 @@ Volcanos(chat.ONACTION, {list: [ can.onimport.draw(can, {shape: svg.RECT, points: [ order(index, args.step/4, item.close), order(index, args.step/4*3, item.begin), ], style: {rx: 0, ry:0}, _init: function(target) { - can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { cb(event, can, item) } }) + can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { + cb(event, can, item) + }) } }) }}, item.begin < item.close? white: black) }) }, @@ -89,7 +91,9 @@ Volcanos(chat.ONACTION, {list: [ function order(i) { return i*args.step+args.margin } function scale(y) { return (y - min)/(max - min)*(args.height-2*args.margin)+args.margin } can.core.Next(can.data, function(item, next, i) { can.core.Timer(parseInt(can.Action(html.SPEED)), next) can.onimport.draw(can, {shape: svg.RECT, style: {rx: 0, ry: 0}, points: [{x: order(i)+args.step/8.0, y: args.margin}, {x: order(i)+args.step/8.0*7, y: scale(item[field])}], _init: function(target) { - can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { cb(event, can, item) } }) + can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { + cb(event, can, item) + }) } }) }}, group) }) }) diff --git a/plugin/story/video.js b/plugin/story/video.js index 4aed992b..7b50c869 100644 --- a/plugin/story/video.js +++ b/plugin/story/video.js @@ -36,11 +36,11 @@ Volcanos(chat.ONACTION, { can.page.SelectAll(can, can._root._target, html.VIDEO, function(video) { video.playbackRate = parseFloat(can.Option("rate")) video.currentTime = parseInt(can.Option("skip")) - video.ontimeupdate = function(event) { + video.ontimeupdate = function(event) { can.misc.Event(event, can, function(msg) { if (video.currentTime > parseInt(can.Option("next"))) { can.onaction.next(event, can) } - }, video.play(), video.requestFullscreen() + }) }, video.play(), video.requestFullscreen() }) }, }) diff --git a/plugin/table.js b/plugin/table.js index 049a2d53..27272de2 100644 --- a/plugin/table.js +++ b/plugin/table.js @@ -1,13 +1,11 @@ -Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.clear(can, target) +Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(can, target) var cbs = can.onimport[can.Conf(ctx.STYLE)||msg.Option(ctx.STYLE)]; if (can.base.isFunc(cbs)) { can.core.CallFunc(cbs, {can: can, msg: msg, target: target}) can.page.ClassList.add(can, target, can._args[ctx.STYLE]) } else { can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target) - } can.onmotion.story.auto(can, target), can.base.isFunc(cb) && cb(msg) - if (can.isCmdMode()) { - can.page.style(can, can._output, html.MAX_HEIGHT, can.ConfHeight()) - } + } can.onmotion.story.auto(can, target) + if (can.isCmdMode()) { can.page.style(can, can._output, html.MAX_HEIGHT, can.ConfHeight()) } }, _system_app: function(can, msg, target) { can.page.Appends(can, target, msg.Table(function(item) { var name = item.name||item.text @@ -17,17 +15,6 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl ], onclick: function(event) { can.runAction(can.request(event, item, can.Option()), "xterm", []) }} })) }, - card: function(can, msg, target) { - can.page.Appends(can, target, msg.Table(function(item) { - return {view: html.ITEM+ice.SP+(item.status||""), list: [ - {view: [wiki.TITLE, html.DIV, item.name]}, - {view: [wiki.CONTENT, html.DIV, item.text]}, - {view: html.ACTION, inner: item.action, onclick: function(event) { - can.run(can.request(event, item), [ctx.ACTION, event.target.name]) - }}, - ]} - })) - }, _open: function(can, msg, target) { can.page.Appends(can, target, msg.Table(function(item) { return {view: html.ITEM, style: {"text-align": "center", margin: 10, width: 100, "float": "left"}, list: [ @@ -36,30 +23,114 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl ], onclick: function(event) { can.runAction(can.request(event, item, can.Option()), "click", []) }} })) }, - - _panel: function(can, target, action) { - var ui = can.page.Append(can, target, [html.ACTION, html.OUTPUT]) - var action = can.onappend._action(can, [], ui.action, kit.Dict( - cli.CLOSE, function(event) { can.onmotion.hidden(can, target), can.onimport.layout(can) }, - cli.CLEAR, function(event) { can.onmotion.clear(can, ui.output) }, - ice.SHOW, function(event) { can.onaction[ice.SHOW](event, can) }, - action, - mdb.PLUGIN, function(event) { can.user.input(event, can, [ctx.INDEX, ctx.ARGS], function(data) { - can.onimport.plug(can, data, function(sub) { - sub.ConfHeight(target.offsetHeight-4*html.ACTION_HEIGHT) - }, ui.output) - }) }, - )); target._toggle = function(event, show) { action[show? ice.SHOW: cli.CLOSE](event) } - return ui - }, - _title: function(can, title) { can.user.title(title) - // can.user.title(title+ice.SP+(can.misc.Search(can, ice.POD)||location.host)) - }, + _title: function(can, title) { can.user.title(title) }, title: function(can, title) { can._legend.innerHTML = title can.sup && can.sup._tabs && (can.sup._tabs.innerHTML = title) can.sup && can.sup._header_tabs && (can.sup._header_tabs.innerHTML = title) can.isCmdMode() && can.onimport._title(can, title) }, + + tabs: function(can, list, cb, cbs, action) { action = action||can._action + return can.page.Append(can, action, can.core.List(list, function(tabs) { + function close(target) { var next = target.nextSibling||target.previousSibling; if (!next) { return } + next.click(), can.onmotion.delay(can, function() { can.base.isFunc(cbs) && cbs(tabs), can.page.Remove(can, target) }) + } + return {view: html.TABS, title: tabs.text, list: [{text: [tabs.name, html.SPAN]}, {text: ["\u2715", html.SPAN, html.ICON], onclick: function(event) { + close(event.target.parentNode), can.onkeymap.prevent(event) + }}], onclick: function(event) { + can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs) + }, _init: function(target) { tabs._target = target; var menu = tabs._menu||shy() + can.page.Modify(can, target, {draggable: true, _close: function() { close(target) }, + ondragstart: function(event) { var target = event.target; action._drop = function(before) { action.insertBefore(target, before) } }, + ondragover: function(event) { event.preventDefault(), action._drop(event.target) }, + ondrop: function(event) { event.preventDefault(), action._drop(event.target) }, + oncontextmenu: function(event) { can.user.carte(event, can, kit.Dict("Close", function(event) { close(target) }, + "Close others", function(event) { can.page.Select(can, action, html.DIV_TABS, function(_item) { _item == target || close(_item) }) }, + ), ["Close", "Close others", ""].concat(menu.list), function(event, button, meta) { (meta[button]||menu)(event, button, meta) }) }, + }), can.onmotion.delay(can, function() { target.click() }) + }} + }))._target + }, + tool: function(can, list, cb, target) { target = target||can._output + can.core.List(list.reverse(), function(meta) { can.base.isString(meta) && (meta = {index: meta}) + can.onimport.plug(can, meta, function(sub) { sub._delay_init = true + sub.ConfHeight(can.ConfHeight()-4*html.ACTION_HEIGHT), sub.ConfWidth(can.ConfWidth()) + can.page.style(can, sub._output, html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth()) + can._status.appendChild(sub._legend), sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) { + if (can.page.Select(can, can._status, ice.PT+html.SELECT)[0] == event.target) { + can.page.ClassList.del(can, event.target, html.SELECT) + can.page.ClassList.del(can, sub._target, html.SELECT) + return + } + can.onmotion.select(can, target, html.FIELDSET, sub._target), sub.Focus() + can.onmotion.select(can, can._status, html.LEGEND, event.target) + if (sub._delay_init || meta.msg == true) { sub._delay_init = false, meta.msg = false, sub.Update() } + }) }, sub.select = function() { return sub._legend.click(), sub }, sub._legend.onmouseenter = null + sub.onaction.close = function() { sub.select() } + can.base.isFunc(cb) && cb(sub) + }, target) + }) + }, + plug: function(can, meta, cb, target) { if (!meta || !meta.index) { return } + meta.type = meta.type||"plug", meta.name = meta.index, can.onappend.plugin(can, meta, function(sub) { sub.sup = can + sub.ConfHeight(target.offsetHeight-2*html.ACTION_HEIGHT) + can.page.style(can, sub._output, html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth()) + sub.run = function(event, cmds, cb) { + if (can.page.Select(can, sub._option, "input[name=path]").length > 0 && sub.Option(nfs.PATH) == "") { + sub.request(event, {path: "./"}) + } + can.runActionCommand(can.request(event, can.Option()), meta.index, cmds, cb) } + sub.onaction.close = function() { can.onmotion.hidden(can, target) } + can.base.isFunc(cb) && cb(sub) + }, target) + }, + zone: function(can, list, target) { + return can.page.Append(can, target, can.core.List(list, function(zone) { can.base.isString(zone) && (zone = {name: zone}); return zone && {view: [[html.ZONE, zone.name]], list: [ + {view: html.ITEM, inner: can.user.trans(can, zone.name), _init: function(target) { + zone._legend = target + }, onclick: function() { + if (zone._delay_show) { zone._delay_show(zone._target, zone), delete(zone._delay_show) } + can.onmotion.toggle(can, zone._action), can.onmotion.toggle(can, zone._target) + }, oncontextmenu: function(event) { + zone._menu? can.user.carteRight(event, can, zone._menu.meta, zone._menu.list||can.core.Item(zone._menu.meta), function(event, button, meta) { + (meta[button]||can.onaction[button])(event, can, button) + }): can.onmotion.clearCarte(can) + }}, + {view: html.ACTION, _init: function(target) { zone._action = target + can.onappend._action(can, [{input: html.TEXT, placeholder: mdb.SEARCH, onkeyup: function(event) { + can.onkeymap.selectItems(event, can, zone._target) + can.page.Select(can, zone._target, html.DIV_LIST, function(item) { can.onmotion.toggle(can, item, true) }) + if (event.target.value == "") { + can.page.Select(can, zone._target, html.DIV_LIST, function(target) { can.page.ClassList.add(can, target, html.HIDE) }) + can.page.Select(can, zone._target, "div.switch", function(target) { can.page.ClassList.del(can, target, "open") }) + } + }, onfocus: function(event) { var target = event.target + target.setSelectionRange && target.setSelectionRange(0, target.value.length) + }, _init: function(target) { zone._search = target + }}], target, {}) + }}, + {view: html.LIST, _init: function(target) { can.ui[zone.name] = zone + zone._total = function(total) { return can.page.Modify(can, zone._search, {placeholder: "search in "+total+" item"}), total } + zone._target = target, zone.refresh = function() { zone._init(target, zone) } + can.base.isFunc(zone._init) && (zone._menu = zone._init(target, zone)||zone._menu) + if (zone._delay_show) { can.onmotion.hidden(can, zone._action), can.onmotion.hidden(can, zone._target) } + }} + ]} })) + }, + tree: function(can, list, field, split, cb, target, node) { + node = node||{"": target}; can.core.List(list, function(item) { + item[field] && can.core.List(item[field].split(split), function(value, index, array) { if (!value) { return } + var last = array.slice(0, index).join(split), name = array.slice(0, index+1).join(split); if (node[name]) { return } + var ui = can.page.Append(can, node[last], [{view: html.ITEM, list: [{view: ["switch"+(item.expand? " open": ""), html.DIV, (index==array.length-1?"":"\u25B8")]}, {view: [mdb.NAME, html.DIV, value+(index==array.length-1?"":"")], _init: item._init, oncontextmenu: function(event) { if (!item._menu) { return } + can.user.carteRight(event, can, item._menu.meta, item._menu.list||can.core.Item(item._meta.meta), function(event, button) { + (item._menu.meta[button]||item._menu)(event, can, button) + }) + }}], onclick: function(event) { if (node[name].childElementCount == 2) { node[name].firstChild.click() } + index < array.length - 1? can.page.ClassList.set(can, ui["switch"], "open", !can.page.ClassList.neg(can, node[name], html.HIDE)): can.base.isFunc(cb) && cb(event, item) + }}, {view: [[html.LIST, item.expand? "": html.HIDE]]}]); node[name] = ui.list + }) + }); return node + }, item: function(can, item, cb, cbs, target) { target = target||(can.ui && can.ui.project? can.ui.project: can._output) var ui = can.page.Append(can, target, [{view: [html.ITEM, html.DIV, item.nick||item.name], onclick: function(event) { can.onmotion.select(can, target, html.DIV_ITEM, event.target) @@ -86,113 +157,16 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl }}, {view: html.LIST}]); can.onimport.list(can, item, cb, ui.list) }) }, - tree: function(can, list, field, split, cb, target, node) { - node = node||{"": target}; can.core.List(list, function(item) { - item[field] && can.core.List(item[field].split(split), function(value, index, array) { if (!value) { return } - var last = array.slice(0, index).join(split), name = array.slice(0, index+1).join(split); if (node[name]) { return } - var ui = can.page.Append(can, node[last], [{view: html.ITEM, list: [{view: ["switch"+(item.expand? " open": ""), html.DIV, (index==array.length-1?"":"⌃")]}, {view: [mdb.NAME, html.DIV, value+(index==array.length-1?"":"")], _init: item._init, oncontextmenu: function(event) { if (!item._menu) { return } - can.user.carteRight(event, can, item._menu.meta, item._menu.list||can.core.Item(item._meta.meta), function(event, button) { - (item._menu.meta[button]||item._menu)(event, can, button) - }) - }}], onclick: function(event) { if (node[name].childElementCount == 2) { node[name].firstChild.click() } - index < array.length - 1? can.page.ClassList.set(can, ui["switch"], "open", can.page.ClassList.neg(can, node[name], "hide")): can.base.isFunc(cb) && cb(event, item) - }}, {view: [[html.LIST, item.expand? "": html.HIDE]]}]); node[name] = ui.list - }) - }); return node - }, - zone: function(can, list, target) { - return can.page.Append(can, target, can.core.List(list, function(zone) { can.base.isString(zone) && (zone = {name: zone}); return zone && {view: [[html.ZONE, zone.name]], list: [ - {view: html.ITEM, inner: can.user.trans(can, zone.name), _init: function(target) { - zone._legend = target - }, onclick: function() { - if (zone._delay_show) { zone._delay_show(zone._target, zone), delete(zone._delay_show) } - can.onmotion.toggle(can, zone._action), can.onmotion.toggle(can, zone._target) - }, oncontextmenu: function(event) { - zone._menu? can.user.carteRight(event, can, zone._menu.meta, zone._menu.list||can.core.Item(zone._menu.meta), function(event, button, meta) { - (meta[button]||can.onaction[button])(event, can, button) - }): can.onmotion.clearCarte(can) - }}, - {view: html.ACTION, _init: function(target) { zone._action = target - can.onappend._action(can, [{input: html.TEXT, placeholder: mdb.SEARCH, onkeyup: function(event) { - can.onkeymap.selectItems(event, can, zone._target) - can.page.Select(can, zone._target, html.DIV_LIST, function(item) { can.onmotion.toggle(can, item, true) }) - event.target.value == "" && can.page.Select(can, zone._target, html.DIV_LIST, function(target) { can.page.ClassList.add(can, target, html.HIDE) }) - }, onfocus: function(event) { var target = event.target - target.setSelectionRange && target.setSelectionRange(0, target.value.length) - }, _init: function(target) { zone._search = target - }}], target, {}) - }}, - {view: html.LIST, _init: function(target) { can.ui[zone.name] = zone - zone._total = function(total) { return can.page.Modify(can, zone._search, {placeholder: "search in "+total+" item"}), total } - zone._target = target, zone.refresh = function() { zone._init(target, zone) } - can.base.isFunc(zone._init) && (zone._menu = zone._init(target, zone)||zone._menu) - if (zone._delay_show) { can.onmotion.hidden(can, zone._action), can.onmotion.hidden(can, zone._target) } - }} - ]} })) - }, - - tabs: function(can, list, cb, cbs, action, each) { action = action||can._action - return can.page.Append(can, action, can.core.List(list, function(tabs) { - return {view: html.TABS, list: [{text: [tabs.name, html.SPAN]}, {text: ["\u2715", html.SPAN, html.ICON], onclick: function(event) { - var item = event.target.parentNode, next = item.nextSibling||item.previousSibling; if (!next) { return } - next.click(), can.onmotion.delay(can, function() { can.base.isFunc(cbs) && cbs(item._meta), can.page.Remove(can, item) }), can.onkeymap.prevent(event) - }}], title: tabs.text, onclick: function(event) { - can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs) - }, _init: function(item) { tabs._target = item - function close(item) { var next = item.nextSibling||item.previousSibling; if (!next) { return } - next.click(), can.onmotion.delay(can, function() { can.base.isFunc(cbs) && cbs(item._meta), can.page.Remove(can, item) }) - } - var menu = tabs._menu||shy({}, [], function(event, button, meta) { (meta[button])(event, can, button) }) - can.page.Modify(can, item, {draggable: true, _close: function() { close(item) }, _meta: tabs, - oncontextmenu: function(event) { can.user.carte(event, can, can.base.Copy(kit.Dict( - "Close", function(event) { close(item) }, - "Close others", function(event) { can.page.Select(can, action, html.DIV_TABS, function(_item) { _item == item || close(_item) }) }, - "Close all", function(event) { can.page.Select(can, action, html.DIV_TABS, close) }, - ), menu.meta), ["Close", "Close others", "Close all", ""].concat(menu.list), function(event, button, meta) { - menu(event, button, meta) - }) }, - ondragstart: function(event) { action._drop = function(before) { action.insertBefore(event.target, before) } }, - ondragover: function(event) { event.preventDefault(), action._drop(event.target) }, - ondrop: function(event) { event.preventDefault(), action._drop(event.target) }, - }) - can.base.isFunc(each) && each(item), can.onmotion.delay(can, function() { item.click() }) - }} - }))._target - }, - plug: function(can, meta, cb, target) { if (!meta || !meta.index) { return } - meta.type = meta.type||"plug", meta.name = meta.index, can.onappend.plugin(can, meta, function(sub) { sub.sup = can - // can.page.ClassList.add(can, sub._target, chat.FLOAT) - can.page.ClassList.add(can, sub._target, html.HIDE) - sub.ConfHeight(target.offsetHeight-2*html.ACTION_HEIGHT) - can.page.style(can, sub._output, html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth()) - sub.run = function(event, cmds, cb) { - if (can.page.Select(can, sub._option, "input[name=path]").length > 0 && sub.Option(nfs.PATH) == "") { - sub.request(event, {path: "./"}) - } - can.runActionCommand(can.request(event, can.Option()), meta.index, cmds, cb) } - sub.onaction.close = function() { can.onmotion.hidden(can, target) } - can.base.isFunc(cb) && cb(sub) - }, target) - }, - tool: function(can, list, cb, target) { target = target||can._output - can.core.List(list.reverse(), function(meta) { can.base.isString(meta) && (meta = {index: meta}) - can.onimport.plug(can, meta, function(sub) { sub._delay_init = true - sub.ConfHeight(can.ConfHeight()-4*html.ACTION_HEIGHT), sub.ConfWidth(can.ConfWidth()) - can.page.style(can, sub._output, html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth()) - can._status.appendChild(sub._legend), sub._legend.onclick = function(event) { - if (can.page.Select(can, can._status, ice.PT+html.SELECT)[0] == event.target) { - can.page.ClassList.del(can, event.target, html.SELECT) - can.page.ClassList.del(can, sub._target, html.SELECT) - return - } - can.onmotion.select(can, target, html.FIELDSET, sub._target), sub.Focus() - can.onmotion.select(can, can._status, html.LEGEND, event.target) - if (sub._delay_init || meta.msg == true) { sub._delay_init = false, meta.msg = false, sub.Update() } - }, sub.select = function() { return sub._legend.click(), sub }, sub._legend.onmouseenter = null - sub.onaction.close = function() { sub.select() } - can.base.isFunc(cb) && cb(sub) - }, target) - }) + card: function(can, msg, target) { + can.page.Appends(can, target, msg.Table(function(item) { + return {view: html.ITEM+ice.SP+(item.status||""), list: [ + {view: [wiki.TITLE, html.DIV, item.name]}, + {view: [wiki.CONTENT, html.DIV, item.text]}, + {view: html.ACTION, inner: item.action, onclick: function(event) { + can.run(can.request(event, item), [ctx.ACTION, event.target.name]) + }}, + ]} + })) }, }) Volcanos(chat.ONLAYOUT, { diff --git a/proto.js b/proto.js index 257efc68..06d888d4 100644 --- a/proto.js +++ b/proto.js @@ -1,7 +1,11 @@ var kit = {proto: function(sub, sup) { return sub.__proto__ = sup, sub }, Dict: function() { var res = {}, arg = arguments; for (var i = 0; i < arg.length; i += 2) { var key = arg[i] - if (typeof key == "object") { i--; for (var k in key) { res[k] = key[k] } - for (var j = 0; j < key.length; j += 2) { res[key[j]] = key[j+1] } + if (typeof key == "object") { i--; + if (key.length == undefined) { + for (var k in key) { res[k] = key[k] } + } else { + for (var j = 0; j < key.length; j += 2) { res[key[j]] = key[j+1] } + } } else if (typeof key == "string" && key) { res[key] = arg[i+1] } } return res }, } @@ -114,6 +118,7 @@ var cli = { BEGIN: "begin", START: "start", OPEN: "open", CLOSE: "close", STOP: "stop", END: "end", RESTART: "restart", COLOR: "color", WHITE: "white", BLACK: "black", RED: "red", GREEN: "green", BLUE: "blue", YELLOW: "yellow", CYAN: "cyan", PURPLE: "purple", MAGENTA: "magenta", GLASS: "transparent", + GRAY: "gray", MAKE: "make", MAIN: "main", EXEC: "exec", DONE: "done", COST: "cost", FROM: "from", CLEAR: "clear", } var log = { @@ -144,7 +149,7 @@ var chat = { HEADER: "Header", ACTION: "Action", FOOTER: "Footer", libs: ["/lib/base.js", "/lib/core.js", "/lib/date.js", "/lib/misc.js", "/lib/page.js", "/lib/user.js"], - panel_list: [{name: "Header", pos: "head"}, {name: "River", pos: "left"}, {name: "Action", pos: "main"}, {name: "Search", pos: "auto"}, {name: "Footer", pos: "foot"}], + panel_list: [{name: "Header", style: "head"}, {name: "River", style: "left"}, {name: "Action", style: "main"}, {name: "Search", style: "auto"}, {name: "Footer", style: "foot"}], plugin_list: [ "/plugin/state.js", "/plugin/input.js", @@ -246,7 +251,7 @@ function shy(help, meta, list, cb) { var arg = arguments, i = 0; function next(t }; var _can_name = "", _can_path = "" var Volcanos = shy({version: window._version||"", iceberg: "/chat/", volcano: "/frame.js", cache: {}, pack: {}, args: {}}, function(name, can, libs, cb) { var meta = arguments.callee.meta, list = arguments.callee.list; if (typeof name == lang.OBJECT) { - if (name.length > 0) { return Volcanos({panels: [{name: chat.HEADER, pos: html.HIDE, state: [mdb.TIME, aaa.USERNICK]}, {name: chat.ACTION, pos: html.MAIN, tool: name}, {name: chat.FOOTER, pos: html.HIDE}]}) } + if (name.length > 0) { return Volcanos({panels: [{name: chat.HEADER, style: html.HIDE, state: [mdb.TIME, aaa.USERNICK]}, {name: chat.ACTION, style: html.MAIN, tool: name}, {name: chat.FOOTER, style: html.HIDE}]}) } var Config = name; name = Config.name||ice.CAN, _can_name = "", _can_path = "" meta.iceberg = Config.iceberg||meta.iceberg, meta.libs = Config.libs||chat.libs, panels = Config.panels||chat.panel_list libs = [], panels.forEach(function(p) { p && (libs = libs.concat(p.list = p.list||["/panel/"+p.name+nfs._JS, "/panel/"+p.name+nfs._CSS])) }), libs = libs.concat(Config.plugin||chat.plugin_list) @@ -349,10 +354,10 @@ try { if (typeof(window) == lang.OBJECT) { // chrome case nfs.JS: var item = document.createElement(nfs.SCRIPT); item.src = url+Volcanos.meta.version, item.onerror = cb, item.onload = cb, document.body.appendChild(item); break } } Volcanos.meta._init = function(can) { - var last = can.page.width() < can.page.height(); window.onresize = function(event) { + var last = can.page.width() < can.page.height(); window.onresize = function(event) { can.misc.Event(event, can, function(msg) { if (can.user.isMobile && last === can.page.width() < can.page.height()) { return } last = can.page.width() < can.page.height() can.onengine.signal(can, chat.ONRESIZE, can.request(event, kit.Dict(html.HEIGHT, window.innerHeight, html.WIDTH, window.innerWidth))) - } + }) } } } else { // nodejs global.kit = kit, global.ice = ice