From 8cff6f4572789cbdb8000fc49f79518738741e96 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Fri, 27 Jan 2023 20:54:00 +0800 Subject: [PATCH] opt action.js --- frame.js | 26 ++-- index.css | 24 +--- lib/base.js | 6 +- lib/misc.js | 2 +- lib/user.js | 4 +- panel/action.css | 87 +++--------- panel/action.js | 269 ++++++++++++------------------------- panel/footer.js | 3 +- panel/header.js | 70 ++++++---- panel/river.js | 5 +- plugin/input.js | 2 +- plugin/local/code/xterm.js | 32 ++--- plugin/state.js | 20 ++- plugin/story/trend.js | 4 +- proto.js | 8 +- 15 files changed, 221 insertions(+), 341 deletions(-) diff --git a/frame.js b/frame.js index de76cb76..062a369e 100644 --- a/frame.js +++ b/frame.js @@ -1,7 +1,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.require([can.volcano], null, function(can, key, sub) { can[key] = sub }) if (!can.user.isMailMaster) { if (can.misc.Search(can, ice.MSG_SESSID)) { can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID)); return can.misc.Search(can, ice.MSG_SESSID, "") } } can.user.title(can.misc.Search(can, chat.TITLE)||can.misc.Search(can, ice.POD)||location.host) - can.onappend.topic(can, html.DARK), can.onappend.topic(can, html.LIGHT, {panel: cli.WHITE, plugin: cli.ALICEBLUE, legend: "lightsteelblue", input: cli.WHITE, output: cli.WHITE, table: cli.ALICEBLUE, + can.onappend.theme(can, html.DARK), can.onappend.theme(can, html.LIGHT, {panel: cli.WHITE, plugin: cli.ALICEBLUE, legend: "lightsteelblue", input: cli.WHITE, output: cli.WHITE, table: cli.ALICEBLUE, hover: cli.ALICEBLUE, border: cli.TRANSPARENT, label: cli.BLACK, text: cli.BLACK, info: cli.BLUE, warn: cli.RED}) can.run = function(event, cmds, cb) { var msg = can.request(event); cmds = cmds||[]; return (can.onengine[cmds[0]]||can.onengine._remote)(event, can, msg, can, cmds, cb) } can.core.Next(list, function(item, next) { item.type = chat.PANEL @@ -26,7 +26,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.requ if (panel.onengine._static(event, can, msg, panel, cmds, cb)) { return } var toast, _toast = msg.Option(chat._TOAST); if (_toast) { can.onmotion.delay(can, function() { toast = toast||can.user.toastProcess(msg._can, _toast) }, 500) } msg.option = can.core.List(msg.option, function(item) { return [chat._TOAST, ice.MSG_HANDLE].indexOf(item) > -1 && delete(msg[item])? undefined: item }) - msg.OptionDefault(ice.MSG_TOPIC, can.getHeader(chat.TOPIC), ice.SESS_HEIGHT, panel.Conf(html.HEIGHT), ice.SESS_WIDTH, panel.Conf(html.WIDTH)) + msg.OptionDefault(ice.MSG_THEME, can.getHeader(chat.THEME), ice.SESS_HEIGHT, panel.Conf(html.HEIGHT), ice.SESS_WIDTH, panel.Conf(html.WIDTH)) if (can.base.isUndefined(msg[ice.MSG_DAEMON])) { var sub = msg._can; can.base.isUndefined(sub._daemon) && can.ondaemon._list[0] && (sub._daemon = can.ondaemon._list.push(sub)-1) if (sub._daemon) { msg.Option(ice.MSG_DAEMON, can.core.Keys(can.ondaemon._list[0], sub._daemon)) } } can.onengine.signal(panel, chat.ONREMOTE, can.request({}, {_follow: panel._follow, _msg: msg, _cmds: cmds})) @@ -55,7 +55,13 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.requ return can.base.isString(item) && (item = can.core.SplitInput(item, can.base.isFunc(command.meta[item])? html.BUTTON: type)), item.type != html.SELECT && (type = item.type), button = button || item.type == html.BUTTON, item }); if (!button) { command.list.push(can.core.SplitInput(ice.LIST, html.BUTTON)) } command.can = can, command.meta.name = name, arguments.callee.meta[_name] = command }), - listen: shy(function(can, name, cb) { arguments.callee.meta[name] = (arguments.callee.meta[name]||[]).concat(cb) }), + listen: shy(function(can, name, cb, target) { + if (target) { + target[name] = function(event) { can.misc.Event(event, can, cb) } + } else { + arguments.callee.meta[name] = (arguments.callee.meta[name]||[]).concat(cb) + } + }), signal: function(can, name, msg) { msg = msg||can.request(); var _msg = name == chat.ONREMOTE? msg.Option("_msg"): msg _msg.Option(ice.LOG_DISABLE) == ice.TRUE || can.misc.Log(name, can._name, (msg._cmds||[]).join(ice.SP), name == chat.ONMAIN? can: _msg) // _msg.Option(ice.LOG_DISABLE) == ice.TRUE || can.misc.Log(name, can._name, (msg._cmds||[]).join(ice.SP), name == chat.ONMAIN? can: _msg, _msg._can._target) @@ -217,7 +223,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }) }, - topic: function(can, topic, color, style, list) { const PANEL_STYLE = "panel-style", PLUGIN_STYLE = "plugin-style" + theme: function(can, theme, 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" @@ -289,7 +295,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { 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+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)}) + }).join(ice.NL) } can.page.Append(can, document.head, ctx.STYLE, {"innerText": render(html.BODY+ice.PT+theme, 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) @@ -352,7 +358,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { 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) + }, target, ui[item._index] = can.onappend.field(can, item.type, {name: item.index.split(ice.PT).pop(), help: item.help}, target)._target) } else { can.page.Append(can, target, [item]) } } }); return list } ui.list = append(target, type, list||[html.PROJECT, [[html.CONTENT, html.PROFILE], html.DISPLAY]]) @@ -390,7 +396,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { can.runAction(can.request()._caller(), 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.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.type = meta.type||chat.STORY, meta.name = meta.name||value.meta&&value.meta.name||"", meta.height = meta.height||can.ConfHeight()-2*html.ACTION_HEIGHT, 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) { @@ -443,8 +449,10 @@ Volcanos(chat.ONLAYOUT, {_init: function(can, target) { target = target||can._ro 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} if (right) { - for (var p = event.target; p != document.body; p = p.parentNode) { - var _right = p.clientLeft+p.clientWidth+10; if (_right < layout.left) { layout.left = _right } + for (var p = event.target; p && p != document.body; p = p.parentNode) { + var _right = p.clientLeft+p.clientWidth+10 + // if (_right < layout.left) { layout.left = _right } + var _right = p.offsetLeft+p.offsetWidth+10 } } can.getActionSize(function(left, top, width, height) { left = left||0, top = top||0, height = can.base.Max(height, can.page.height()-top) diff --git a/index.css b/index.css index caa5b6d4..3d643f98 100644 --- a/index.css +++ b/index.css @@ -118,14 +118,15 @@ div.action>div.tabs { padding:5px; height:31px; } div.status>div.item { padding:5px; height:30px; } div.status>div.item>label { font-size:0.6rem; } /* display */ -form.option, div.action { display:contents; } form.option.hide, div.action.hide { display:none; } +div.action { display:contents; } form.option.hide, div.action.hide { display:none; } +// 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.cmd, form.option>div.textarea { width:100%; } textarea { resize:vertical; } legend, form.option, form.option>div.item, div.action, div.action>div.item, div.action>div.tabs, div.status>div.item, div.layout.flex>* { float:left; } 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, div.carte, fieldset.input { overflow:auto; } fieldset>div.output, fieldset>div.status, div.item.textarea, div.project div.item, div.content, div.code, div.story[data-type=spark] { clear:both; } fieldset>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(.output):not(.float):not(.full):not(.cmd) { padding:10px; margin:10px; } fieldset.plugin:not(.float):not(.full):not(.cmd)>legend { float:none; } fieldset.auto, fieldset.full, fieldset.float, div.float { position:fixed; z-index:10; } fieldset.plug { position:absolute; bottom:0; right:0; } fieldset.cmd fieldset.plug { position:fixed; bottom:31px; right:0; } @@ -157,7 +158,7 @@ div.story[data-type=spark] span:hover { background-color:deepskyblue; box-shadow select, input[type=text], textarea { box-shadow:4px 4px 20px 4px #626bd0; } legend, select, input[type=button], div.tabs, div.item, span.item, th, td, h1, h2, h3 { cursor:pointer; } div.title, div.story[data-type=spark] { cursor:copy; } -/* topic */ +/* theme */ body.black a { color:yellow; } body.black div.project div.zone>div.list>div.zone>div.item { background-color:#09466fc2; } body.white { background-color:rgba(5,34,56,0.75); color:white; } @@ -228,6 +229,7 @@ body.print div.float { background-color:snow; } body.print select, body.print input[type=text], body.print textarea { box-shadow:4px 4px 20px 4px lightgray; } body.print fieldset.draw div.output { background-color:lightgray; } body.print fieldset.draw div.output div.content svg { background-color:lightgray; } +body.dark ::selection { background-color:#033a3a; } /* mobile */ body.mobile legend { font-size:1.6rem; height:38px; } body.mobile select { font-size:1.4rem; height:38px; } @@ -289,21 +291,6 @@ body.mobile table.layout td.content div.toggle.project { width:30px; padding-top body.mobile table.layout td.content div.toggle.profile { width:30px; padding-top:35px; } body.mobile table.layout td.content div.toggle.display { margin-top:-30px; height:30px; } body.mobile table.layout td.content div.toggle.display>div { translate:5px -15px; } -/* flex */ -div.layout.tabs>div.tabs { display:flex; overflow:auto; } -div.layout.tabs>div.tabs>div { padding:10px; height:32px; flex:1; } -div.layout.tabs>div.tabs>div:hover { background-color:steelblue; } -div.layout.tabs>div.list { width:100%; height:100%; flex:1; } -div.layout.tabs>div.list>div { height:100%; display:none; } -div.layout.tabs>div.list>div.select { display:block; } -div.layout.tabs.left { display:flex; } -div.layout.tabs.left>div.tabs { flex-direction:column; } -div.layout.tabs.left>div.tabs>div { writing-mode:tb; } -div.layout.tabs.right { display:flex; } -div.layout.tabs.right>div.tabs { flex-direction:column; } -div.layout.tabs.right>div.tabs>div { writing-mode:tb; } -div.layout.tabs.box>div.list { height:unset; } -div.layout.tabs.box>div.tabs { background-color:steelblue; text-align:center; padding:3px; display:block; } /* table card */ div.output.card div.item.stop { color:gray; } div.output.card div.item { padding:10px; border:#e7e7e7 solid 1px; margin:10px; width:240px; float:left; } @@ -321,4 +308,3 @@ div.story[data-type=spark]::-webkit-scrollbar { width:0 !important; height:0 !im div.project::-webkit-scrollbar { width:0 !important; height:0 !important; } div.content::-webkit-scrollbar { width:0 !important; height:0 !important; } -body.dark ::selection { background-color:#033a3a; } diff --git a/lib/base.js b/lib/base.js index a0dfd925..edccc945 100644 --- a/lib/base.js +++ b/lib/base.js @@ -124,7 +124,7 @@ Volcanos("base", { for (var i = 0; i < arguments.length; i++) { var v = arguments[i] if (typeof v == lang.OBJECT) { if (v == null) { continue } if (v.length > 0) { return v } for (var k in v) { return v } - } else if (typeof v == lang.STRING && v) { return v + } else if (typeof v == lang.STRING) { if (v == "") { continue } else { return v } } else if (v == undefined) { continue } else { return v } } }, @@ -140,7 +140,9 @@ Volcanos("base", { if (arguments.length > 2) { for (var i = 1; i < arguments.length; i++) { str = callee(str, arguments[i]) } return str } if (str.indexOf(pre) == -1) { return str } return str.slice(pre.length) }, - trimSuffix: function(str, end) { var index = str.lastIndexOf(end); if (index == -1 || index+end.length != str.length) { return str } return str.slice(0, index) }, + trimSuffix: function(str, end) { while (str) { var index = str.lastIndexOf(end) + if (index == -1 || index+end.length != str.length) { break } str = str.slice(0, index) + } return str }, trim: function(args) { if (this.isString(args)) { return args.trim() } if (this.isArray(args)) { for (var i = args.length-1; i >= 0; i--) { if (!args[i]) { args.pop() } else { break } } } return args diff --git a/lib/misc.js b/lib/misc.js index 6fa33a3c..3c2117a6 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -171,7 +171,7 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} MergeCache: function(can, hash) { return can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true) }, MergePodCmd: function(can, objs) { objs.pod = can.core.Keys(can.misc.Search(can, ice.POD), objs.pod) - objs.topic = objs.topic||can.misc.Search(can, chat.TOPIC) + objs.theme = objs.theme||can.misc.Search(can, chat.THEME) return can.misc.MergeURL(can, objs, true) }, MergeURL: function(can, objs, clear) { var pod = "" diff --git a/lib/user.js b/lib/user.js index 19ec4832..b618d68f 100644 --- a/lib/user.js +++ b/lib/user.js @@ -36,7 +36,7 @@ Volcanos("user", {info: {}, agent: { open: function(url) { window.open(url) || (location.href = url) }, close: function(url) { window.close() }, title: function(text) { if (window.webview) { return title(text) } return text && (document.title = text), document.title }, - topic: function(can, name) { can.base.isString(name) && (name = [name]) || name || [] + theme: function(can, name) { can.base.isString(name) && (name = [name]) || name || [] can.user.isWebview && name.push(html.WEBVIEW), can.user.isMobile && name.push(html.MOBILE) && can.user.isLandscape() && name.push(html.LANDSCAPE) can.Conf(chat.DISPLAY) && name.push(can.Conf(chat.DISPLAY)), can.user.mod.isCmd && name.push(chat.SIMPLE) can.user.language(can) && name.push(can.user.language(can)), can.page.styleClass(can, document.body, name.join(ice.SP)) @@ -101,7 +101,7 @@ Volcanos("user", {info: {}, agent: { meta = meta||can.ondetail||can.onaction||{}, list = can.base.getValid(list, meta.list, can.core.Item(meta)); if (!list || list.length == 0) { return } function click(event, button) { can.misc.Event(event, can, function(msg) { can.onkeymap.prevent(event) meta[button]? meta[button](event, can, button): can.base.isFunc(cb)? cb(event, button, meta, carte): - can.core.CallFunc([can.onaction, button], [event, can, button]), can.page.Remove(can, ui._target) + can.core.CallFunc([can.onaction, button], [event, can, button]) // , can.onmotion.delay(can, function() { carte._sub || can.page.Remove(can, ui._target) }) }) } function remove_sub(carte) { carte._sub && can.page.Remove(can, carte._sub._target), delete(carte._sub) } var ui = can.page.Append(can, document.body, [{view: [[chat.CARTE, meta._style||"", chat.FLOAT]], list: can.core.List(list, function(item, index) { diff --git a/panel/action.css b/panel/action.css index 3fe9c5a8..1f6c5147 100644 --- a/panel/action.css +++ b/panel/action.css @@ -1,77 +1,24 @@ fieldset.Action { min-width:160px; } fieldset.Action>div.action { background-color:#4682b46b; width:100%; display:none; } -fieldset.Action>div.action div { font-size:1.1rem; cursor:pointer; padding:5px 20px; height:31px; float:left; } -fieldset.Action>div.action div.select { background-color:#6495ed63; } -fieldset.Action>div.action div:hover { background-color:#6495ed63; } +fieldset.Action>div.action div.tabs { font-size:1.1rem; padding:5px 20px; } +fieldset.Action>div.action div.tabs.select { background-color:#6495ed63; } +fieldset.Action>div.action div.tabs:hover { background-color:#6495ed63; } fieldset.Action.tabs>div.action { display:block; } -fieldset.Action.tabs>div.output { overflow:hidden; } fieldset.Action.tabs>div.output>fieldset>legend { display:none; } -fieldset.Action.tabs>div.output>fieldset.plugin { display:none; } -fieldset.Action.tabs>div.output>fieldset.plugin.select { display:block; } -fieldset.Header action>div.tabs { padding:0; margin-left:20px; display:contents; } -fieldset.Header action>div.tabs:hover { background-color:none; } -fieldset.Header div.tabs div.tabs { padding:5px 10px; } -fieldset.Header div.tabs div.tabs:hover { background-color:#6495ed63; } -fieldset.Action.tabview>div.output { overflow:hidden; } -fieldset.Action.tabview>div.output fieldset.plugin.iframe div.output { overflow:hidden; } -fieldset.Action.tabview>div.output>fieldset>legend { display:none; } -fieldset.Action.tabview>div.output>fieldset.plugin { padding:0; margin:0; display:none; overflow:auto; } -fieldset.Action.tabview>div.output>fieldset.plugin.select { display:block; } -fieldset.Action.tabview>div.output>fieldset.plugin>form.option { display:none; } -fieldset.Action.tabview>div.output>fieldset.plugin>div.action { display:none; } -fieldset.Action.tabview>div.output>fieldset.plugin>div.output { overflow:auto; } -fieldset.Action.tabview>div.output>fieldset.plugin>div.status { display:none; } -fieldset.Action.horizon>div.output>fieldset.plugin { padding:0; margin:0; overflow:auto; float:left; } -fieldset.Action.horizon>div.output>fieldset.plugin>legend { display:none; } -fieldset.Action.horizon>div.output>fieldset.plugin>form.option { display:none; } -fieldset.Action.horizon>div.output>fieldset.plugin>div.action { display:none; } -fieldset.Action.horizon>div.output>fieldset.plugin>div.output { overflow:auto; } -fieldset.Action.horizon>div.output>fieldset.plugin>div.status { display:none; } -fieldset.Action.vertical>div.output>fieldset.plugin { padding:0; margin:0; overflow:auto; float:left; } -fieldset.Action.vertical>div.output>fieldset.plugin>legend { display:none; } -fieldset.Action.vertical>div.output>fieldset.plugin>form.option { display:none; } -fieldset.Action.vertical>div.output>fieldset.plugin>div.action { display:none; } -fieldset.Action.vertical>div.output>fieldset.plugin>div.output { overflow:auto; } -fieldset.Action.vertical>div.output>fieldset.plugin>div.status { display:none; } -fieldset.Action.grid>div.output>fieldset.plugin { overflow:auto; float:left; } -fieldset.Action.grid>div.output>fieldset.plugin>div.output { overflow:auto; } +fieldset.Action.tabs>div.output>fieldset.plugin:not(.select) { display:none; } +fieldset.Header div.Action>div.tabs { margin-left:20px; float:left; } +fieldset.Header div.Action>div.tabs:hover { background-color:none; } +fieldset.Header div.tabs>div.tabs { padding:5px 10px; height:31px; float:left; } +fieldset.Header div.tabs>div.tabs:hover { background-color:#6495ed63; } +fieldset.Action.tabview>div.output>fieldset.plugin:not(.select) { display:none; } +fieldset.Action.vertical>div.output>fieldset.plugin { float:left; } +fieldset.Action.horizon>div.output>fieldset.plugin { float:left; } +fieldset.Action.flow>div.output>fieldset.plugin { float:left; } +fieldset.Action.free>div.output>fieldset.plugin { position:absolute; } +fieldset.Action.free>div.output>fieldset.plugin.select { z-index:10; } +fieldset.Action.grid>div.output>fieldset.plugin { float:left; } fieldset.Action.grid>div.output>fieldset.plugin>div.action { display:none; } fieldset.Action.grid>div.output>fieldset.plugin>div.status { display:none; } fieldset.Action.grid>div.output>fieldset.plugin>form.option input[type=text] { width:80px; } -fieldset.Action.flow>div.output>fieldset.plugin { float:left; } -fieldset.Action.free>div.output>fieldset.plugin { position:absolute; } -fieldset.Action.free>div.output>fieldset.plugin.select { display:block; } -fieldset.Action>div.project.toggle { - background-color:cornsilk; opacity:0.4; color:teal; font-size:36px; padding-top:50px; height:150px; width:20px; position:fixed; top:30%; - border-top-right-radius:20px; border-bottom-right-radius:20px; -} - -/* flex */ -div.layout.tabs>div.tabs { display:flex; overflow:auto; } -div.layout.tabs>div.tabs>div { padding:10px; height:32px; flex:1; } -div.layout.tabs>div.tabs>div:hover { background-color:steelblue; } -div.layout.tabs>div.list { width:100%; height:100%; flex:1; } -div.layout.tabs>div.list>div { height:100%; display:none; } -div.layout.tabs>div.list>div.select { display:block; } -div.layout.tabs.left { display:flex; } -div.layout.tabs.left>div.tabs { flex-direction:column; } -div.layout.tabs.left>div.tabs>div { writing-mode:tb; } -div.layout.tabs.right { display:flex; } -div.layout.tabs.right>div.tabs { flex-direction:column; } -div.layout.tabs.right>div.tabs>div { writing-mode:tb; } -div.layout.tabs.box>div.list { height:unset; } -div.layout.tabs.box>div.tabs { background-color:steelblue; text-align:center; padding:3px; display:block; } -/* layout */ -table.layout { border-spacing:0; } -table.layout td { vertical-align:top; } -table.layout td.content div.toggle { background-color:#4682b46b; color:white; font-size:24px; position:absolute; } -table.layout td.content div.toggle>div { display:table-cell; } -table.layout td.content div.toggle.project { padding-top:50px; height:130px; width:15px; top:20%; left:0; border-top-right-radius:10px; border-bottom-right-radius:10px; } -table.layout td.content div.toggle.profile { padding-top:50px; height:130px; width:15px; top:20%; right:0; border-top-left-radius:10px; border-bottom-left-radius:10px; } -table.layout td.content div.toggle.display { margin-top:-15px; height:15px; width:130px; left:40%; border-top-left-radius:10px; border-top-right-radius:10px; } -table.layout td.content div.toggle.display>div { text-align:center; width:130px; rotate:-90deg; translate:5px -5px; } -body.mobile table.layout div.toggle { font-size:48px; } -body.mobile table.layout td.content div.toggle.project { width:30px; padding-top:35px; } -body.mobile table.layout td.content div.toggle.profile { width:30px; padding-top:35px; } -body.mobile table.layout td.content div.toggle.display { margin-top:-30px; height:30px; } -body.mobile table.layout td.content div.toggle.display>div { translate:5px -15px; } +fieldset.Action>div.project.toggle { font-size:32px; padding-top:50px; height:150px; position:fixed; top:30%; border-top-right-radius:20px; border-bottom-right-radius:20px; } +fieldset.Action>div.project.toggle { background-color:#4a566e6e; } diff --git a/panel/action.js b/panel/action.js index 6fae100f..149e6514 100644 --- a/panel/action.js +++ b/panel/action.js @@ -1,210 +1,116 @@ (function() { var TABS = "tabs", TABVIEW = "tabview", HORIZON = "horizon", VERTICAL = "vertical", GRID = "grid", FREE = "free", FLOW = "flow", PAGE = "page" Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) - var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM); can.core.Next(msg.Table(), function(item, next) { - item.type = chat.PLUGIN, item.inputs = can.base.Obj(item.inputs||item.list), item.feature = can.base.Obj(item.feature||item.meta) - can.onappend.plugin(can, item, function(sub, meta, skip) { can.onimport._run(can, sub, function(event, cmds, cb) { - return can.run(event, can.misc.concat(can, river == web.SHARE? [ctx.ACTION]: [], [river, storm, meta.id||meta.index], cmds), cb) - }), can.onimport._tabs(can, sub, meta), skip || next() }) - }, function() { can.onmotion.delay(can, function() { can.onaction.layout(can, can.misc.SearchOrConf(can, html.LAYOUT), true) }) }) + var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM); can.core.Next(msg.Table(), function(item, next) { item.type = chat.PLUGIN, item.mode = can.Mode() + can.onappend.plugin(can, item, function(sub, meta, skip) { + sub.run = function(event, cmds, cb) { return can.run(event, can.misc.concat(can, river == web.SHARE? [ctx.ACTION]: [], [river, storm, meta.id||meta.index], cmds), cb) } + can._plugins = can.misc.concat(can, can._plugins, [sub]), can.onimport._tabs(can, sub, meta), skip || next() + sub._scrollIntoView = function() { can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN } + sub._target.onclick = function(event) { event.target == sub._target && sub._tabs.click() } + }) + }, function() { can.isCmdMode() || can.onmotion.delay(can, function() { can.onaction.layout(can) }) }) }, _share: function(can, share) { share && can.runAction({}, web.SHARE, [share], function(msg) { - can.Mode(web.SHARE), msg.Length() > 1? can.onlayout._init(can): can.onengine.signal(can, chat.ONACTION_CMD) - can.user.title(msg.SearchOrOption(chat.TITLE)), can.setHeader(chat.TOPIC, msg.SearchOrOption(chat.TOPIC)) + can.user.title(msg.SearchOrOption(chat.TITLE)), can.setHeader(chat.THEME, msg.SearchOrOption(chat.THEME)), msg.Length() == 1 && can.onengine.signal(can, chat.ONACTION_CMD) can.Conf(chat.RIVER, web.SHARE, chat.STORM, share), can.onimport._init(can, msg) }) }, - _cmd: function(can, item, next) { can.base.Copy(item, {type: chat.PLUGIN, mode: chat.CMD, opts: can.misc.Search(can)}), can.onengine.signal(can, chat.ONACTION_CMD) - can.onappend.plugin(can, item, function(sub, meta, skip) { can.onimport._run(can, sub, function(event, cmds, cb) { - return can.runActionCommand(event, sub._index, cmds, cb||function(msg) { - sub.onimport._process(sub, msg) || sub.Update() - }) - }), can.user.title(meta.name), skip || next() }), can.onlayout._init(can) - }, - _run: function(can, sub, cbs) { can._plugins = can.misc.concat(can, can._plugins, [sub]) - sub.run = function(event, cmds, cb) { (!cmds || cmds[0] != ctx.ACTION) && sub.request(event, kit.Dict(ice.SESS_HEIGHT, sub.ConfHeight(), ice.SESS_WIDTH, sub.ConfWidth())) - return cbs(event, cmds, cb) - }, sub.Mode(can.Mode()), sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()), can.page.style(can, sub._output, html.MAX_WIDTH, can.ConfWidth()) - }, _tabs: function(can, sub, meta) { var tabs = [{view: [html.TABS, html.DIV, meta.name], onclick: function(event) { can.onmotion.select(can, can._header_tabs, html.DIV_TABS, sub._header_tabs) can.onmotion.select(can, can._action, html.DIV_TABS, sub._tabs), can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, sub._target) - if (sub._delay_refresh) { sub._delay_refresh = false, sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), can.Conf(html.LAYOUT) == "") } - }, onmouseenter: sub._legend.onmouseenter, ondblclick: sub._legend.onclick}] - sub._header_tabs = can.page.Append(can, can._header_tabs, tabs)._target, sub._tabs = can.page.Append(can, can._action, tabs)._target + if (sub._delay_refresh) { sub._delay_refresh = false, sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), can.onexport.layout(can) == "") } + if (can.onexport.layout(can)) { return } sub._scrollIntoView() + }, oncontextmenu: sub._legend.onclick}]; sub._header_tabs = can.page.Append(can, can._header_tabs, tabs)._target, sub._tabs = can.page.Append(can, can._action, tabs)._target }, - _menu: function(can, msg) { if (can.user.isMobile || can.user.mod.isPod) { return } + _menu: function(can, msg) { if (can.user.isMobile) { return } can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.onaction._menus), function(event, button, list) { can.core.CallFunc([can.onaction, list[0]], [can, button]) }) - can.page.Select(can, can._root.Header._output, html.ACTION, function(target) { can.onmotion.hidden(can, can._header_tabs = can.page.Append(can, target, [html.TABS])._target) }) + can.page.Select(can, can._root.Header._output, "div.Action", function(target) { can.onmotion.hidden(can, can._header_tabs = can.page.Append(can, target, [html.TABS])._target) }) }, }) -Volcanos(chat.ONKEYMAP, {_init: function(can, target) { can.onkeymap._build(can) - can.onengine.listen(can, chat.ONKEYDOWN, function(msg, model) { - if (event.ctrlKey && event.key >= "1" && event.key <= "9") { - var sub = can._plugins[parseInt(event.key)-1]; if (sub) { - can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN - sub._header_tabs.click() - can.onmotion.delay(can, function() { sub.Focus() }) - } - } - can._keylist = can.onkeymap._parse(msg._event, can, model, can._keylist||[], can._output) - }) - }, - _mode: { normal: { - j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) }, - k: function(event, can, target) { target.scrollBy(0, event.ctrlKey? -300: -30) }, - - b: function(event, can) { can.search(event, ["Header.onaction.black"]) }, - w: function(event, can) { can.search(event, ["Header.onaction.white"]) }, - p: function(event, can) { can.search(event, ["Header.onaction.print"]) }, - c: function(event, can) { can.user.toimage(can, can.user.title(), can._target.parentNode, true) }, - - t: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == TABVIEW? ice.AUTO: TABVIEW, true) }, - h: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == HORIZON? ice.AUTO: HORIZON, true) }, - v: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == VERTICAL? ice.AUTO: VERTICAL, true) }, - - ":": function(event, can) { can.onengine.signal(can, chat.ONCOMMAND_FOCUS), can.onkeymap.prevent(event) }, - " ": function(event, can) { can.onengine.signal(can, chat.ONSEARCH_FOCUS), can.onkeymap.prevent(event) }, - Enter: function(event, can) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event)) }, - Escape: function(event, can, target) { can.page.Select(can, can._root._target, can.page.Keys(html.FIELDSET_FLOAT, html.DIV_FLOAT), function(target) { can.page.Remove(can, target) }) }, - }, }, _engine: {}, -}) Volcanos(chat.ONACTION, {_init: function(can, target) { - can.Conf(html.MARGIN_Y, 4*html.PLUGIN_MARGIN+2*html.ACTION_HEIGHT+html.ACTION_MARGIN), can.Conf(html.MARGIN_X, (can.user.isMobile? 2: 4)*html.PLUGIN_MARGIN) - if (can.user.isMobile || can.user.mod.isPod) { var gt = "❯", lt = "❮"; function toggle(view) { return can.onmotion.toggle(can, can._root.River._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.misc.Event(event, can, function(msg) { can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }) } + can.Conf(html.MARGIN_Y, 4*html.PLUGIN_MARGIN+html.ACTION_MARGIN), can.Conf(html.MARGIN_X, (can.user.isMobile? 2: 4)*html.PLUGIN_MARGIN) + can.onengine.listen(can, "ontouchstart", function(msg) { can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }, target) can.onengine.listen(can, chat.ONSEARCH, function(msg, arg) { arg[0] == ctx.COMMAND && can.run(msg, ["can.command"]) }) }, - _menus: [ - [html.LAYOUT, ice.AUTO, TABS, TABVIEW, HORIZON, VERTICAL, GRID, FREE, FLOW, PAGE], - [ice.HELP, "tutor", "manual", "service", "devops", "refer"], - ], - _trans: kit.Dict( - html.LAYOUT, "布局", - ice.AUTO, "默认布局", - TABS, "标签布局", - TABVIEW, "标签分屏", - HORIZON, "左右分屏", - VERTICAL, "上下分屏", - GRID, "网格布局", - FREE, "自由布局", - FLOW, "流动布局", - PAGE, "网页布局", - - ice.HELP, "帮助", - "tutor", "入门简介", - "manual", "使用手册", - "service", "服务手册", - "devops", "编程手册", - "refer", "参考手册", - ), - 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.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) { - can.onimport._cmd(can, item, next) - }) }) - }, - onstorm_select: function(can, msg, river, storm) { - if (can.onmotion.cache(can, function(cache, old) { - var key = can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm)) - return cache[old] = can._plugins, can._plugins = cache[key]||[], key - }, can._output, can._action, can._header_tabs)) { - var conf = can.core.Value(can._root, can.core.Keys(chat.RIVER, river, chat.STORM, storm))||{} - return can.onaction.layout(can, can.misc.SearchOrConf(can, html.LAYOUT)||msg.Option(html.LAYOUT)||conf.layout, true) - } - can.run({}, [river, storm], function(msg) { - if (msg.Length() == 0) { if (can.user.isLocalFile) { return } - return can.onengine.signal(can, chat.ONACTION_NOTOOL, can.request({}, {river: river, storm: storm})) - } - can.onaction.layout(can, can.misc.SearchOrConf(can, html.LAYOUT)||msg.Option(html.LAYOUT), true) - // return can.onkeymap._init(can), can.onimport._menu(can, msg), can.onimport._init(can, msg) - return can.onkeymap._init(can), can.onimport._init(can, msg) + onsize: function(can, msg, height, width) { can.Conf({height: height-can.Conf(html.MARGIN_Y), width: width-can.Conf(html.MARGIN_X)}) }, + onmain: function(can, msg) { can.onimport._share(can, can.misc.Search(can, web.SHARE)) }, + onlogin: function(can, msg) { can.ondaemon._init(can), can.onimport._menu(can, msg), can.onkeymap._init(can) + can._root.River && can.onmotion.delay(can, function() { var gt = "❯", lt = "❮", river = can._root.River._target + var target = can.page.Append(can, can._target, [{view: [[html.TOGGLE, chat.PROJECT], html.DIV, can.page.isDisplay(river)? lt: gt], onclick: function(event) { + can.page.Modify(can, target, can.onmotion.toggle(can, river)? lt: gt), can.onaction.layout(can) + }}])._target + }); if (!can.Conf(chat.TOOL) && !can.user.mod.isCmd) { return } can._names = location.pathname + can.Conf(chat.TOOL)? can.onappend.layout(can, can._output, FLOW, can.core.List(can.Conf(chat.TOOL), function(item, index, list) { item.type = chat.PLUGIN + if (list.length == 1) { can.onengine.signal(can, chat.ONACTION_CMD), 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) { + if (msg.Length() == 1) { can.onengine.signal(can, chat.ONACTION_CMD) } can.onimport._init(can, msg) }) }, - onaction_cmd: function(can, msg) { can.Conf(html.MARGIN_Y, 2*html.ACTION_HEIGHT), can.Conf(html.MARGIN_X, 0) - can.page.style(can, can._target, html.HEIGHT, can.ConfHeight(can.page.height()), html.WIDTH, can.ConfWidth(can.page.width())) - can.ConfHeight(can.page.height()-can.Conf(html.MARGIN_Y)) - can.page.ClassList.add(can, can._target, can.Mode(chat.CMD)), can.page.ClassList.add(can, can._root._target, chat.SIMPLE) + onstorm_select: function(can, msg, river, storm) { + if (can.onmotion.cache(can, function(cache, old) { var key = can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm)) + return cache[old] = can._plugins, can._plugins = cache[key]||[], key + }, can._output, can._action, can._header_tabs)) { return can.onaction.layout(can) } + can.run({}, [river, storm], function(msg) { + if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOTOOL, can.request({}, {river: river, storm: storm})) } + return can.onimport._init(can, msg) + }) }, + onaction_cmd: function(can, msg) { can.page.ClassList.add(can, can._target, can.Mode(chat.CMD)), can.Conf(html.MARGIN_Y, 0), can.Conf(html.MARGIN_X, 0), can.onlayout._init(can) }, onsearch: function(can, msg, arg) { var fields = msg.Option(ice.MSG_FIELDS).split(ice.FS) if (arg[0] == mdb.FOREACH || arg[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, arg, fields) } if (arg[0] == mdb.FOREACH || arg[0] == ctx.COMMAND) { can.onexport.command(can, msg, arg, fields) } }, - onkeydown: function(can, msg) { var event = msg._event; if (event.ctrlKey && event.key >= "1" && event.key <= "9") { var index = parseInt(event.key)-1 - can.onmotion.select(can, can._header_tabs, html.DIV_TABS, index), can.onmotion.select(can, can._action, html.DIV_TABS, index) - can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, index) - } }, - onresize: function(can, height, width) { - can.onlayout._init(can), can.onaction.layout(can, can.Conf(html.LAYOUT)), window.setsize && window.setsize(can.page.width(), can.page.height()) - }, - onsize: function(can, msg, height, width) { - can.Conf({height: height-can.Conf(html.MARGIN_Y), width: width-can.Conf(html.MARGIN_X)}) + onkeydown: function(can, msg, model) { if (can.onkeymap.selectCtrlN(msg._event, can, can._action, html.DIV_TABS)) { return } + can._keylist = can.onkeymap._parse(msg._event, can, model, can._keylist||[], can._output) }, + onresize: function(can, height, width) { can.onaction.layout(can), window.setsize && window.setsize(can.page.width(), can.page.height()) }, onprint: function(can, msg) { can.page.styleHeight(can, can._target, "") }, - - layout: function(can, button, silent) { button = button||ice.AUTO; can.page.ClassList.del(can, can._target, can.Conf(html.LAYOUT)) - if (button == ice.AUTO) { button = "" } else { can.page.ClassList.add(can, can._target, can.Conf(html.LAYOUT, button)) } - can.user.isMobile || can.Mode() || (can._root.River && can.onmotion.toggle(can, can._root.River._target, true), can.onmotion.toggle(can, can._root.Footer._target, true)) - can.user.isMobile && can.Mode() && can.page.style(can, can._target, html.WIDTH, "", html.HEIGHT, "") - can.onlayout._init(can), can._header_tabs && can.onmotion.hidden(can, can._header_tabs), can.Conf(chat.LAYOUT, button) - var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can, silent) || can.onlayout._plugin(can, button) + layout: function(can, button) { can._layout && can.page.ClassList.del(can, can._target, can._layout), can._header_tabs && can.onmotion.hidden(can, can._header_tabs) + button = (can._layout = button)||can.misc.SearchOrConf(can, html.LAYOUT)||ice.AUTO, button == ice.AUTO? (button = ""): can.page.ClassList.add(can, can._target, button) + can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {"layout": button})), can.onlayout._init(can) + can.core.List(can._plugins, function(sub) { sub._delay_refresh = false, can.page.ClassList.set(can, sub._target, html.OUTPUT, ["tabview", "horizon", "vertical"].indexOf(button) > -1) }) + var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can) || can.onlayout._plugin(can, button) }, - help: function(can, button) { can.user.open("/help/"+button+".shy") }, + _menus: [[html.LAYOUT, ice.AUTO, TABS, TABVIEW, HORIZON, VERTICAL, GRID, FREE, FLOW, PAGE]], + _trans: kit.Dict( + html.LAYOUT, "布局", ice.AUTO, "默认布局", TABS, "标签布局", + TABVIEW, "标签分屏", HORIZON, "左右分屏", VERTICAL, "上下分屏", + GRID, "网格布局", FREE, "自由布局", FLOW, "流动布局", PAGE, "网页布局", + ), }) Volcanos(chat.ONLAYOUT, { - tabs: function(can) { - can.getActionSize(function(height, width) { can.ConfHeight(height-can.Conf(html.MARGIN_Y)+html.ACTION_MARGIN), can.ConfWidth(width-can.Conf(html.MARGIN_X)) }) - can.onmotion.select(can, can._action, html.DIV_TABS) || can.onmotion.select(can, can._action, html.DIV_TABS, 0, function(target) { target.click() }) - }, - tabview: function(can) { can.onmotion.hidden(can, can._root.River._target), can.onmotion.hidden(can, can._root.Footer._target), can.onlayout._init(can) - can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width) }) - can.onmotion.toggle(can, can._header_tabs, true), can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }) - can.onmotion.select(can, can._action, html.DIV_TABS) || can.onmotion.select(can, can._action, html.DIV_TABS, 0, function(target) { target.click() }) + tabs: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-can.Conf(html.MARGIN_Y)+html.ACTION_MARGIN), can.ConfWidth(width-can.Conf(html.MARGIN_X)) }) + can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }) + can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }) return true }, - horizon: function(can) { can.onmotion.hidden(can, can._root.River._target), can.onmotion.hidden(can, can._root.Footer._target), can.onlayout._init(can) - can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width/2) }) + tabview: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width) }) + can.core.List(can._plugins, function(sub) { sub._delay_refresh = true }), can.onmotion.toggle(can, can._header_tabs, true), + can.onmotion.select(can, can._action, html.DIV_TABS, can.onmotion.select(can, can._action, html.DIV_TABS)||0, function(target) { target.click() }) + return true }, - vertical: function(can) { can.onmotion.hidden(can, can._root.River._target), can.onmotion.hidden(can, can._root.Footer._target), can.onlayout._init(can) - can.getActionSize(function(height, width) { can.ConfHeight(height/2), can.ConfWidth(width) }) - }, - free: function(can) { - can.getActionSize(function(height, width) { can.ConfHeight(height-can.Conf(html.MARGIN_Y)+html.ACTION_MARGIN), can.ConfWidth(width-can.Conf(html.MARGIN_X)) }) - can.core.List(can._plugins, function(sub, index) { can.onmotion.move(can, sub._target, {left: 40*index, top: 40*index}) }) - }, - grid: function(can, silent) { - return can.user.input(event, can, [{name: "m", value: 2}, {name: "n", value: 2}], function(data) { can.onlayout._grid(can, parseInt(data.m), parseInt(data.n)) }, silent), true - }, - _grid: function(can, m, n) { can.getActionSize(function(height, width) { var h = (height-(4*n+1)*html.PLUGIN_MARGIN)/n, w = (width-(4*m+1)*html.PLUGIN_MARGIN)/m - can.ConfHeight(h-html.ACTION_HEIGHT-3*html.PLUGIN_MARGIN), can.ConfWidth(w), can.onlayout._plugin(can, GRID) + horizon: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height), can.ConfWidth(width/2) }) }, + vertical: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height/2), can.ConfWidth(width) }) }, + grid: function(can) { can.getActionSize(function(height, width) { var m = 2, n = 2; + var h = height/n-4*html.PLUGIN_MARGIN-html.ACTION_HEIGHT, w = width/m-4*html.PLUGIN_MARGIN; can.ConfHeight(h), can.ConfWidth(w), can.onlayout._plugin(can, GRID) }) }, - _plugin: function(can, button) { can.core.List(can._plugins, function(sub) { - sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), button == "" || button == FREE || button == FLOW), button == "" && can.page.style(can, sub._output, html.MAX_HEIGHT, "") - }) }, + free: function(can) { can.getActionSize(function(height, width) { can.ConfHeight(height-2*can.Conf(html.MARGIN_Y)), can.ConfWidth(width-can.Conf(html.MARGIN_Y)) }) + can.onmotion.toggle(can, can._header_tabs, true), can.core.List(can._plugins, function(sub, index) { can.onmotion.move(can, sub._target, {left: 120*index, top: 80*index}) }) + }, + page: function(can) { can.page.styleHeight(can, can._output, ""), can.page.style(can, document.body, kit.Dict(html.OVERFLOW, "")) }, + _plugin: function(can, button) { can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), ["", FLOW, PAGE].indexOf(button) > -1) && can.page.style(can, sub._output, html.MAX_HEIGHT, "") }) }, }) Volcanos(chat.ONEXPORT, { size: function(can, msg) { - msg.Option(html.TOP, can._output.offsetTop) - msg.Option(html.LEFT, can._output.offsetLeft) - msg.Option(html.WIDTH, can._output.offsetWidth) - msg.Option(html.HEIGHT, can._output.offsetHeight) - msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X)) - msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)) + msg.Option(html.LEFT, can._output.offsetLeft), msg.Option(html.TOP, can._output.offsetTop) + msg.Option(html.WIDTH, can._output.offsetWidth), msg.Option(html.HEIGHT, can._output.offsetHeight) + msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X)), msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)) msg.Option(html.SCROLL, can.user.isMobile? can._target.parentNode.parentNode.scrollTop: can._output.scrollTop) }, - layout: function(can, msg) { return can.Conf(html.LAYOUT) }, - args: function(can, msg, cb, target) { can.core.Next(can._plugins, function(sub, next, index, array) { + layout: function(can) { return can._layout||can.misc.SearchOrConf(can, html.LAYOUT) }, + args: function(can, msg, cb) { can.core.Next(can._plugins, function(sub, next, index, array) { cb(can.page.SelectArgs(can, sub._option, "", function(target) { return target.value }), sub, next, index, array) }) }, plugin: function(can, msg, arg, fields) { can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (meta.index.indexOf(arg[1]) == -1) { return } - var data = {ctx: ice.CAN, cmd: can._name, type: mdb.PLUGIN, name: sub._legend.innerHTML, text: shy("跳转", function(event) { - can._output.scrollTop = sub._target.offsetTop-html.PLUGIN_MARGIN - // sub.Focus() - })} + var data = {ctx: ice.CAN, cmd: can._name, type: mdb.PLUGIN, name: sub._legend.innerHTML, text: shy("goto", function(event) { sub._scrollIntoView() })} if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd } else { return } msg.Push(data, fields) }) }, @@ -217,22 +123,23 @@ Volcanos(chat.ONEXPORT, { Volcanos(chat.ONENGINE, {_engine: function(event, sup, msg, can, cmds, cb) { var storm = can.core.Value(can._root, can.core.Keys(chat.RIVER, cmds[0], chat.STORM, cmds[1])); if (!storm || cmds.length != 2) { return false } if (storm.index) { can.runAction(event, ctx.COMMAND, [].concat(storm.index), cb) } else { can.core.List(storm.list, function(value) { - msg.Push(mdb.NAME, value.name||"") - msg.Push(mdb.HELP, value.help||"") - msg.Push(ctx.INPUTS, JSON.stringify(value.inputs)) - msg.Push(ctx.FEATURE, JSON.stringify(value.feature)) - msg.Push(ctx.INDEX, value.index||"") - msg.Push(ctx.ARGS, value.args||"[]") - msg.Push(ctx.STYLE, value.style||"") - msg.Push(ctx.DISPLAY, value.display||"") - msg.Push(ice.MSG_ACTION, value._action||"") + msg.Push(mdb.NAME, value.name||"").Push(mdb.HELP, value.help||"").Push(ctx.INPUTS, JSON.stringify(value.inputs)).Push(ctx.FEATURE, JSON.stringify(value.feature)) + msg.Push(ctx.INDEX, value.index||"").Push(ctx.ARGS, value.args||"[]").Push(ctx.STYLE, value.style||"").Push(ctx.DISPLAY, value.display||"") }), can.base.isFunc(cb) && cb(msg) } return true }}) -Volcanos(chat.ONPLUGIN, { - _plugin: shy("默认插件", [mdb.NAME, ice.LIST, ice.BACK]), - layout: shy("界面布局", { - _init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)||ice.AUTO) }, - }, ["layout:select=auto,tabs,tabview,horizon,vertical,free,grid,flow,page", ice.RUN], function(can, msg, arg) { can.onaction.layout(can, arg[0], true) }), +Volcanos(chat.ONKEYMAP, { + _mode: {normal: { + j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) }, + k: function(event, can, target) { target.scrollBy(0, event.ctrlKey? -300: -30) }, + t: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == TABVIEW? ice.AUTO: TABVIEW, true) }, + h: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == HORIZON? ice.AUTO: HORIZON, true) }, + v: function(event, can) { can.onaction.layout(can, can.Conf(chat.LAYOUT) == VERTICAL? ice.AUTO: VERTICAL, true) }, + }}, _engine: {}, +}) +Volcanos(chat.ONPLUGIN, {_plugin: shy("默认插件", [mdb.NAME, ice.LIST, ice.BACK]), + layout: shy("界面布局", {_init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)||ice.AUTO) }}, + ["layout:select=auto,tabs,tabview,horizon,vertical,flow,free,grid,page", ice.RUN], function(can, msg, arg) { can.onaction.layout(can, arg[0]) }), + "parse": shy("生成网页", { "show": function(can, msg, arg) { var name = arg[1]||ice.CAN; can.isCmdMode() && can.user.title(name) arg && arg[0] && Volcanos(name, {_follow: can.core.Keys(can._follow, name)}, [chat.PLUGIN_STORY+"parse.js"], function(sub) { diff --git a/panel/footer.js b/panel/footer.js index d3c6e96a..87a8716a 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -31,7 +31,8 @@ Volcanos(chat.ONACTION, {_init: function(can) { if (can.user.isExtension || can. onlogin: function(can, msg) { can.run({}, [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) }, ontoast: function(can, msg) { can.core.CallFunc(can.onimport.toast, {can: can, msg: msg}) }, onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) }, - onaction_cmd: function(can) { can.onappend.style(can, can._target, html.HIDE) }, + onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, + onlayout: function(can, layout) { can.onmotion.toggle(can, can._target, !layout || layout == "tabs") }, oncommand_focus: function(can) { can.page.Select(can, can._output, ["div.cmd", html.INPUT], function(target) { can.onmotion.focus(can, target) }) }, }) Volcanos(chat.ONEXPORT, {height: function(can) { return can._target.offsetHeight }, diff --git a/panel/header.js b/panel/header.js index 1f919b52..dc7169f9 100644 --- a/panel/header.js +++ b/panel/header.js @@ -5,8 +5,11 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onimport._background(can, msg, target) can.onimport._search(can, msg, target) // can.onimport._menus(can, msg, target) - var themeMedia = window.matchMedia("(prefers-color-scheme: dark)") - can.__topic = themeMedia.matches? html.DARK: html.LIGHT, themeMedia.addListener(function(event) { can.__topic = event.matches? html.DARK: html.LIGHT }) + var themeMedia = window.matchMedia("(prefers-color-scheme: light)") + can.__theme = themeMedia.matches? html.LIGHT: html.DARK, themeMedia.addListener(function(event) { + can.__theme = event.matches? html.LIGHT: html.DARK + can.onengine.signal(can, "onthemechange", can.request(event, {theme: can.__theme})) + }) }, _title: function(can, msg, target) { if (can.user.isMobile) { return } can.core.List(can.base.getValid(can.Conf(chat.TITLE)||msg.result, ["shylinux.com/x/contexts"]), function(item) { @@ -42,14 +45,14 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { _time: function(can, target) { can.core.Timer({interval: 100}, function() { can.onimport.time(can, target) }) can.onappend.figure(can, {action: "date"}, target) }, - time: function(can, target) { can.onimport.topic(can), target.innerHTML = can.user.time(can, null, "%w %H:%M:%S") }, + time: function(can, target) { can.onimport.theme(can), target.innerHTML = can.user.time(can, null, "%w %H:%M:%S") }, avatar: function(event, can, avatar) { if (can.user.isExtension || can.user.isLocalFile) { return } can.runAction(event, aaa.AVATAR, [avatar], function(msg) { can.user.info.avatar = avatar, can.onimport._avatar(can, msg), can.user.toastSuccess(can) }) }, background: function(event, can, background) { if (can.user.isExtension || can.user.isLocalFile) { return } can.runAction(event, aaa.BACKGROUND, [background], function(msg) { can.user.info.background = background, can.onimport._background(can, msg), can.user.toastSuccess(can) }) }, - topic: function(can, topic) { topic && (can._topic = can.base.Obj(topic).join(ice.SP)), can.user.topic(can, can.onexport.topic(can)) }, + theme: function(can, theme) { theme && (can._theme = can.base.Obj(theme).join(ice.SP)), can.user.theme(can, can.onexport.theme(can)) }, menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds]) return can.page.Append(can, can._output, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) { if (can.base.isString(item)) { return {view: [html.MENU, html.DIV, can.user.trans(can, item, trans)], onclick: function(event) { can.base.isFunc(cb) && cb(event, item, [item]) }} } @@ -67,7 +70,8 @@ Volcanos(chat.ONACTION, { "setting", "设置", chat.BLACK, "黑色主题", chat.WHITE, "白色主题", chat.PRINT, "打印主题", code.WEBPACK, "打包页面", web.TOIMAGE, "生成图片", "shareuser", "共享用户", "setnick", "设置昵称", aaa.PASSWORD, "修改密码", aaa.LANGUAGE, "语言地区", aaa.CHINESE, "中文", web.CLEAR, "清除背景", aaa.LOGOUT, "退出登录", ), - onmain: function(can) { can.onimport.topic(can) + onsize: function(can) { can.onimport.theme(can), can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, + onmain: function(can) { can.onimport.theme(can), can.onkeymap._init(can) can.run({}, [], function(msg) { if (!can.Conf(aaa.USERNICK, msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME))) { return msg.Option(chat.SSO)? can.user.jumps(msg.Option(chat.SSO)): can.user.login(can, function() { can.onengine.signal(can, chat.ONMAIN, msg) }, msg.Option(aaa.LOGIN)) } can.user.info.usernick = can.Conf(aaa.USERNICK), can.user.info.language = can.misc.Search(can, aaa.LANGUAGE)||msg.Option(aaa.LANGUAGE) @@ -76,24 +80,23 @@ Volcanos(chat.ONACTION, { can.onmotion.clear(can), can.onimport._init(can, msg, can._output), can.onengine.signal(can, chat.ONLOGIN, msg) }) }, - onsize: function(can) { can.onimport.topic(can), can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, + onstorm_select: function(can, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) }, - onaction_cmd: function(can) { can.onappend.style(can, can._target, html.HIDE) }, + onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, onsearch_focus: function(can) { can._search && can._search.focus() }, onshare: function(can, msg, args) { can.user.share(can, msg, [ctx.ACTION, chat.SHARE].concat(args||[])) }, - onwebpack: function(can, msg) { - can.user.input(msg._event, can, [{name: mdb.NAME, value: can.user.title()}], function(data) { - can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ice.MSG_SESSID, ""], function(key) { delete(msg[key]) }) }) - can.runAction(can.request({}, {args: "name,river,storm,topic,layout", _toast: "打包中...", - name: data.name, content: JSON.stringify(Volcanos.meta.pack), river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), topic: can._topic, layout: can.getAction(html.LAYOUT), - }), code.WEBPACK, [], function(msg) { can.user.download(can, web.SHARE_LOCAL+msg.Result(), name, nfs.HTML), can.user.toastSuccess(can, "打包成功", code.WEBPACK) }) - }) - }, + onkeydown: function(can, msg, model) { can._keylist = can.onkeymap._parse(msg._event, can, model, can._keylist||[], can._output) }, + onwebpack: function(can, msg) { can.user.input(msg._event, can, [{name: mdb.NAME, value: can.user.title()}], function(data) { + can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ice.MSG_SESSID, ""], function(key) { delete(msg[key]) }) }) + can.runAction(can.request({}, {args: "name,river,storm,theme,layout", _toast: "打包中...", + name: data.name, content: JSON.stringify(Volcanos.meta.pack), river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), theme: can._theme, layout: can.getAction(html.LAYOUT), + }), code.WEBPACK, [], function(msg) { can.user.download(can, web.SHARE_LOCAL+msg.Result(), name, nfs.HTML), can.user.toastSuccess(can, "打包成功", code.WEBPACK) }) + }) }, - title: function(event, can) { var args = {}; can.core.List([chat.TITLE, chat.TOPIC], function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) }); can.user.jumps(can.misc.MergeURL(can, args, true)) }, - black: function(event, can, button) { can.onimport.topic(can, button) }, - white: function(event, can, button) { can.onimport.topic(can, button) }, - print: function(event, can, button) { can.onimport.topic(can, [chat.WHITE, button]), can.onengine.signal(can, chat.ONPRINT) }, + title: function(event, can) { var args = {}; can.core.List([chat.TITLE, chat.THEME], function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) }); can.user.jumps(can.misc.MergeURL(can, args, true)) }, + black: function(event, can, button) { can.onimport.theme(can, button) }, + white: function(event, can, button) { can.onimport.theme(can, button) }, + print: function(event, can, button) { can.onimport.theme(can, [chat.WHITE, button]), can.onengine.signal(can, chat.ONPRINT) }, webpack: function(event, can) { can.onengine.signal(can, "onwebpack", can.request(event)) }, toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) }, @@ -116,22 +119,35 @@ Volcanos(chat.ONACTION, { logout: function(event, can) { can.user.logout(can) }, }) Volcanos(chat.ONEXPORT, {height: function(can) { return can._target.offsetHeight }, - topic: function(can) { - return can._topic || can.misc.Search(can, chat.TOPIC) || can.misc.localStorage(can, "can.topic") || can.__topic || (can.base.isNight()? "dark": "light") + theme: function(can) { + return can._theme || can.misc.Search(can, chat.THEME) || can.misc.localStorage(can, "can.theme") || can.__theme || (can.base.isNight()? "dark": "light") }, background: function(can) { return can.user.info.background == "void"? "": can.user.info.background }, avatar: function(can) { return can.user.info.avatar == "void"? "": can.user.info.avatar }, }) +Volcanos(chat.ONKEYMAP, {_init: function(can, target) { can.onkeymap._build(can) }, + _mode: { normal: { + b: function(event, can) { can.search(event, ["Header.onaction.black"]) }, + w: function(event, can) { can.search(event, ["Header.onaction.white"]) }, + p: function(event, can) { can.search(event, ["Header.onaction.print"]) }, + c: function(event, can) { can.user.toimage(can, can.user.title(), can._target.parentNode, true) }, + + ":": function(event, can) { can.onengine.signal(can, chat.ONCOMMAND_FOCUS), can.onkeymap.prevent(event) }, + " ": function(event, can) { can.onengine.signal(can, chat.ONSEARCH_FOCUS), can.onkeymap.prevent(event) }, + Enter: function(event, can) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event)) }, + Escape: function(event, can) { can.onmotion.clearFloat(can) }, + }, }, _engine: {}, +}) Volcanos(chat.ONPLUGIN, { title: shy("应用标题", [chat.TITLE], function(can, msg, arg) { msg.Echo(can.user.title(arg[0])) }), - topic: shy("界面主题", { - _init: function(can) { can.Option(chat.TOPIC, can.getHeader(chat.TOPIC)) }, - }, ["topic:select=auto,dark,light,white,black,print", ice.RUN], function(can, msg, arg) { - if (arg[0] == "auto") { arg[0] = "" } - if (arg.length > 0) { can.misc.localStorage(can, "can.topic", arg[0]) } - msg.Echo(can.onimport.topic(can, arg[0])) + theme: shy("界面主题", { + _init: function(can) { can.Option(chat.THEME, can.getHeader(chat.THEME)) }, + }, ["theme:select=auto,dark,light,white,black,print", ice.RUN], function(can, msg, arg) { + if (arg[0] == "auto") { arg[0] = "", can._theme = "" } + if (arg.length > 0) { can.misc.localStorage(can, "can.theme", arg[0]) } + msg.Echo(can.onimport.theme(can, arg[0])) }), location: shy("请求地址", { copy: function(can) { can.user.copy(msg._event, can, location.href) }, diff --git a/panel/river.js b/panel/river.js index 03ac8a38..f9246bee 100644 --- a/panel/river.js +++ b/panel/river.js @@ -36,6 +36,9 @@ Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.REFRESH], _init: function(can) { onsearch: function(can, msg, arg) { if (arg[0] == mdb.FOREACH || arg[0] == chat.STORM) { can.onexport.storm(can, msg, arg) } }, onresize: function(can, msg) { can.user.isMobile && can.onmotion.hidden(can, can._target) }, onprint: function(can, msg) { can.page.styleHeight(can, can._target, "") }, + onlayout: function(can, layout) { + can.onmotion.toggle(can, can._target, !layout || layout == "tabs") + }, create: function(event, can) { can.user.input(event, can, [{name: mdb.TYPE, values: [aaa.TECH, aaa.VOID], _trans: "类型"}, {name: mdb.NAME, value: "hi", _trans: "群名"}, {name: mdb.TEXT, value: "hello", _trans: "简介"}], function(args) { can.runAction(event, mdb.CREATE, args, function(msg) { can.misc.Search(can, {river: msg.Result()}) }) @@ -66,7 +69,7 @@ Volcanos(chat.ONDETAIL, {list: ["添加应用", "重命名群组", "删除群组 "删除群组": function(event, can, button, river) { can.runAction(event, mdb.REMOVE, [mdb.HASH, river], function(msg) { can.misc.Search(can, {river: "", storm: ""}) }) }, "添加应用": function(event, can, button, river) { can.ondetail.create(event, can, button, river) }, - "共享应用": function(event, can, button, river, storm) { can.onmotion.share(event, can, [{name: chat.TITLE, value: can.user.title()}, {name: chat.TOPIC, values: [cli.WHITE, cli.BLACK]}], [mdb.TYPE, chat.STORM, chat.RIVER, river, chat.STORM, storm]) }, + "共享应用": function(event, can, button, river, storm) { can.onmotion.share(event, can, [{name: chat.TITLE, value: can.user.title()}, {name: chat.THEME, values: [cli.WHITE, cli.BLACK]}], [mdb.TYPE, chat.STORM, chat.RIVER, river, chat.STORM, storm]) }, "添加工具": function(event, can, button, river, storm) { can.user.select(event, can, ctx.COMMAND, ctx.INDEX, function(item, next) { can.run({}, [river, storm, chat.STORM, ctx.ACTION, mdb.INSERT].concat([web.SPACE, can.misc.Search(can, ice.POD)||"", ctx.INDEX, item[0]]), function(msg) { next() }) }, function() { can.misc.Search(can, {river: river, storm: storm}) }) }, diff --git a/plugin/input.js b/plugin/input.js index 32b665bb..dfb49a58 100644 --- a/plugin/input.js +++ b/plugin/input.js @@ -3,7 +3,7 @@ Volcanos(chat.ONACTION, { run: function(event, can) { can.run(event) }, refresh: function(event, can) { can.run(event) }, list: function(event, can) { can.sup.isSimpleMode() || can.run(event) }, back: function(event, can) { can.sup.onimport._back(can.sup) }, - onclick: function(event, can) { can.Conf(mdb.TYPE) == html.BUTTON && can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())) }, + onclick: function(event, can) { can.Conf(mdb.TYPE) == html.BUTTON && can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())), can.onkeymap.prevent(event) }, onfocus: function(event, can, target) { can.Conf(mdb.TYPE) == html.TEXT && can.onmotion.selectRange(target) }, onchange: function(event, can) { can.Conf(mdb.TYPE) == html.SELECT && can.run(event) }, onkeydown: function(event, can) { can.onkeymap.input(event, can, event.target) diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index 96c32b4a..903b56f9 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -1,35 +1,34 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.onmotion.clear(can), can.onlayout._init(can) can.page.requireModules(can, ["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() { - var item = {hash: can.Option(mdb.HASH)}; msg.Table(function(value) { can.core.Value(item, value.key, value.value) }) - item.text && can.onmotion.delay(can, function() { can.onimport._input(can, item.text+ice.NL) }) + var item = msg.TableDetail(); item.hash = can.Option(mdb.HASH), item.text && can.onmotion.delay(can, function() { can.onimport._input(can, item.text+ice.NL) }) can.onimport._connect(can, item), can.onappend.tools(can, msg, function(sub) { sub.onexport.record = function(_, value, key, line) { can.onimport._input(can, value+ice.NL) } }), msg.Option(ice.MSG_TOOLKIT, ""), can.base.isFunc(cb) && cb(msg), can.onappend._status(can) + can.sup._save && can._current.write(can.sup._save.replaceAll(ice.NL, "\r\n")), can.sup._save = "" + can.sup._listen || can.onengine.listen(can, chat.ONTHEMECHANGE, function() { can = can.core.Value(can.sup, chat._OUTPUTS_CURRENT) + can._current.selectAll(), can.sup._save = can.base.trimSuffix(can._current.getSelection(), ice.NL), can.Update() + }), can.sup._listen = true }) }, - _connect: function(can, item) { var term = new Terminal({tabStopWidth: 4, cursorBlink: true}) - var fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon), term._fit = fitAddon - can.onmotion.delay(can, function() { fitAddon.fit() }) - term.loadAddon(new WebLinksAddon.WebLinksAddon()) - term.onTitleChange(function(title) { can.onexport.title(can, title) }) + _connect: function(can, item) { var term = new Terminal({tabStopWidth: 4, cursorBlink: true, theme: can.onimport._theme(can, item)}); term.loadAddon(new WebLinksAddon.WebLinksAddon()) + var fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon), term._fit = fitAddon, can.onmotion.delay(can, function() { fitAddon.fit() }) + term.onTitleChange(function(title) { can.onexport.title(can, title) }), can.onexport.title(can, item.name) term.onResize(function(size) { can.onimport._resize(can, size) }) term.onData(function(data) { can.onimport._input(can, data) }) term.onCursorMove(function() { can.onexport.term(can) }) - can.onexport.title(can, item.name) - can._current = term, term._item = item - term.open(can._output), term.focus() + can._current = term, term._item = item, term.open(can._output), term.focus() }, - _resize: function(can, size) { - can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "") + _resize: function(can, size) { can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "") can.runAction(can.request({}, size, can._current._item), "resize", [], function() { can.onexport.term(can) }) }, - _input: function(can, data) { if (!can._current) { return } - can.runAction(can.request({}, can._current._item), "input", [btoa(data)], function() {}) + _input: function(can, data) { can._current && can.runAction(can.request({}, can._current._item), "input", [btoa(data)], function() {}) }, + _theme: function(can, item) { + return can.base.Obj(item.theme)||(can.getHeaderTheme() == html.LIGHT? {background: cli.WHITE, foreground: cli.BLACK, cursor: cli.BLUE}: {}) }, grow: function(can, msg, _arg) { can._current.write(_arg) }, }) Volcanos(chat.ONLAYOUT, {_init: function(can) { - can.page.style(can, can._output, html.HEIGHT, can.ConfHeight()+8, html.WIDTH, can.ConfWidth()+18, html.MAX_WIDTH, "") + can.page.style(can, can._output, html.HEIGHT, can.ConfHeight()+4, html.WIDTH, can.ConfWidth(), html.MAX_WIDTH, "") can._current && can._current._fit.fit(), can.onexport.term(can) }, cmd: function(can) { can._current && can.onexport.title(can, can._current._item.name), can.ConfWidth(can.ConfWidth()-10) }, @@ -42,7 +41,8 @@ Volcanos(chat.ONACTION, { Volcanos(chat.ONEXPORT, {list: [mdb.TYPE, mdb.NAME, "rows", "cols", "cursorY", "cursorX"], term: function(can) { var term = can._current||{}, item = term._item; if (!item) { return } can.core.List(can.onexport.list, function(key) { - can.Status(key, can.base.getValid(item[key], term[key], term.buffer.active[key], "")) + can.Status(key, can.base.getValid(item[key], term[key], term.buffer.active[key], "")+"") }), can.Status(mdb.TYPE, item[mdb.TYPE]||""), can.Status(mdb.NAME, item[mdb.NAME]||"") }, + title: function(can, title) { can.sup.onexport.title(can.sup, title) }, }) diff --git a/plugin/state.js b/plugin/state.js index 099b0edd..7fc6fdfc 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -55,14 +55,15 @@ Volcanos(chat.ONIMPORT, {_process: function(can, msg) { msg.OptionStatus() && ca }, _open: function(can, msg, arg) { return can.user.open(arg) }, size: function(can, height, width, auto, mode) { var sub = can.core.Value(can, chat._OUTPUTS_CURRENT) - height -= html.ACTION_HEIGHT+(sub? can.onexport.statusHeight(can): html.ACTION_HEIGHT) + height -= can.onexport.actionHeight(can)+can.onexport.statusHeight(can) if (auto) { can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "", html.MAX_HEIGHT, height? can.ConfHeight(height): "", html.MAX_WIDTH, can.ConfWidth(width)) } else { can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(height), html.WIDTH, can.ConfWidth(width), html.MAX_HEIGHT, "", html.MAX_WIDTH, "") } - if (!sub) { return } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()) + if (!sub) { return auto } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()) if (mode) { sub.Mode(can.Mode(mode)), sub.onlayout[mode](sub) } else { sub.onlayout._init(sub) } + return auto }, change: function(event, can, name, value, cb) { return can.page.SelectArgs(can, can._option, "", function(input) { if (input.name != name || value == input.value) { return } return input.value = value, can.Update(event, can.Input([], true), cb), input @@ -103,7 +104,7 @@ Volcanos(chat.ONACTION, {list: [ }) }, "远程控制": function(event, can) { can.onaction.keyboard(event, can) }, "共享工具": function(event, can) { var meta = can.Conf() - can.onmotion.share(event, can, [{name: chat.TITLE, value: meta.name}, {name: chat.TOPIC, values: [can.getHeader(chat.TOPIC), "light", "dark", cli.WHITE, cli.BLACK]}], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) + can.onmotion.share(event, can, [{name: chat.TITLE, value: meta.name}, {name: chat.THEME, values: [can.getHeader(chat.THEME), "light", "dark", cli.WHITE, cli.BLACK]}], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) }, "打开链接": function(event, can) { can.user.open(can.onexport.link(can)) }, "生成链接": function(event, can) { can.onmotion.share(event, can, [], [mdb.LINK, can.user.copy(event, can, can.onexport.link(can))]) }, @@ -202,10 +203,17 @@ Volcanos(chat.ONEXPORT, { args.cmd = meta.index||can.core.Keys(meta.ctx, meta.cmd), args.cmd == web.WIKI_WORD && (args.cmd = args.path) return can.misc.MergePodCmd(can, args, true) }, - title: function(can, title) {}, + title: function(can, title) { + can.isCmdMode() && can.user.title(title) + }, output: function(can, msg) {}, action: function(can, button, line) {}, record: function(can, value, key, line) {}, - actionHeight: function(can) { return can._action.style.display == html.NONE || can._action.innerHTML == ""? 0: html.ACTION_HEIGHT }, - statusHeight: function(can) { return can._status.style.display == html.NONE || can._status.innerHTML == "" || can._status.offsetHeight == 0? 0: html.ACTION_HEIGHT }, + actionHeight: function(can) { + return (!can.page.isDisplay(can._option) && !can.page.isDisplay(can._action)) || + (can._option.innerHTML == "" && can._action.innerHTML == "") || + (can._target.offsetHeight > 0 && can._option.offsetHeight == 0 && can._option.offsetHeight == 0)? 0: html.ACTION_HEIGHT + }, + statusHeight: function(can) { + return !can.page.isDisplay(can._status) || can._status.innerHTML == "" || (can._target.offsetHeight > 0 && can._status.offsetHeight == 0)? 0: html.ACTION_HEIGHT }, }) diff --git a/plugin/story/trend.js b/plugin/story/trend.js index c0aaaf7b..6430bcbc 100644 --- a/plugin/story/trend.js +++ b/plugin/story/trend.js @@ -71,7 +71,7 @@ Volcanos(chat.ONACTION, {list: [ "折线图": function(event, can) { var args = can.onimport._layout(can); args.step = parseFloat((args.width-2*args.margin) / (can._msg.Length()-1)) var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK)) var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE)) - var group = can.getHeaderTopic() == cli.BLACK? black: white + var group = can.getHeaderTheme() == cli.BLACK? black: white can.onimport.transform(can, black), can.onimport.transform(can, white) can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) { var max = can.data[0][field], min = can.data[0][field] for (var i = 1; i < can.data.length; i += 1) { var value = can.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } } @@ -84,7 +84,7 @@ Volcanos(chat.ONACTION, {list: [ "柱状图": function(event, can) { var args = can.onimport._layout(can) var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK)) var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE)) - var group = can.getHeaderTopic() == cli.BLACK? black: white + var group = can.getHeaderTheme() == cli.BLACK? black: white can.onimport.transform(can, black), can.onimport.transform(can, white) can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) { var max = can.data[0][field], min = can.data[0][field] for (var i = 1; i < can.data.length; i += 1) { var value = can.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } } diff --git a/proto.js b/proto.js index a5cfcd37..74b739d1 100644 --- a/proto.js +++ b/proto.js @@ -37,7 +37,7 @@ var ice = { MSG_PREFIX: "_prefix", MSG_USERNAME: "user.name", MSG_USERNICK: "user.nick", - MSG_TITLE: "sess.title", MSG_TOPIC: "sess.topic", MSG_RIVER: "sess.river", MSG_STORM: "sess.storm", MSG_WIDTH: "sess.width", MSG_HEIGHT: "sess.height", + MSG_TITLE: "sess.title", MSG_THEME: "sess.theme", MSG_RIVER: "sess.river", MSG_STORM: "sess.storm", MSG_WIDTH: "sess.width", MSG_HEIGHT: "sess.height", MSG_MODE: "sess.mode", MSG_DAEMON: "sess.daemon", LOG_DISABLE: "log.disable", @@ -140,7 +140,7 @@ var chat = { LIB: "lib", PAGE: "page", PANEL: "panel", PLUGIN: "plugin", STORY: "story", PLUG: "plug", TOAST: "toast", CARTE: "carte", INPUT: "input", UPLOAD: "upload", CONTEXTS: "contexts", LAYOUT: "layout", PROJECT: "project", CONTENT: "content", DISPLAY: "display", PROFILE: "profile", ACTIONS: "actions", - TITLE: "title", TOPIC: "topic", BLACK: "black", WHITE: "white", PRINT: "print", LIGHT: "light", DARK: "dark", + TITLE: "title", THEME: "theme", BLACK: "black", WHITE: "white", PRINT: "print", LIGHT: "light", DARK: "dark", SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field", TOOL: "tool", STATE: "state", MENUS: "menus", SSO: "sso", LOCATION: "location", IFRAME: "iframe", OUTPUT: "output", SIMPLE: "simple", FLOAT: "float", FULL: "full", CMD: "cmd", @@ -175,6 +175,8 @@ var chat = { ONRESIZE: "onresize", ONKEYUP: "onkeyup", ONKEYDOWN: "onkeydown", ONMOUSEENTER: "onmouseenter", ORIENTATIONCHANGE: "orientationchange", ONSTORM_SELECT: "onstorm_select", ONACTION_NOTOOL: "onaction_notool", ONACTION_TOUCH: "onaction_touch", ONACTION_CMD: "onaction_cmd", ONOPENSEARCH: "onopensearch", ONSEARCH_FOCUS: "onsearch_focus", ONCOMMAND_FOCUS: "oncommand_focus", + ONTHEMECHANGE: "onthemechange", + ONLAYOUT: "onlayout", ONTOAST: "ontoast", ONDEBUG: "ondebug", ONSHARE: "onshare", ONPRINT: "onprint", _INIT: "_init", _TRANS: "_trans", _STYLE: "_style", _ENGINE: "_engine", _SEARCH: "_search", _OUTPUTS_CURRENT: "_outputs.-1", _NAMES: "_names", _TOAST: "_toast", @@ -305,7 +307,7 @@ var Volcanos = shy({version: window._version||"", iceberg: "/chat/", volcano: "/ setHeaderMenu: function(list, cb) { can._menu && can.page.Remove(can, can._menu) return can._menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.HEADER, chat.ONIMPORT, html .MENU], can._name].concat(list), cb) }, - getHeaderTopic: function(cb) { return can.get(chat.HEADER, chat.TOPIC, cb) }, + getHeaderTheme: function(cb) { return can.get(chat.HEADER, chat.THEME, cb) }, getHeader: function(key, cb) { return can.get(chat.HEADER, key, cb) }, setHeader: function(key, value) { return can.set(chat.HEADER, key, value) }, setAction: function(key, value) { return can.set(chat.ACTION, key, value) },