diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 00000000..08d3924d Binary files /dev/null and b/favicon.ico differ diff --git a/frame.js b/frame.js index a0930a13..ab25241a 100644 --- a/frame.js +++ b/frame.js @@ -13,13 +13,13 @@ var can = Volcanos("chat", { typeof cb == "function" && cb(event, page, value, key, body); }, - run: function(event, option, cmds, cb) {ctx.Run(event, option, cmds, cb)}, + run: function(event, option, cmds, cb) {can.misc.Run(event, page, option, cmds, cb)}, }, Config.libs.concat(["page/"+name]), function(page) {page.Conf(conf); page.onimport._init && page.onimport._init(page, conf, body) can.core.Next(conf.pane, function(item, cb) {page.panes = page.panes || {}; page.panes[item.name] = page[item.pos] = page[item.name] = can.Pane(page, item.name, item, cb, can.page.Select(can, body, "fieldset."+item.name)[0] || - can.page.AppendField(can, body, item.name+" dialog", item)) + can.page.AppendField(can, body, item.name+" "+(item.pos||""), item)) }, function() {typeof cb == "function" && cb(page)}) }, conf) return page.target = body, page @@ -27,7 +27,7 @@ var can = Volcanos("chat", { Pane: shy("构造面板", function(can, name, meta, cb, field) { var river = "", storm = ""; - var pane = Volcanos(name, {_type: "local", + var pane = Volcanos(name, {_type: "local", target: field, option: field.querySelector("form.option"), action: field.querySelector("div.action"), output: field.querySelector("div.output"), @@ -58,7 +58,7 @@ var can = Volcanos("chat", { typeof cb == "function" && cb(event, pane, {width: width, height: height}, "size", pane.output) }, - Show: function(width, height, offset) {field.style.display = "block"; + Show: function(event, width, height, offset) {field.style.display = "block"; if (width < 0) {field.style.left = -width / 2 + "px"; field.style.width = (document.body.offsetWidth + width) + "px"; } @@ -71,6 +71,8 @@ var can = Volcanos("chat", { if (height < 0) {field.style.top = -height / 2 + (offset||0) + "px"; field.style.height = (document.body.offsetHeight + height) + "px"; } + var cb = pane.onimport["show"]; + typeof cb == "function" && cb(event, can, width, "show", pane.output) return field; }, Hide: function() {field.style.display = "none"}, @@ -80,8 +82,10 @@ var can = Volcanos("chat", { msg.Option(item.name, item.value) }) can.run(event, pane.option.dataset, cmds, cb) + return msg }, }, Config.libs.concat(["pane/"+name]), function(pane) { + can.Dream(document.head, "pane/"+name+".css") pane.onimport._init && pane.onimport._init(pane, pane.Conf(meta), pane.output, pane.action, pane.option, field) function deal(event, value) { @@ -93,7 +97,7 @@ var can = Volcanos("chat", { })) typeof cb == "function" && cb(pane) }, meta) - return pane.target = field, pane + return pane }), Plugin: shy("构造插件", function(can, name, meta, run, field) { var option = field.querySelector("form.option"); @@ -105,12 +109,16 @@ var can = Volcanos("chat", { var args = meta.args || []; var feature = JSON.parse(meta.feature||'{}'); var exports = JSON.parse(meta.exports||'{}'); - var plugin = Volcanos(name, {_type: "local", + var plugin = Volcanos(name, {_type: "local", target: field, option: field.querySelector("form.option"), action: field.querySelector("div.action"), output: field.querySelector("div.output"), Inputs: can.Inputs, Output: can.Output, + Import: function(event, value, key) {var cb = plugin.onimport[key]; + typeof cb == "function" && cb(event, plugin, value, key, plugin.output); + }, + Remove: function(event) {var list = can.page.Select(can, option, "input.temp") list.length > 0 && list[list.length-1].parentNode.removeChild(list[list.length-1]) }, @@ -121,7 +129,12 @@ var can = Volcanos("chat", { plugin[name] = can.Inputs(plugin, item, "input", name, value, cb, option); }, Select: function(event, target, focus) { - can.plugin = field, can.input = target || option.querySelectorAll("input")[1]; + can.page.Select(can, field.parentNode, "field.item.select", function(item) { + can.page.ClassList.del(can, item, "select") + }) + can.page.ClassList.add(can, field, "select") + + can._plugin = plugin, can.input = target || option.querySelectorAll("input")[1]; focus && can.input.focus(); return true }, @@ -143,7 +156,7 @@ var can = Volcanos("chat", { }, Check: function(event, target, cb) { plugin.page.Select(can, option, ".args", function(item, index, list) { - if (item == target && index < list.length-1) {can.plugin == field && list[index+1].focus(); return item} + if (item == target && index < list.length-1) {can._plugin.target == field && list[index+1].focus(); return item} }).length == 0 && plugin.Runs(event, cb) }, Last: function(event) { @@ -167,7 +180,7 @@ var can = Volcanos("chat", { }) }, Show: function(type, msg, cb) {plugin.msg = msg, msg._plugin_name = name; - return plugin[type] = can.Output(plugin, type, msg, cb, output, option) + return plugin._output = plugin[type] = can.Output(plugin, type, msg, cb, output, option) }, Clone: function(event) {meta.nick = meta.name + can.ID() can.Plugin(can, meta.nick, meta, run, @@ -177,7 +190,7 @@ var can = Volcanos("chat", { }, Config.libs.concat(["plugin/"+(meta.type||"state")]), function(plugin) {plugin.Conf(meta); can.core.Next(JSON.parse(meta.inputs||"[]"), plugin.Append) }, meta) - return plugin.target = field, field.Plugin = plugin + return plugin }), Inputs: shy("构造控件", function(can, item, type, name, value, cb, option) { var input = Volcanos(name, {type: "local", item: item, @@ -200,10 +213,12 @@ var can = Volcanos("chat", { return input }), Output: shy("构造组件", function(can, type, msg, cb, target, option) { - if (type == "inner" && (!msg.result || msg.result.length == 0)) { - type = "table" - } + if (type == "inner" && (!msg.result || msg.result.length == 0)) {type = "table"} var output = Volcanos(type, {_type: "local", msg: msg, + Import: function(event, value, key) {var cb = output.onimport[key]; + typeof cb == "function" && cb(event, output, value, key, target); + }, + Export: function(event, value, key, index) {can.Report(event, value, key, index)}, run: function(event, cmd, cb, silent) { (output[cmd[1]] || can[cmd[1]] || can.Run)(event, cmd, cb, silent); @@ -214,11 +229,9 @@ var can = Volcanos("chat", { return output.target = target, target.Output = output }), }, Config.libs.concat(Config.list), function(can) { - if (ctx.Search("feature") != "") { - can[Config.main] = can.Page(can, Config.main, Config, function(chat) { - chat.Login.Import(event||{}, "", "login") - can.user.Search(can, "layout") && chat.Login.Export(event||{}, can.user.Search(can, "layout"), "layout") - }, document.body) - } + can[Config.main] = can.Page(can, Config.main, Config, function(chat) { + chat.Login.Export(event||{}, can.user.Search(can, "layout")||"工作", "layout") + chat.Login.Import(event||{}, "", "login") + }, document.body) }) diff --git a/index.html b/index.html new file mode 100644 index 00000000..07e645fc --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + volcanos + + + + + + + + + + + diff --git a/lib/base.js b/lib/base.js index 241b3d50..86b3caab 100644 --- a/lib/base.js +++ b/lib/base.js @@ -19,11 +19,11 @@ Volcanos("base", {help: "基础模块", Time: shy("时间格式化", function(t, fmt) {var now = t? new Date(t): new Date(); fmt = fmt || "%y-%m-%d %H:%M:%S"; fmt = fmt.replace("%y", now.getFullYear()) - fmt = fmt.replace("%m", kit.number(now.getMonth()+1, 2)) - fmt = fmt.replace("%d", kit.number(now.getDate(), 2)) - fmt = fmt.replace("%H", kit.number(now.getHours(), 2)) - fmt = fmt.replace("%M", kit.number(now.getMinutes(), 2)) - fmt = fmt.replace("%S", kit.number(now.getSeconds(), 2)) + fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2)) + fmt = fmt.replace("%d", this.Number(now.getDate(), 2)) + fmt = fmt.replace("%H", this.Number(now.getHours(), 2)) + fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2)) + fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2)) return fmt }), }) diff --git a/lib/core.js b/lib/core.js index 97f2f2c6..c12b6d3e 100644 --- a/lib/core.js +++ b/lib/core.js @@ -1,10 +1,4 @@ Volcanos("core", {help: "核心模块", - Item: shy("迭代器", function(obj, cb) {var list = []; - for (var k in obj) {var res; - list.push(typeof cb == "function" && (res = cb(k, obj[k])) != undefined && res || k) - } - return list - }), List: shy("迭代器", function(obj, cb, interval, cbs) {obj = typeof obj == "string"? [obj]: (obj || []) if (interval > 0) { function loop(i) {if (i >= obj.length) {return typeof cbs == "function" && cbs(obj)} @@ -20,6 +14,20 @@ Volcanos("core", {help: "核心模块", } return list; }), + Item: shy("迭代器", function(obj, cb) {var list = []; + for (var k in obj) {var res; + list.push(typeof cb == "function" && (res = cb(k, obj[k])) != undefined && res || k) + } + return list + }), + Items: function(obj, cb) {var list = [] + for (var key in obj) { + list = list.concat(this.List(obj[key], function(value, index, array) { + return typeof cb == "function" && cb(value, index, key, obj) + })) + } + return list + }, Next: shy("迭代器", function(obj, cb, cbs) {obj = typeof obj == "string"? [obj]: (obj || []) function next(list, cb) { list && list.length > 0? typeof cb == "function" && cb(list[0], function() { diff --git a/lib/misc.js b/lib/misc.js index 75001f88..e7cf49a8 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -1,4 +1,65 @@ Volcanos("misc", {help: "工具模块", + POST: shy("请求后端", {order: 0}, function(can, msg, url, form, cb) { + var args = can.core.Items(form, function(value, index, key) { + return key+"="+encodeURIComponent(value) + }) + var xhr = new XMLHttpRequest() + xhr.onreadystatechange = function() { + if (xhr.readyState != 4) {return} + if (xhr.status != 200) {return} + + try { + var res = JSON.parse(xhr.responseText||'[{"result":[]}]') + res.length > 0 && res[0] && (res = res[0]) + + if (res.download_file) { + window.open(res.download_file.join("")) + } else if (res.page_redirect) { + location.href = res.page_redirect.join("") + } else if (res.page_refresh) { + location.reload() + } + } catch (e) { + var res = {"result": [xhr.responseText]} + } + + typeof cb == "function" && cb(msg.Copy(res)) + } + + xhr.open("POST", url) + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") + xhr.setRequestHeader("Accept", "application/json") + xhr.send(args.join("&")) + ++arguments.callee.meta.order + }), + Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmd, cb) { + var msg = can.Event(event) + + var option = {"cmds": cmd} + msg.option && msg.option.forEach(function(item) { + msg[item] && (option[item] = msg[item]) + }) + for (var k in dataset) { + option[k] = dataset[k].toLowerCase().split(",") + } + + var what = ++arguments.callee.meta.order + + msg._hand = true + msg.option = [] + for (var k in option) { + msg.option.push(k) + msg[k] = option[k] + } + // msg.detail = ["run", what].concat(option.group).concat(option.names).concat(option.cmds) + // kit.Log(msg.detail.concat([msg])) + + // kit.History("run", -1, option) + this.POST(can, msg, can.Conf("context"), option, function(msg) { + // kit.Log("run", what, "result", msg.result? msg.result[0]: "", msg) + typeof cb == "function" && cb(msg) + }), delete(event.msg) + }), }) diff --git a/lib/page.js b/lib/page.js index 42a18c38..1275d15c 100644 --- a/lib/page.js +++ b/lib/page.js @@ -38,7 +38,7 @@ Volcanos("page", {help: "网页模块", if (typeof key == "string") {var res = can.page.Create(can, key, value); return target.appendChild(res), res} value = value || {} - can.core.List(key, function(item, index) { + can.core.List(key, function(item, index) {if (!item) {return} // 基本结构: type name data list var type = item.type || "div", data = item.data || {}; var name = item.name || data.name; @@ -102,6 +102,22 @@ Volcanos("page", {help: "网页模块", data.onkeyup = function(event) { typeof list[2] == "function" && list[2](event); } + } else if (item.username) {var list = can.core.List(item.username); + type = "input", name = name || list[0] || "username"; + data.name = data.name || name; + data.className = data.className || data.name; + data.placeholder = data.placeholder || data.name; + data.title = data.title || data.placeholder; + data.autocomplete = data.autocomplete || "username" + + } else if (item.password) {var list = can.core.List(item.password); + type = "input", name = name || list[0] || "password"; + data.type = "password" + data.name = data.name || name; + data.className = data.className || data.name; + data.placeholder = data.placeholder || data.name; + data.title = data.title || data.placeholder; + data.autocomplete = data.autocomplete || "current-password" } else if (item.row) {type = "tr"; item.list = item.row.map(function(text) {return {text: [text, item.sub||"td"]}}); @@ -150,7 +166,7 @@ Volcanos("page", {help: "网页模块", AppendField: shy("添加插件", function(can, target, type, item) { var dataset = {}; item && item.name && (dataset.names = item.name); item && item.group && (dataset.group = item.group); var field = can.page.Append(can, target, [{view: [type, "fieldset"], list: [ - {text: [(item.nick||item.name||"")+"("+(item.help||"")+")", "legend"]}, + item.pos? undefined: {text: [(item.nick||item.name||"")+"("+(item.help||"")+")", "legend"]}, {view: ["option", "form"], dataset: dataset, list: [{type: "input", style: {display: "none"}}]}, {view: ["action"]}, {view: ["output"]}, @@ -191,12 +207,14 @@ Volcanos("page", {help: "网页模块", return text; }, Download: function(can, name, value) { - can.user.toast({title: "下载中...", width: 200, + var timer = can.user.toast({title: "下载中...", width: 200, text:''+name+'', }) + can.page.Select(can, timer.toast.content, "a", function(item) { + item.click() + }) }, - DelText: function(target, start, count) { target.value = target.value.substring(0, start)+target.value.substring(start+(count||target.value.length), target.value.length) target.setSelectionRange(start, start) @@ -261,11 +279,6 @@ Volcanos("page", {help: "网页模块", event.stopPropagation() return true default: - if (target.value.endsWith("j") && event.key == "k") { - can.page.DelText(target, target.selectionStart-1, 2) - target.blur() - break - } return false } } diff --git a/lib/user.js b/lib/user.js index 56de3fd6..6ae118d3 100644 --- a/lib/user.js +++ b/lib/user.js @@ -2,7 +2,7 @@ Volcanos("user", {help: "用户模块", alert: function(text) {alert(JSON.stringify(text))}, confirm: function(text) {return confirm(JSON.stringify(text))}, prompt: function(text, cb) {(text = prompt(text)) != undefined && typeof cb == "function" && cb(text); return text}, - reload: function() {confirm("重新加载页面?") && location.reload()}, + reload: function(force) {(force || confirm("重新加载页面?")) && location.reload()}, toast: function(text) {}, carte: function(event, cb) {}, diff --git a/order.js b/order.js index 03d2b06a..e86356e1 100644 --- a/order.js +++ b/order.js @@ -1,4 +1,4 @@ -var Config = { +var Config = {context: "/chat/", main: "chat", list: ["page/chat", "pane/Toast", "pane/Carte", "pane/Debug", "pane/Tutor", "pane/Favor", "pane/Login", @@ -12,29 +12,22 @@ var Config = { ], libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"], pane: [ - {group: "index", name: "Toast", pos: "float"}, - {group: "index", name: "Carte", pos: "float"}, - {group: "index", name: "Debug", pos: "float"}, - {group: "index", name: "Login", pos: "float"}, - {group: "index", name: "Favor", pos: "float"}, - {group: "index", name: "Tutor", pos: "float"}, + {group: "index", name: "Toast", pos: "dialog", duration: 3000}, + {group: "index", name: "Carte", pos: "dialog"}, + {group: "index", name: "Debug", pos: "dialog"}, + {group: "index", name: "Login", pos: "dialog"}, + {group: "index", name: "Favor", pos: "dialog"}, + {group: "index", name: "Tutor", pos: "dialog"}, - {group: "index", name: "Header", pos: "head", - title: "github.com/shylinux/context", - state: ["time", "user", "link"], - }, - {group: "index", name: "Ocean", pos: "float", def_name: "meet"}, + {group: "index", name: "Header", pos: "head", state: ["time", "user", "link"], title: "github.com/shylinux/context"}, + {group: "index", name: "Ocean", pos: "dialog", def_name: "meet"}, {group: "index", name: "River", pos: "left"}, {group: "index", name: "Storm", pos: "right"}, - {group: "index", name: "Steam", pos: "float", def_name: "miss"}, - + {group: "index", name: "Steam", pos: "dialog", def_name: "miss"}, {group: "index", name: "Target", pos: "top"}, {group: "index", name: "Source", pos: "center"}, {group: "index", name: "Action", pos: "bottom"}, - {group: "index", name: "Footer", pos: "foot", - title: 'shylinux@163.com', - state: ["ntxt", "ncmd"], - }, + {group: "index", name: "Footer", pos: "foot", state: ["ntxt", "ncmd"], title: 'shylinux@163.com'}, ], layout: {list: ["工作", "办公", "聊天"], size: { "工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0}, diff --git a/page/chat.js b/page/chat.js index 2a3c00be..d3bb9616 100644 --- a/page/chat.js +++ b/page/chat.js @@ -11,12 +11,12 @@ Volcanos("onimport", {help: "导入数据", list: [], Volcanos("onaction", {help: "组件交互", list: [], onkeydown: function(event, can) { switch (event.key) { + case "Escape": + break case " ": - if (can.Favor) { - can.page.Select(can, can.Favor.Show(), "input.cmd", function(item) { - item.focus() - }) - } + can.Favor && can.page.Select(can, can.Favor.Show(), "input.cmd", function(item) { + item.focus() + }) event.stopPropagation() event.preventDefault() diff --git a/pane/Action.css b/pane/Action.css new file mode 100644 index 00000000..bb16ee50 --- /dev/null +++ b/pane/Action.css @@ -0,0 +1,4 @@ +fieldset.Action div.output div.item:hover { + background-color:lightblue; +} + diff --git a/pane/Action.js b/pane/Action.js index 1eaa2317..d497ed05 100644 --- a/pane/Action.js +++ b/pane/Action.js @@ -38,9 +38,14 @@ Volcanos("onimport", {help: "导入数据", list: [], item.value = value }) }, - favor: function(event, can, msg, cmd, output) {cmd = msg.detail[0]; - var p = can[cmd]; if (p && p.Select) {p.Select(event, null, true); return msg._hand = true} - var cb = can.onaction[cmd]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg._hand = true} + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + if (msg._hand) {return} + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + + var sub = can[key]; if (sub && sub.Select) {sub.Select(event, null, true); return msg.Echo(can._name, " select ", sub._name), msg._hand = true} + + can._plugin && can._plugin.Import(event, msg, cmd) }, }) Volcanos("onaction", {help: "组件交互", list: [["layout", "工作", "办公", "聊天"], "清屏", "刷新", "串行", "并行", diff --git a/pane/Carte.css b/pane/Carte.css new file mode 100644 index 00000000..cb0750b0 --- /dev/null +++ b/pane/Carte.css @@ -0,0 +1,32 @@ +fieldset.dialog.Carte { + padding:0; + border:solid 2px red; + background-color:greenyellow; + position:absolute; + display:none; + z-index:200; +} +fieldset.dialog.Carte>div.action { + padding:0; +} +fieldset.dialog.Carte>div.output { + padding:0; +} +fieldset.dialog.Carte>div.output button { + display:block; +} +fieldset.dialog.Carte>div.output select { + display:block; +} +fieldset.dialog.Carte>div.output div.layout>div { + float:left; +} +fieldset.dialog.Carte>div.output div.item { + padding:0px 6px; +} +fieldset.dialog.Carte>div.output div.space { + border:solid 1px gray; + margin-top:8px; + clear:both; +} + diff --git a/pane/Carte.js b/pane/Carte.js index 5f695af0..a1aacae5 100644 --- a/pane/Carte.js +++ b/pane/Carte.js @@ -21,11 +21,13 @@ Volcanos("onimport", {help: "导入数据", list: [], event.stopPropagation() event.preventDefault() - can.Show() + can.Show(event) } }, }) -Volcanos("onaction", {help: "组件交互", list: []}) +Volcanos("onaction", {help: "组件交互", list: [], + onmouseleave: function(event, can) {can.Hide()}, +}) Volcanos("onchoice", {help: "组件菜单", list: []}) Volcanos("ondetail", {help: "组件详情", list: []}) Volcanos("onexport", {help: "导出数据", list: []}) diff --git a/pane/Debug.css b/pane/Debug.css new file mode 100644 index 00000000..957958ad --- /dev/null +++ b/pane/Debug.css @@ -0,0 +1,49 @@ +fieldset.dialog.Debug { + opacity:0.8; +} +fieldset.dialog.Debug tr.hide { + display:none; +} +fieldset.dialog.Debug tr.event { + background-color:red; +} +fieldset.dialog.Debug tr.run { + background-color:lightgreen; +} +fieldset.dialog.Debug tr.wss { + background-color:lightblue; +} +fieldset.dialog.Debug tr.key { + background-color:lightyellow; +} +fieldset.dialog.Debug>div.output { + overflow:auto; + margin-top:50px; +} +fieldset.dialog.Debug>div.output table caption { + position:absolute; + top:50px; + left:20px; +} +fieldset.dialog.Debug>div.output table thead { + position:absolute; + top:72px; + left:18px; +} +fieldset.dialog.Debug>div.output table thead th { + border:solid 1px red; +} +fieldset.dialog.Debug>div.output table caption>span { + margin-right:4px; +} +fieldset.dialog.Debug>div.output table caption>span:hover { + cursor:pointer; + background-color:red; +} +fieldset.dialog.Debug>div.output table th { + min-width:60px; +} +fieldset.dialog.Debug>div.output table td { + min-width:60px; +} + diff --git a/pane/Favor.css b/pane/Favor.css new file mode 100644 index 00000000..90fd741a --- /dev/null +++ b/pane/Favor.css @@ -0,0 +1,28 @@ +fieldset.Favor { + border:solid 2px red; + background-color:rgba(100,100,100,0.8); + position:absolute; + display:none; + z-index:100; +} +fieldset.Favor input.cmd { + color:white; + font-size:16px; + font-weight:bold; + font-family:monospace; + background-color:black; + border:solid 1px white; + padding:4px; + min-width:383px; +} +fieldset.Favor div.output { + color:white; + font-size:16px; + font-family:monospace; + white-space:pre; + max-width:640px; + max-height:240px; + overflow:auto; +} + + diff --git a/pane/Favor.js b/pane/Favor.js index 6e8d8e10..42298bb7 100644 --- a/pane/Favor.js +++ b/pane/Favor.js @@ -1,47 +1,58 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, conf, output, action, option, field) { - can.Show(400, 100, 100), can.Hide(); - can.page.Append(can, option, [{input: ["cmd", function(event) { + can.Show(event, 400, 100), can.Hide(); + can.target.style.height = "" + can.target.style.width = "" + + function res(msg) { + if (msg._hand) {ui.cmd.value = ""; + output.innerHTML = msg.Result() + } + return msg + } + function run(event, cmds) {cmds = cmds.trim().split(" "); + var cmd = cmds[0]; if (cmd == "") {return} + var msg = can.Event(event, {detail: cmds}); + can.msg = msg; + + var cb = can.onexport[cmd]; + typeof cb == "function"? cb(event, can, msg, cmds, output): can.Export(event, msg, "favor"); + + return msg._hand? res(msg): can.run(event, cmds, res, true); + } + + var ui = can.page.Append(can, option, [{input: ["cmd", function(event) { can.page.oninput(event, can) - function run(cmds) {cmds = cmds.split(" ") - var cmd = cmds[0] - - var msg = can.Event(event, {detail: cmds}); - var cb = can.onexport[cmd] - if (typeof cb == "function") { - cb(event, can, msg, cmds, output); - } else { - can.Export(event, msg, "favor") - } - - if (!msg._hand) { - can.run(event, cmds, function(msg) { - (output.innerHTML = msg.Result()) == ""? (can.target.style.height = "100px"): (can.target.style.height = ""); - event.target.value = ""; - }, true) - } else { - output.innerHTML = msg.Result(); - event.target.value = ""; - } - return msg - } - switch (event.key) { - case "Enter": run(event.target.value.trim()); break + case "Enter": run(event, event.target.value); break case "Escape": can.Hide(); break + default: if (event.target.value.endsWith("j") && event.key == "k") { + can.page.DelText(event.target, event.target.selectionStart-1, 2) + event.target.value == ""? can.Hide(): run(event, event.target.value) + break + } return false } + event.stopPropagation() + event.preventDefault() + return true + }, function(event) { + switch (event.key) { + default: return false + } + event.stopPropagation() + event.preventDefault() + return true }]}]) }, }) Volcanos("onaction", {help: "组件交互", list: [], onmousedown: function(event, can) { - can.moving = !can.moving; - can.movarg = { - x: event.x, y: event.y, - top: can.target.offsetTop, + if (event.ctrlKey) {can.moving = !can.moving, can.movarg = { left: can.target.offsetLeft, - }; + top: can.target.offsetTop, + x: event.x, y: event.y, + }} }, onmousemove: function(event, can) { if (can.moving) { @@ -53,16 +64,15 @@ Volcanos("onaction", {help: "组件交互", list: [], // can.moving = false; }, }) -Volcanos("onchoice", {help: "组件菜单", list: []}) -Volcanos("ondetail", {help: "组件详情", list: []}) -Volcanos("onexport", {help: "导出数据", list: [], - pwd: function(event, can, msg, cmd, output) { - msg.Echo("hello world") - }, - time: function(event, can, msg, cmd, output) { - msg.Echo(can.base.Time()) +Volcanos("onchoice", {help: "组件菜单", list: ["下载"], + "下载": function(event, can, msg, cmd, target) {msg = msg || can.msg; + var list = msg.Export(can._name); + can.page.Download(can, list[0]+list[1], list[2]); }, }) - - +Volcanos("ondetail", {help: "组件详情", list: []}) +Volcanos("onexport", {help: "导出数据", list: [], + hi: function(event, can, msg, cmd, output) {msg.Echo("hello world")}, + time: function(event, can, msg, cmd, output) {msg.Echo(can.base.Time())}, +}) diff --git a/pane/Footer.css b/pane/Footer.css new file mode 100644 index 00000000..aa2f2117 --- /dev/null +++ b/pane/Footer.css @@ -0,0 +1,29 @@ +fieldset.Footer { + clear:both; + overflow:hidden; + height:32px; +} +fieldset.Footer>div.action { + padding:0; +} +fieldset.Footer>div.output div.title { + float:left; +} +fieldset.Footer>div.output div.magic { + float:right; + margin-top:-6px; +} +fieldset.Footer>div.output div.magic>label { + margin-right:2px; +} +fieldset.Footer>div.output div.magic>input { + background-color:black; + color:lightgreen;; +} +fieldset.Footer>div.output div.state { + float:right; +} +fieldset.Footer>div.output div.state div { + float:right; +} + diff --git a/pane/Header.css b/pane/Header.css new file mode 100644 index 00000000..a59bdd90 --- /dev/null +++ b/pane/Header.css @@ -0,0 +1,32 @@ +fieldset.Header { + height:32px; + min-width:640px; + clear:both; +} +fieldset.Header>div.action { + padding:0; +} +fieldset.Header>div.output>div.title { + cursor:pointer; + float:left; +} +fieldset.Header>div.output>div.title:hover { + cursor:pointer; + background-color:red; + border:ridge 2px yellow; +} +fieldset.Header>div.output>div.state { + float:right; +} +fieldset.Header>div.output>div.state div.item { + padding:0; +} +fieldset.Header>div.output>div.state>div { + cursor:pointer; + margin-left:5px; + float:right; +} +fieldset.Header>div.output>div.state>div:hover { + background-color:red; +} + diff --git a/pane/Header.js b/pane/Header.js index d021fc22..433d5678 100644 --- a/pane/Header.js +++ b/pane/Header.js @@ -47,5 +47,12 @@ Volcanos("onexport", {help: "导出数据", list: [], link: function(event, can, value, cmd, output) { can.ui[cmd].innerHTML = value }, + user: function(event, can, value, cmd, output) { + if (can.user.confirm("logout?")) { + can.user.Cookie(can, "sessid", "") + can.user.reload() + } + can.ui["user"].innerHTML = value + }, }) diff --git a/pane/Login.css b/pane/Login.css new file mode 100644 index 00000000..512cbe80 --- /dev/null +++ b/pane/Login.css @@ -0,0 +1,13 @@ +fieldset.Login { + font-size:28px; + z-index:20; +} +fieldset.Login>form.option input { + font-size:18px; + height:28px; +} +fieldset.Login>form.option button { + font-size:18px; + height:28px; +} + diff --git a/pane/Login.js b/pane/Login.js index a5f739f8..3c9ca2ff 100644 --- a/pane/Login.js +++ b/pane/Login.js @@ -1,10 +1,31 @@ Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, conf, output, action, option, field) { + var ui = can.page.Appends(can, option, [ + {text: ["username: ", "label"]}, {username: []}, {type: "br"}, + {text: ["password: ", "label"]}, {password: []}, {type: "br"}, + {button: ["login", function(event, cmd) { + if (!ui.username.value) {ui.username.focus(); return} + if (!ui.password.value) {ui.password.focus(); return} + + can.run(event, [ui.username.value, ui.password.value], function(msg) { + if (msg.result && msg.result.length > 0) { + can.Hide(), can.Export(event, "", "login") + } else { + can.user.toast("用户或密码错误") + } + }) + event.stopPropagation() + event.preventDefault() + return true + }]}, {type: "br"}, + ]) + }, login: function(event, can, value, cmd, output) { - if (!can.user.Cookie("sessid")) {can.Show(); return} + if (!can.user.Cookie("sessid")) {can.Show(event, 400, 400); return} can.run(event||{}, [], function(msg) { msg.nickname && msg.nickname.length > 0? - can.Export(event, msg.nickname[0], "username"): can.Show() + can.Export(event, msg.nickname[0], "username"): can.Show(event, -1, -1) }) }, }) diff --git a/pane/Ocean.css b/pane/Ocean.css new file mode 100644 index 00000000..3ad4ff6d --- /dev/null +++ b/pane/Ocean.css @@ -0,0 +1,8 @@ +fieldset.Ocean div.create pre:hover { + background-color:red; +} +fieldset.Ocean div.create pre:hover { + background-color:red; +} + + diff --git a/pane/Ocean.js b/pane/Ocean.js index d6edcff9..78633f86 100644 --- a/pane/Ocean.js +++ b/pane/Ocean.js @@ -29,7 +29,7 @@ Volcanos("onimport", {help: "导入数据", list: [], }) }, ocean: function(event, can, value, key, output) { - if (value == "create") {can.Show(); + if (value == "create") {can.Show(event); can.run(event, [], function(msg) { can.onimport.init(event, can, msg, key, output); }); diff --git a/pane/River.css b/pane/River.css new file mode 100644 index 00000000..f34292ed --- /dev/null +++ b/pane/River.css @@ -0,0 +1,10 @@ +fieldset.River { + float:left; +} +fieldset.River>div.output { + padding:0; +} +fieldset.River>div.output>div.item { + padding-left:6px; +} + diff --git a/pane/River.js b/pane/River.js index e2ede911..5d0a8698 100644 --- a/pane/River.js +++ b/pane/River.js @@ -16,11 +16,15 @@ Volcanos("onimport", {help: "导入数据", list: [], }) } }, - favor: function(event, can, msg, cmd, output) { + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + if (msg._hand) {return} + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + can.page.Select(can, output, "div.item>span", function(item) { if (item.innerText == msg.detail[0]) { - msg.Echo("storm", msg.detail[0]) item.click(), msg._hand = true; + msg.Echo(can._name, " ", key) } }) }, diff --git a/pane/Source.css b/pane/Source.css new file mode 100644 index 00000000..763e3d43 --- /dev/null +++ b/pane/Source.css @@ -0,0 +1,10 @@ +fieldset.Source { + overflow:hidden; +} +fieldset.Source div.action { + padding:0; +} +fieldset.Source div.output { + padding:0; +} + diff --git a/pane/Steam.css b/pane/Steam.css new file mode 100644 index 00000000..9bbd187a --- /dev/null +++ b/pane/Steam.css @@ -0,0 +1,16 @@ +fieldset.Steam table.device { + padding:10px; + border:solid 1px green; + margin-left:10px; + float:left; +} +fieldset.Steam div.output tr.select { + background-color:red; +} +fieldset.Steam div.create { + /* clear:both; */ +} +fieldset.Steam div.create pre:hover { + background-color:red; +} + diff --git a/pane/Steam.js b/pane/Steam.js index e45d47b8..23916034 100644 --- a/pane/Steam.js +++ b/pane/Steam.js @@ -21,7 +21,7 @@ Volcanos("onimport", {help: "导入数据", list: [], can.device = device can.ui = ui }, - init: function(event, can, msg, key, output) {output.innerHTML = ""; can.Show(-100, -100); + init: function(event, can, msg, key, output) {output.innerHTML = ""; can.Show(event, -100, -100); var table = can.page.Append(can, output, "table") can.page.Append(can, table, [{text: ["1. 选择用户节点 ->", "caption"]}]) diff --git a/pane/Storm.css b/pane/Storm.css new file mode 100644 index 00000000..0ce4b2b6 --- /dev/null +++ b/pane/Storm.css @@ -0,0 +1,11 @@ +fieldset.Storm { + float:right; +} +fieldset.Storm>div.output { + padding:0; +} +fieldset.Storm>div.output>div.item { + padding-left:6px; +} + + diff --git a/pane/Storm.js b/pane/Storm.js index 4c69c99f..88c7bf26 100644 --- a/pane/Storm.js +++ b/pane/Storm.js @@ -17,10 +17,15 @@ Volcanos("onimport", {help: "导入数据", list: [], }) } }, - favor: function(event, can, msg, cmd, output) { + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + if (msg._hand) {return} + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + + can.page.Select(can, output, "div.item.k"+msg.detail[0], function(item) { - msg.Echo("storm", msg.detail[0]) item.click(), msg._hand = true; + msg.Echo(can._name, " ", key) }) }, }) @@ -34,20 +39,14 @@ Volcanos("onaction", {help: "组件交互", list: ["创建", "刷新"], }) }, }) -Volcanos("onchoice", {help: "组件菜单", list: ["返回", "清空", "复制", "下载", "表格", "绘图", "媒体"], - "返回": function(event, can, msg, cmd, target) { - can.run(event, ["", "Last"]) +Volcanos("onchoice", {help: "组件菜单", list: ["创建", "刷新"], + "创建": function(event, can, msg, cmd, output) { + can.Export(event, "create", "steam") }, - "清空": function(event, can, msg, cmd, target) { - can.target.innerHTML = ""; - }, - "复制": function(event, can, msg, cmd, target) { - var list = can.onexport.Format(can, msg, "data"); - can.user.toast(can.page.CopyText(can, list[2]), "复制成功") - }, - "下载": function(event, can, msg, cmd, target) { - var list = can.onexport.Format(can, msg, msg._plugin_name||"data"); - can.page.Download(can, list[0]+list[1], list[2]); + "刷新": function(event, can, msg, cmd, output) { + can.run(event, [can.Conf("river")], function(msg) { + can.onimport.init(event, can, msg, cmd, output) + }) }, }) Volcanos("ondetail", {help: "组件详情", list: ["保存", "恢复", "删除"], diff --git a/pane/Target.css b/pane/Target.css new file mode 100644 index 00000000..f56a19f1 --- /dev/null +++ b/pane/Target.css @@ -0,0 +1,23 @@ +fieldset.Target div.output div.item:hover { + background-color:lightgreen; +} +fieldset.Target>div.output>div.item { + padding-top:6px; + clear:both; +} +fieldset.Target>div.output>div.item>div.text { + padding:6px; + float:left; +} +fieldset.Target>div.output>div.item>div.time { + padding-left:5px; + font-size:10px; + color:gray; +} +fieldset.Target>div.output>div.item>div.user { + border-right:solid 1px green; + border-bottom:solid 1px green; + float:left; + padding:6px; +} + diff --git a/pane/Toast.css b/pane/Toast.css new file mode 100644 index 00000000..615c1705 --- /dev/null +++ b/pane/Toast.css @@ -0,0 +1,32 @@ +fieldset.dialog.Toast { + border:solid 2px red; + background-color:#ffffff; + position:absolute; + display:none; + z-index:200; +} +fieldset.dialog.Toast>div.action { + padding:0 0px; +} +fieldset.dialog.Toast>div.output { + padding:0 10px; + text-align:center; +} +fieldset.dialog.Toast>div.output>div.title { + font-size:12px; + text-align:center; + color:gray; +} +fieldset.dialog.Toast>div.output>div.content { + word-break:break-word; + white-space:pre-wrap; + text-align:center; + margin:0px; + padding:2px; + font-size:16px; +} +fieldset.dialog.Toast>div.output>div.tick { + font-size:12px; + color:gray; +} + diff --git a/pane/Toast.js b/pane/Toast.js index a54cfa92..02f96cde 100644 --- a/pane/Toast.js +++ b/pane/Toast.js @@ -1,11 +1,12 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, conf, output) { can.user.toast = function(text, title, duration, list) {if (!text) {return can.Hide()} - text = typeof text == "object"? text: {list: list, text: text, title: title||"", duration: duration||3000} + text = typeof text == "object"? text: {list: list, text: text, title: title||""} + text.duration = text.duration || conf.duration || 3000 var list = [{text: [text.title||"", "div", "title"]}, {text: [text.text||"", "div", "content"]}, - {view: ["form"], list: text.list||[{type: "button", inner: "cancel", click: function() { + {view: ["form"], list: text.list||[{type: "button", inner: "ok", click: function() { timer.stop = true }}]}, {text: [text.tick||"", "div", "tick"]}, @@ -14,7 +15,7 @@ Volcanos("onimport", {help: "导入数据", list: [], var toast = can.page.Appends(can, output, list) var width = text.width||text.text.length*10+100 width = width>400?400:width - can.Show(width, text.height||80) + can.Show(event, width, text.height||80) var begin = can.base.Time().split(" ")[1] var timer = can.Timer({value: 1000, length: text.duration > 0? text.duration/1000: text.duration}, function(t, i) { @@ -25,9 +26,12 @@ Volcanos("onimport", {help: "导入数据", list: [], }, function() { can.Hide() }) + timer.toast = toast return timer } }, + show: function(event, can, value, cmd, output) { + } }) Volcanos("onaction", {help: "组件交互", list: []}) Volcanos("onchoice", {help: "组件菜单", list: []}) diff --git a/pane/Tutor.css b/pane/Tutor.css new file mode 100644 index 00000000..e69de29b diff --git a/plugin/inner.js b/plugin/inner.js index 20264378..e654de17 100644 --- a/plugin/inner.js +++ b/plugin/inner.js @@ -28,6 +28,10 @@ Volcanos("onimport", {help: "导入数据", list: [], } }) }, + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + }, }) Volcanos("onaction", {help: "组件交互", list: [], }) diff --git a/plugin/input.js b/plugin/input.js index c207e70e..d82ab933 100644 --- a/plugin/input.js +++ b/plugin/input.js @@ -4,7 +4,7 @@ Volcanos("onimport", {help: "导入数据", list: [], switch (item.type) { case "upfile": item.type = "file"; break case "select": - item.values = kit.Trans(item.values); + item.values = typeof item.values == "string"? item.values.split(" "): item.values; input.type = "select", input.list = item.values.map(function(value) { return {type: "option", value: value, inner: value}; }) @@ -39,9 +39,30 @@ Volcanos("onimport", {help: "导入数据", list: [], Volcanos("onaction", {help: "控件交互", list: [], onclick: function(event, can) {can.Select(event); can.item.type == "button" && can.run(event)}, onkeydown: function(event, can) { - if (event.key == "Enter") {return can.run(event, [])} - if (event.key == "Escape") {return event.target.blur()} can.page.oninput(event, can) + + switch (event.key) { + case "Enter": can.run(event, []); break + case "Escape": event.target.blur(); break + default: + if (event.target.value.endsWith("j") && event.key == "k") { + can.page.DelText(event.target, event.target.selectionStart-1, 2); + event.target.blur(); + break + } + return false + } + event.stopPropagation() + event.preventDefault() + return true + }, + onkeyup: function(event, can) { + switch (event.key) { + default: return false + } + event.stopPropagation() + event.preventDefault() + return true }, }) Volcanos("onchoice", {help: "控件菜单", list: ["全选", "复制", "清空"], diff --git a/plugin/media.js b/plugin/media.js index a03de5d2..bd686e30 100644 --- a/plugin/media.js +++ b/plugin/media.js @@ -1,9 +1,13 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, output, action, option, field) { - output.innerHTML = msg.Result(); -}, + output.innerHTML = msg.Result(); + }, init: function(can, msg, cb, output, option) {output.innerHTML = msg.Result(); }, + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + }, }) Volcanos("onaction", {help: "组件交互", list: []}) Volcanos("onchoice", {help: "组件菜单", list: []}) diff --git a/plugin/state.js b/plugin/state.js index 16f2ec0f..5481a992 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -1,4 +1,12 @@ -Volcanos("onimport", {help: "导入数据", list: []}) +Volcanos("onimport", {help: "导入数据", list: [], + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + + var sub = can[key]; if (sub && sub.target) {sub.target.focus; return msg.Echo(can._name, " ", sub._name, " ", key), msg._hand = true} + can._output && can._output.Import(event, msg, cmd) + }, +}) Volcanos("onaction", {help: "组件交互", list: []}) Volcanos("onchoice", {help: "组件菜单", list: [["display", "表格", "文档", "相册"], "执行", "返回", "加参", "减参", "克隆", "删除"], diff --git a/plugin/table.js b/plugin/table.js index c3fc2372..635c9d8d 100644 --- a/plugin/table.js +++ b/plugin/table.js @@ -43,6 +43,11 @@ Volcanos("onimport", {help: "导入数据", list: [], }) }) }, + + favor: function(event, can, msg, cmd, output) {var key = msg.detail[0]; + var cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onaction ", key), msg._hand = true} + var cb = can.onchoice[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, output); return msg.Echo(can._name, " onchoice ", key), msg._hand = true} + }, }) Volcanos("onaction", {help: "组件交互", list: [], }) diff --git a/proto.js b/proto.js index db660f85..8716e41c 100644 --- a/proto.js +++ b/proto.js @@ -112,11 +112,33 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块 Result: function() { return msg.result && msg.result.join("") || ""; }, + Export: function(name) {var ext = ".csv", txt = ""; + msg.append && msg.append.length > 0? txt = can.core.List(msg.append, function(key) {return key}).join(",")+"\n"+ + can.core.List(msg.Table(), function(line, index) { + return can.core.List(msg.append, function(key) {return line[key]}).join(",") + }).join("\n"): (ext = ".txt", txt = msg.Result()) + return [name, ext, txt] + }, }; msg.event = event return msg }), Dream: shy("构造器", function(target, type, line, key) { + if (type.endsWith(".css")) { + var style = document.createElement("link"); + style.rel = "stylesheet", style.type = "text/css"; + style.href = (can._path||meta.path)+type + style.onload = line; + target.appendChild(style); + return style + } + if (type.endsWith(".js")) { + var script = document.createElement("script"); + script.src = (can._path||meta.path)+type, + script.onload = line; + target.appendChild(script); + return script + } var text = line, list = [], item = false, style = "" switch (type) { case "input": @@ -181,10 +203,9 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块 can.load(libs[0]), next() } else { // 加载脚本 - var script = document.createElement("script"); - script.src = (can._path||meta.path)+libs[0]+".js"; - script.onload = function() {can.load(libs[0]), next()} - document.body.appendChild(script); + can.Dream(document.body, libs[0]+".js", function() { + can.load(libs[0]), next(); + }) } } else { // 独立模块 diff --git a/style.css b/style.css new file mode 100644 index 00000000..aa38b582 --- /dev/null +++ b/style.css @@ -0,0 +1,246 @@ +html, body { + background-color:#d8d8d8; + padding:0px; + height:100%; + width:100%; + margin:0px; +} +fieldset { + position:relative; + background-color:#d8d8d8; + padding:0px; + min-width:10px; + overflow:auto; + margin:0px; +} +legend { + margin-left:10px; +} + +fieldset>form.option { + padding:0 5px; + margin-right:3px; + float:left; +} +fieldset>form.option div { + margin-right:3px; + float:left; +} +fieldset>form.option div.hide { + display:none; +} +fieldset>form.option div.clear { + clear:both; +} +fieldset>form.option label { + margin-right:3px; +} +fieldset>form.option input.args.cmd { + color:white; + background-color: black; + width:160px; +} +fieldset>form.option input.args.char { + width:20px; +} +fieldset>form.option input.args.tiny { + width:40px; +} +fieldset>form.option input.args { + width:80px; +} +fieldset>form.option input.args.long { + width:240px; +} +fieldset>form.option input.args.full { + width:480px; +} +fieldset>form.option div.item.textarea { + float:left; + clear:both; +} +fieldset>div.action { + padding:6px; +} +fieldset>div.action div.space { + display:inline-block; + width:10px; +} +fieldset>div.output { + clear:both; + /* max-height:800px; */ + padding:5px; +} +fieldset>div.output div.item { + padding:2px; +} +fieldset>div.output div.item:hover { + cursor:pointer; + background-color:red; + border:ridge 2px yellow; +} +fieldset>div.output div.item.select { + background-color:red; + border:ridge 2px yellow; +} +fieldset>div.output div.code { + color:white; + font-size:14px; + font-family:monospace; + background-color:#272822; + white-space:pre; + padding:10px; + overflow:auto; + border:solid 3px green; + max-height:640px; +} +fieldset>div.output div.code span.red { + color:red; +} +fieldset>div.output div.code span.green { + color:green; +} +fieldset>div.output table td { + /* word-break:break-word; */ +} +fieldset>div.output table td.when { + /* word-break:break-word; */ + text-align:center; +} +fieldset>div.output table.edit { +} +fieldset>div.output table.edit td { + min-width:4px; + padding:0px; +} +fieldset>div.output table.edit td>input { + width:600px; + padding:0px; +} +fieldset>div.output table.edit { +} + +fieldset.dialog { + background-color:lightgray; + padding:10px; + display:none; + position:absolute; + z-index:10; +} +fieldset.dialog>div.output { + padding:10px; + float:left; +} +fieldset.dialog>div.output table th { + min-width:130px; +} +fieldset.dialog>div.output table td { + min-width:100px; +} +fieldset.dialog>div.create { + padding:10px; + border:solid 1px red; + margin-left:10px; + float:left; +} +fieldset.dialog>div.create table { + min-width:240px; +} + +fieldset.item { + float:left; +} +fieldset.item:hover { + background-color:gold; + border:ridge 2px red; +} +fieldset.item.select { + background-color:gold; + border:ridge 2px red; +} +fieldset.item>form.option>div.item { + padding:0; + border:0; +} +fieldset.item>form.option>div.item:hover { + border:0; +} +fieldset.item>form.option>div.item.select { + border:0; +} +fieldset.item>div.output { + overflow:auto; +} +fieldset.item>div.output>canvas { + background-color:#8dd09e; +} +fieldset.item>div.output>div.action>button.trap { + background-color:lightblue; + border:2px blue solid; +} +fieldset.item>div.output>div.action>div.space { + width:10px; + display:inline-block; +} +fieldset.item>div.output>div.status>div { + float:left; + height:20px; + border:1px solid black; +} +fieldset.item>div.output>div.status>input.cmd { + float:left; + background-color:black; + color:lightgreen;; + font-size:16px; + width:250px; +} +fieldset.item>div.output>div.code { +} +fieldset.item>div.output>div.code div.number { + float:left; +} + +fieldset table { + font-size:14px; + overflow: auto; + border:solid 1px green; +} +fieldset table caption { + font-size:18px; + font-style:italic; + border:solid 1px green; +} +fieldset table tbody { + overflow:auto; +} +fieldset table tr:hover { + background-color:lightgreen; +} +fieldset table tr.select { + background-color:lightgreen; +} +fieldset table th { + font-family:monospace; + background-color:lightgreen; + cursor:pointer; + padding: 0 6px; +} +fieldset table th.order { + background-color:red; + cursor:pointer; +} +fieldset table td { + max-width:1200px; + font-family:monospace; + padding: 0 6px; + /* white-space: pre; */ +} +fieldset table td.clip { + background-color:red; +} +fieldset table td:hover { + background-color:red; +} +fieldset table td.select { + background-color:red; +}