1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 08:48:06 +08:00
This commit is contained in:
shaoying 2019-12-12 17:45:22 +08:00
parent 6c878dc7dc
commit 30bcd0df6f
42 changed files with 905 additions and 143 deletions

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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)
})

16
index.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=0.7,user-scalable=no">
<title>volcanos</title>
<link rel="shortcut icon" type="image/ico" href="/static/volcanos/favicon.ico">
<link rel="stylesheet" type="text/css" href="/static/volcanos/style.css">
</head>
<body>
<script src="/static/volcanos/proto.js"></script>
<script src="/static/volcanos/order.js"></script>
<script src="/static/volcanos/frame.js"></script>
</body>

View File

@ -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
}),
})

View File

@ -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() {

View File

@ -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)
}),
})

View File

@ -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:'<a href="'+URL.createObjectURL(new Blob([value]))+'" target="_blank" download="'+name+'">'+name+'</a>',
})
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
}
}

View File

@ -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) {},

View File

@ -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: '<a href="mailto:shylinux@163.com">shylinux@163.com</a>',
state: ["ntxt", "ncmd"],
},
{group: "index", name: "Footer", pos: "foot", state: ["ntxt", "ncmd"], title: '<a href="mailto:shylinux@163.com">shylinux@163.com</a>'},
], layout: {list: ["工作", "办公", "聊天"], size: {
"工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0},

View File

@ -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()

4
pane/Action.css Normal file
View File

@ -0,0 +1,4 @@
fieldset.Action div.output div.item:hover {
background-color:lightblue;
}

View File

@ -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", "工作", "办公", "聊天"], "清屏", "刷新", "串行", "并行",

32
pane/Carte.css Normal file
View File

@ -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;
}

View File

@ -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: []})

49
pane/Debug.css Normal file
View File

@ -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;
}

28
pane/Favor.css Normal file
View File

@ -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;
}

View File

@ -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())},
})

29
pane/Footer.css Normal file
View File

@ -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;
}

32
pane/Header.css Normal file
View File

@ -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;
}

View File

@ -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
},
})

13
pane/Login.css Normal file
View File

@ -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;
}

View File

@ -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)
})
},
})

8
pane/Ocean.css Normal file
View File

@ -0,0 +1,8 @@
fieldset.Ocean div.create pre:hover {
background-color:red;
}
fieldset.Ocean div.create pre:hover {
background-color:red;
}

View File

@ -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);
});

10
pane/River.css Normal file
View File

@ -0,0 +1,10 @@
fieldset.River {
float:left;
}
fieldset.River>div.output {
padding:0;
}
fieldset.River>div.output>div.item {
padding-left:6px;
}

View File

@ -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)
}
})
},

10
pane/Source.css Normal file
View File

@ -0,0 +1,10 @@
fieldset.Source {
overflow:hidden;
}
fieldset.Source div.action {
padding:0;
}
fieldset.Source div.output {
padding:0;
}

16
pane/Steam.css Normal file
View File

@ -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;
}

View File

@ -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"]}])

11
pane/Storm.css Normal file
View File

@ -0,0 +1,11 @@
fieldset.Storm {
float:right;
}
fieldset.Storm>div.output {
padding:0;
}
fieldset.Storm>div.output>div.item {
padding-left:6px;
}

View File

@ -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: ["保存", "恢复", "删除"],

23
pane/Target.css Normal file
View File

@ -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;
}

32
pane/Toast.css Normal file
View File

@ -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;
}

View File

@ -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: []})

0
pane/Tutor.css Normal file
View File

View File

@ -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: [],
})

View File

@ -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: ["全选", "复制", "清空"],

View File

@ -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: []})

View File

@ -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", "表格", "文档", "相册"],
"执行", "返回", "加参", "减参", "克隆", "删除"],

View File

@ -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: [],
})

View File

@ -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 {
// 独立模块

246
style.css Normal file
View File

@ -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;
}