mirror of
https://shylinux.com/x/volcanos
synced 2025-04-25 08:48:06 +08:00
opt app
This commit is contained in:
parent
3ca7d99f9c
commit
44ea7eeb88
74
frame.js
74
frame.js
@ -1,46 +1,49 @@
|
||||
var can = Volcanos("chat", {
|
||||
Page: shy("构造网页", function(can, name, conf, cb, body) {
|
||||
var page = Volcanos(name, {_type: "local",
|
||||
var page = Volcanos(name, {_type: "local", _panes: {}, target: body,
|
||||
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
|
||||
|
||||
Report: function(event, value, key) {
|
||||
page.Import && page.Import(event, value, key)
|
||||
can.core.Item(page.panes, function(index, item) {
|
||||
item.Import && item.Import(event, value, key)
|
||||
})
|
||||
},
|
||||
Import: function(event, value, key) {var cb = page.onimport[key];
|
||||
typeof cb == "function" && cb(event, page, value, key, body);
|
||||
},
|
||||
Report: function(event, value, key) {
|
||||
page.Import && page.Import(event, value, key)
|
||||
can.core.Item(page._panes, function(index, item) {
|
||||
item.Import && item.Import(event, value, key)
|
||||
})
|
||||
},
|
||||
|
||||
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,
|
||||
}, Config.libs.concat(["page/"+name]), function(page) {
|
||||
page.onimport._init && page.onimport._init(page, page.Conf(conf), body)
|
||||
|
||||
can.core.Next(conf.pane, function(item, cb) {
|
||||
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+" "+(item.pos||""), item))
|
||||
}, function() {typeof cb == "function" && cb(page)})
|
||||
}, conf)
|
||||
return page.target = body, page
|
||||
return page
|
||||
}),
|
||||
Pane: shy("构造面板", function(can, name, meta, cb, field) {
|
||||
var river = "", storm = "";
|
||||
|
||||
var pane = Volcanos(name, {_type: "local", target: field,
|
||||
var pane = Volcanos(name, {_type: "local", _plugins: [], target: field,
|
||||
option: field.querySelector("form.option"),
|
||||
action: field.querySelector("div.action"),
|
||||
output: field.querySelector("div.output"),
|
||||
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
|
||||
_plugins: [],
|
||||
|
||||
Export: function(event, value, key) {can.Report(event, value, key)},
|
||||
Import: function(event, value, key) {var cb = pane.onimport[key];
|
||||
typeof cb == "function" && cb(event, pane, value, key, pane.output);
|
||||
can.core.List(pane._plugins, function(item) {item.Import(event, value, key)})
|
||||
pane.page.Select(pane, pane.action, "input."+key, function(item) {
|
||||
item.value = value
|
||||
})
|
||||
pane.page.Select(pane, pane.action, "input."+key, function(item) {item.value = value})
|
||||
},
|
||||
Action: function(key, value) {
|
||||
return can.page.Select(can, pane.action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) {
|
||||
value != undefined && (item.value = value), value = item.value
|
||||
}), value
|
||||
},
|
||||
|
||||
Size: function(event, width, height) {var cb = pane.onimport["size"];
|
||||
@ -95,14 +98,7 @@ var can = Volcanos("chat", {
|
||||
can.run(event, pane.option.dataset, cmds, cb)
|
||||
return msg
|
||||
},
|
||||
}, Config.libs.concat(["pane/"+name]), function(pane) {
|
||||
can.Dream(document.head, "pane/"+name+".css")
|
||||
function deal(event, value) {
|
||||
typeof pane.onaction[value] == "function" && pane.onaction[value](event, pane, meta, value, pane.output)
|
||||
}
|
||||
can.page.Append(can, pane.action, can.core.List(pane.onaction.list, function(line) {
|
||||
return typeof line == "string"? {button: [line, deal]}: line.length > 0? {select: [line, deal]}: line
|
||||
}))
|
||||
}, 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)
|
||||
typeof cb == "function" && cb(pane)
|
||||
}, meta)
|
||||
@ -120,9 +116,7 @@ var can = Volcanos("chat", {
|
||||
var feature = JSON.parse(meta.feature||'{}');
|
||||
var exports = JSON.parse(meta.exports||'""')||feature.exports||[];
|
||||
var plugin = Volcanos(name, {_type: "local", target: field,
|
||||
option: field.querySelector("form.option"),
|
||||
action: field.querySelector("div.action"),
|
||||
output: field.querySelector("div.output"),
|
||||
option: option, action: action, output: output,
|
||||
Inputs: can.Inputs, Output: can.Output,
|
||||
|
||||
Import: function(event, value, key) {var cb = plugin.onimport[key];
|
||||
@ -231,6 +225,7 @@ var can = Volcanos("chat", {
|
||||
typeof cb == "function" && cb(plugin)
|
||||
})
|
||||
}, meta)
|
||||
field.Check = plugin.Check
|
||||
return plugin
|
||||
}),
|
||||
Inputs: shy("构造控件", function(can, item, type, name, value, cb, option) {
|
||||
@ -243,14 +238,14 @@ var can = Volcanos("chat", {
|
||||
},
|
||||
Append: function(event, value) {can.Append(null, function(input) {can.Select(event, input.target, true)})},
|
||||
Clone: function(event, value) {can.Clone(event, function(input) {input.Select(event, null, true)})},
|
||||
run: function(event, cmd, cb, silent) {
|
||||
run: function(event, cmd, cb, silent) {var msg = can.Event(event);
|
||||
msg.Option("_action", item.name);
|
||||
(input[item.cb] || can[item.cb] || can.Check)(event, event.target, cb);
|
||||
},
|
||||
|
||||
}, Config.libs.concat(["plugin/"+type]), function(input) {
|
||||
var target = input.onimport.init(input, item, name, value, option);
|
||||
input.target = target, target.Input = input;
|
||||
|
||||
typeof cb == "function" && cb(input);
|
||||
})
|
||||
return input
|
||||
@ -263,16 +258,14 @@ var can = Volcanos("chat", {
|
||||
typeof cb == "function" && cb(event, output, value, key, target);
|
||||
},
|
||||
Option: function(key, value) {
|
||||
can.page.Select(can, can.option, "input[name="+key+"],select[name="+key+"]", function(item) {
|
||||
return can.page.Select(can, can.option, "input[name="+key+"],select[name="+key+"]", function(item) {
|
||||
value != undefined && (item.value = value), value = item.value
|
||||
})
|
||||
return value
|
||||
}), value
|
||||
},
|
||||
Action: function(key, value) {
|
||||
can.page.Select(can, can.action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) {
|
||||
return can.page.Select(can, can.action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) {
|
||||
value != undefined && (item.value = value), value = item.value
|
||||
})
|
||||
return value
|
||||
}), value
|
||||
},
|
||||
Status: function(event, value, key) {var cb = output.onstatus[key];
|
||||
typeof cb == "function"? cb(event, output, value, key, can.page.Select(can, status, "div."+key)[0]): false && output.run(event, ["status", key, value], function(msg) {
|
||||
@ -297,8 +290,11 @@ var can = Volcanos("chat", {
|
||||
}),
|
||||
}, Config.libs.concat(Config.list), function(can) {
|
||||
can[Config.main] = can.Page(can, Config.main, Config, function(chat) {
|
||||
chat.Login.Export(event||{}, can.user.Search(can, "layout")||Config.layout.def, "layout")
|
||||
chat.Login.Import(event||{}, "", "login")
|
||||
can.user.Search(can, "you") && can.user.title(can.user.Search(can, "you"))
|
||||
chat.Import(event||{}, can.user.Search(can, "layout")||Config.layout.def, "layout")
|
||||
can.user.title(can.user.Search(can, "you")||Config.title)
|
||||
can.user.login(function(user) {
|
||||
chat.River.Import(event||{}, "update", "river")
|
||||
chat.Header.Import(event||{}, user.name, "username")
|
||||
})
|
||||
}, document.body)
|
||||
})
|
||||
|
@ -8,7 +8,6 @@
|
||||
<link rel="stylesheet" type="text/css" href="/static/volcanos/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script src="/static/volcanos/lib/wasm.js"></script>
|
||||
<script src="/static/volcanos/proto.js"></script>
|
||||
<script src="/static/volcanos/order.js"></script>
|
||||
<script src="/static/volcanos/frame.js"></script>
|
||||
|
19
lib/core.js
19
lib/core.js
@ -1,5 +1,22 @@
|
||||
Volcanos("core", {help: "核心模块",
|
||||
List: shy("迭代器", function(obj, cb, interval, cbs) {obj = typeof obj == "string"? [obj]: (obj || [])
|
||||
List: shy("迭代器", function(obj, cb, interval, cbs) {
|
||||
if (typeof obj == "number") {
|
||||
var begin = 0, end = obj, step = 1;
|
||||
if (typeof interval == "number") {
|
||||
step = interval
|
||||
}
|
||||
if (typeof cb == "number") {
|
||||
begin = obj, end = cb;
|
||||
}
|
||||
|
||||
var list = []
|
||||
for (var i = begin; i < end; i += step) {
|
||||
list.push(i)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
obj = typeof obj == "string"? [obj]: (obj || [])
|
||||
if (interval > 0) {
|
||||
function loop(i) {if (i >= obj.length) {return typeof cbs == "function" && cbs(obj)}
|
||||
typeof cb == "function" && cb(obj[i], i, obj), setTimeout(function() {loop(i+1)}, interval);
|
||||
|
12
lib/misc.js
12
lib/misc.js
@ -36,7 +36,7 @@ Volcanos("misc", {help: "工具模块",
|
||||
Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmd, cb) {
|
||||
var msg = can.Event(event)
|
||||
|
||||
var option = {"cmds": cmd}
|
||||
var option = {"cmds": cmd||msg.cmd}
|
||||
msg.option && msg.option.forEach(function(item) {
|
||||
msg[item] && (option[item] = msg[item])
|
||||
})
|
||||
@ -56,15 +56,13 @@ Volcanos("misc", {help: "工具模块",
|
||||
// kit.Log(msg.detail.concat([msg]))
|
||||
|
||||
// kit.History("run", -1, option)
|
||||
this.POST(can, msg, can.Conf("context")+dataset.names.toLowerCase(), option, function(msg) {
|
||||
this.POST(can, msg, can.Conf("iceberg")+(dataset.names||msg.names).toLowerCase(), option, function(msg) {
|
||||
// kit.Log("run", what, "result", msg.result? msg.result[0]: "", msg)
|
||||
typeof cb == "function" && cb(msg)
|
||||
}), delete(event.msg)
|
||||
}),
|
||||
WSS: shy("请求后端", {order: 0}, function(can, cb, onerror, onclose, onopen) {var meta = arguments.callee.meta
|
||||
can._socket = new WebSocket(location.protocol.replace("http", "ws")+"//"+location.host+"/space/?"+can.base.Args({
|
||||
node: "active", name: can._share||"", user: can._username||"", share: can._share||"",
|
||||
}))
|
||||
WSS: shy("请求后端", {order: 0}, function(can, url, args, cb, onopen, onerror, onclose) {var meta = arguments.callee.meta
|
||||
can._socket = new WebSocket(url+"?"+can.base.Args(args))
|
||||
|
||||
var timer = can.Timer(30000, function() {
|
||||
can._socket.send("{}")
|
||||
@ -74,7 +72,7 @@ Volcanos("misc", {help: "工具模块",
|
||||
}, can._socket.onclose = onclose || function() {
|
||||
timer.stop = true, can.user.toast("wss redial")
|
||||
can.Log("wss", "close"), delete(can._socket), setTimeout(function() {
|
||||
can.misc.WSS(can, cb, onerror, onclose, onopen)
|
||||
can.misc.WSS(can, url, args, cb, onerror, onclose, onopen)
|
||||
}, 1000)
|
||||
}, can._socket.onopen = onopen
|
||||
can._socket.onmessage = function(event) {var order = ++meta.order
|
||||
|
@ -195,6 +195,7 @@ Volcanos("page", {help: "网页模块",
|
||||
{view: ["action"]}, {view: ["output"]}, {view: ["status"]},
|
||||
// {view: ["border-bottom"]},
|
||||
]}]).first;
|
||||
field.Meta = item
|
||||
return field;
|
||||
}),
|
||||
AppendTable: shy("添加表格", function(can, target, msg, list, cb, cbs) {
|
||||
@ -260,7 +261,7 @@ Volcanos("page", {help: "网页模块",
|
||||
},
|
||||
|
||||
AppendAction: shy("添加控件", function(can, action, list, cb) {
|
||||
can.page.Append(can, action, can.core.List(list, function(line) {
|
||||
return can.page.Append(can, action, can.core.List(list, function(line) {
|
||||
return typeof line == "string"? {button: [line, cb]}: line.length > 0? {select: [line, cb]}: line
|
||||
}))
|
||||
}),
|
||||
|
@ -7,6 +7,8 @@ Volcanos("user", {help: "用户模块",
|
||||
|
||||
toast: function(text) {},
|
||||
carte: function(event, cb) {},
|
||||
login: function(cb) {},
|
||||
share: function(cb) {},
|
||||
|
||||
Share: shy("共享链接", function(can, objs, clear) {var obj = objs || {}; var path = location.pathname;
|
||||
obj.path && (path = obj.path, delete(obj.path))
|
||||
|
17
manifest.json
Normal file
17
manifest.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "volcanos",
|
||||
"version": "0.0.1",
|
||||
"background": {"page": "plugin/chrome/chrome.html"},
|
||||
"browser_action": {"default_popup": "plugin/chrome/popup.html"},
|
||||
"content_scripts": [],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"history",
|
||||
"cookies",
|
||||
"bookmarks",
|
||||
"notifications",
|
||||
"*://localhost/*",
|
||||
"*://localhost:9020/*"
|
||||
]
|
||||
}
|
9
order.js
9
order.js
@ -1,4 +1,5 @@
|
||||
var Config = {context: "/chat/",
|
||||
var Config = {iceberg: "/chat/", volcano: "/static/volcanos/",
|
||||
libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"],
|
||||
main: "chat", list: ["page/chat",
|
||||
"pane/Toast", "pane/Tutor", "pane/Debug",
|
||||
"pane/Carte", "pane/Favor", "pane/Login",
|
||||
@ -9,9 +10,7 @@ var Config = {context: "/chat/",
|
||||
"pane/Footer",
|
||||
|
||||
"plugin/state", "plugin/input", "plugin/table", "plugin/inner", "plugin/media",
|
||||
],
|
||||
libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"],
|
||||
pane: [
|
||||
], pane: [
|
||||
{group: "index", name: "Toast", pos: "dialog", duration: 3000},
|
||||
{group: "index", name: "Tutor", pos: "dialog"},
|
||||
{group: "index", name: "Debug", pos: "dialog"},
|
||||
@ -30,7 +29,7 @@ var Config = {context: "/chat/",
|
||||
{group: "index", name: "Action", pos: "bottom"},
|
||||
{group: "index", name: "Footer", pos: "foot", state: ["ntxt", "ncmd"], title: '<a href="mailto:shylinux@163.com">shylinux@163.com</a>'},
|
||||
|
||||
], layout: {def: "办公", list: ["工作", "办公", "聊天"], size: {
|
||||
], title: "volcanos", layout: {def: "办公", list: ["工作", "办公", "聊天"], size: {
|
||||
"最大": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
|
||||
"工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0},
|
||||
"办公": {head: 30, foot: 30, left: 100, right: 100, bottom: -1, center: 0, top: 0},
|
||||
|
@ -21,6 +21,9 @@ Volcanos("onaction", {help: "组件交互", list: [],
|
||||
can.Action.escape && can.Action.escape(event)
|
||||
break
|
||||
case " ":
|
||||
if (event.target.getAttribute("contenteditable")) {
|
||||
break
|
||||
}
|
||||
if (event.target.tagName == "INPUT" || event.target.tagName == "TEXTAREA") {
|
||||
break
|
||||
}
|
||||
|
128
pane/Action.js
128
pane/Action.js
@ -4,76 +4,137 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
input.value = can.user.Search(can, input.name) || ""
|
||||
})
|
||||
},
|
||||
init: function(event, can, msg, cmd, output) {output.innerHTML = "";
|
||||
init: function(event, can, msg, cmd, target) {can.output.innerHTML = "";
|
||||
msg.Table(function(item, index) {if (!item.name) {return}
|
||||
can._plugins.push(can[item.name] = can.Plugin(can, item.name, item, function(event, cmds, cbs) {
|
||||
can.run(event, [item.river, item.storm, item.action].concat(cmds), cbs)
|
||||
}, can.page.AppendField(can, output, "item "+item.group+" "+item.name, item)))
|
||||
}, can.page.AppendField(can, can.output, "item "+item.group+" "+item.name, item)))
|
||||
})
|
||||
|
||||
},
|
||||
size: function(event, can, value, cmd, output) {
|
||||
},
|
||||
layout: function(event, can, value, cmd, output) {can.layout = value;
|
||||
layout: function(event, can, value, cmd, target) {can.layout = value;
|
||||
can.page.Select(can, can.action, "select.layout", function(item) {
|
||||
item.value = value
|
||||
})
|
||||
},
|
||||
scroll: function(event, can, value, cmd, output) {can.layout = value;
|
||||
output.parentElement.scrollBy(value.x, value.y)
|
||||
scroll: function(event, can, value, cmd, target) {can.layout = value;
|
||||
can.output.parentElement.scrollBy(value.x, value.y)
|
||||
},
|
||||
river: function(event, can, value, cmd, output) {
|
||||
river: function(event, can, value, cmd, target) {
|
||||
if (value == "update") {return}
|
||||
can.Conf("temp_river", value)
|
||||
},
|
||||
you: function(event, can, value, cmd, output) {
|
||||
you: function(event, can, value, cmd, target) {
|
||||
can.user.title(value)
|
||||
},
|
||||
storm: function(event, can, value, cmd, output) {
|
||||
can.Cache(can.Conf("river")+"."+can.Conf("storm"), output, "some");
|
||||
storm: function(event, can, value, cmd, target) {
|
||||
can.Cache(can.Conf("river")+"."+can.Conf("storm"), can.output, "some");
|
||||
|
||||
can.Conf("river", can.Conf("temp_river"))
|
||||
can.Conf("storm", value)
|
||||
if (!can.Cache(can.Conf("river")+"."+can.Conf("storm"), output)) {
|
||||
if (!can.Cache(can.Conf("river")+"."+can.Conf("storm"), can.output)) {
|
||||
can.run(event, [can.Conf("river"), can.Conf("storm")], function(msg) {
|
||||
can.onimport.init(event, can, msg, cmd, output)
|
||||
can.onimport.init(event, can, msg, cmd, can.output)
|
||||
})
|
||||
}
|
||||
},
|
||||
favor: function(event, can, msg, cmd, output) {var key = msg.detail[0];
|
||||
favor: function(event, can, msg, cmd, target) {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 cb = can.onaction[key]; if (typeof cb == "function") {cb(event, can, msg, cmd, can.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, can.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", "最大", "工作", "办公", "聊天"], "清屏", "刷新", "串行", "并行",
|
||||
Volcanos("onaction", {help: "组件交互", list: [["layout", "最大", "工作", "办公", "聊天"], "刷新", "清屏", "并行","串行",
|
||||
["action", "正常", "编辑", "编排", "定位"],
|
||||
{input: "pod"}, {input: "you"}, {input: "hot"}, {input: "top"},
|
||||
],
|
||||
onmousemove: function(event, can, msg, cmd, output) {
|
||||
onmousemove: function(event, can, msg, cmd, target) {
|
||||
can.resize && can.resize(event)
|
||||
},
|
||||
layout: function(event, can, value, cmd, output) {
|
||||
action: function(event, can, value, cmd, target) {
|
||||
switch (value) {
|
||||
case "正常":
|
||||
can.page.Select(can, target, "fieldset.item", function(item) {
|
||||
item.setAttribute("draggable", false)
|
||||
})
|
||||
break
|
||||
case "编排":
|
||||
can.page.Select(can, target, "fieldset.item", function(item) {
|
||||
item.setAttribute("draggable", true)
|
||||
item.ondragstart = function(event) {can.drag = event.target}
|
||||
item.ondragover = function(event) {event.preventDefault()}
|
||||
item.ondrop = function(event) {event.preventDefault()
|
||||
item.parentNode.insertBefore(can.drag, item)
|
||||
}
|
||||
})
|
||||
break
|
||||
case "定位":
|
||||
var max = 0;
|
||||
var current, begin;
|
||||
can.page.Select(can, target, "fieldset.item", function(item) {
|
||||
item.style.left = item.offsetLeft + "px"
|
||||
item.style.top = item.offsetTop + "px"
|
||||
})
|
||||
can.page.Select(can, target, "fieldset.item", function(item) {
|
||||
item.style.position = "absolute"
|
||||
item.onmousedown = function(event) {
|
||||
if (can.Action("action") != "定位") {return}
|
||||
|
||||
if (current) {
|
||||
current.style.left = event.clientX - begin.x + begin.left + "px"
|
||||
current.style.top = event.clientY - begin.y + begin.top + "px"
|
||||
current = null;
|
||||
return
|
||||
}
|
||||
current = event.target;
|
||||
current.style["z-index"] = max = max + 1
|
||||
begin = {x: event.clientX, y: event.clientY, left: item.offsetLeft, top: item.offsetTop}
|
||||
};
|
||||
target.onmousemove = item.onmousemove = function(event) {if (!current) {return}
|
||||
current.style.left = event.clientX - begin.x + begin.left + "px"
|
||||
current.style.top = event.clientY - begin.y + begin.top + "px"
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
},
|
||||
layout: function(event, can, value, cmd, target) {
|
||||
can.Export(event, value, cmd)
|
||||
},
|
||||
"清屏": function(event, can, msg, cmd, output) {
|
||||
can.page.Select(can, output, "fieldset.item>div.output", function(item) {
|
||||
item.innerHTML = "";
|
||||
})
|
||||
},
|
||||
"刷新": function(event, can, msg, cmd, output) {
|
||||
can.page.Select(can, output, "fieldset.item>div.output", function(item) {
|
||||
"刷新": function(event, can, msg, cmd, target) {
|
||||
can.page.Select(can, can.output, "fieldset.item>div.output", function(item) {
|
||||
item.innerHTML = "";
|
||||
})
|
||||
can.run(event, [can.Conf("river"), can.Conf("storm")], function(msg) {
|
||||
can.onimport.init(event, can, msg, cmd, output)
|
||||
can.onimport.init(event, can, msg, cmd, can.output)
|
||||
})
|
||||
},
|
||||
"清屏": function(event, can, msg, cmd, target) {
|
||||
can.page.Select(can, can.output, "fieldset.item>div.output", function(item) {
|
||||
item.innerHTML = "";
|
||||
})
|
||||
},
|
||||
"并行": function(event, can, msg, cmd, target) {
|
||||
can.page.Select(can, target, "fieldset.item", function(field) {
|
||||
can.page.Select(can, field, "input[type=button]", function(input, index) {
|
||||
index == 0 && field.Check(event, input, function() {})
|
||||
})
|
||||
})
|
||||
},
|
||||
"串行": function(event, can, msg, cmd, target) {
|
||||
can.core.Next(can.page.Select(can, target, "fieldset.item", function(field) {
|
||||
return field
|
||||
}), function(field, cb) {
|
||||
can.page.Select(can, field, "input[type=button]", function(input, index) {
|
||||
index == 0 && field.Check(event, input, cb)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件菜单", list: [["layout", "工作", "办公", "聊天"]],
|
||||
Volcanos("onchoice", {help: "组件菜单", list: [["layout", "工作", "办公", "聊天"], "保存"],
|
||||
"工作": function(event, can, msg, cmd, target) {
|
||||
can.Export(event, cmd, "layout")
|
||||
},
|
||||
@ -83,6 +144,15 @@ Volcanos("onchoice", {help: "组件菜单", list: [["layout", "工作", "办公"
|
||||
"聊天": function(event, can, msg, cmd, target) {
|
||||
can.Export(event, cmd, "layout")
|
||||
},
|
||||
"保存": function(event, can, msg, cmd, target) {
|
||||
var list = []
|
||||
can.page.Select(can, target, "fieldset", function(item) {var meta = item.Meta
|
||||
list.push(meta.node||"", meta.group, meta.index, meta.index)
|
||||
})
|
||||
can.run(event, [can.Conf("river"), can.Conf("storm"), "save"].concat(list), function(msg) {
|
||||
can.user.toast("保存成功")
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("ondetail", {help: "组件详情", list: []})
|
||||
Volcanos("onexport", {help: "导出数据", list: []})
|
||||
|
@ -2,11 +2,13 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_init: function(can, conf, output, action, option, field) {output.innerHTML = "";
|
||||
conf.title && can.page.Append(can, output, [{view: "title",
|
||||
list: [{text: conf.title, className: "title"}], click: function(event) {can.onexport.title(event, can)}}])
|
||||
|
||||
can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(conf.state, function(item) {
|
||||
return {text: conf[item]||"", className: item, click: function(event) {var cb = can.onexport[item];
|
||||
typeof cb == "function" && cb(event, can, item, item, output)
|
||||
}};
|
||||
})}])
|
||||
|
||||
can.timer = can.Timer({interval: 1000, length: -1}, function() {
|
||||
can.ui.time.innerHTML = can.base.Time().split(" ")[1]
|
||||
})
|
||||
|
@ -1,6 +1,19 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_init: function(can, conf, output, action, option, field) {
|
||||
var ui = can.page.Appends(can, option, [
|
||||
can.user.login = function(cb) {
|
||||
can.user.Cookie("sessid")? can.onaction.check(event, can, cb, "check", output):
|
||||
can.onaction.login(event, can, cb, "login", output)
|
||||
}
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "组件交互", list: [],
|
||||
check: function(event, can, cb, cmd, target) {
|
||||
can.run(event||{}, ["check"], function(msg) {var user = msg.nickname && msg.nickname[0] || msg.Result()
|
||||
user? typeof cb == "function" && cb({name: user}): can.onaction.login(event, can, cb, "login", target)
|
||||
})
|
||||
},
|
||||
login: function(event, can, cb, cmd, target) {
|
||||
var ui = can.page.Appends(can, target, [
|
||||
{text: ["账号: ", "label"]}, {username: []}, {type: "br"},
|
||||
{text: ["密码: ", "label"]}, {password: []}, {type: "br"},
|
||||
{button: ["密码登录", function(event, cmd) {
|
||||
@ -9,17 +22,14 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
|
||||
can.run(event, ["login", 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("用户或密码错误")
|
||||
can.Hide(), can.onaction.check(event, can, cb, "check", target)
|
||||
return
|
||||
}
|
||||
can.user.toast("用户或密码错误")
|
||||
})
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
return true
|
||||
}]},
|
||||
{button: ["扫码登录", function(event, cmd) {
|
||||
can.onimport.username(event, can, "", function(event, msg) {
|
||||
can.onaction.socket(event, can, "", function(event, msg) {
|
||||
switch (msg.detail[0]) {
|
||||
case "space":
|
||||
if (msg.detail[1] == "share") {can._share = msg.detail[2]
|
||||
@ -31,19 +41,18 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
break
|
||||
case "sessid":
|
||||
can.user.Cookie(can, "sessid", msg.detail[1])
|
||||
can.Hide(), can.Export(event, "", "login")
|
||||
can.Hide(), typeof cb == "function" && cb({name: user})
|
||||
can.user.toast("")
|
||||
return true
|
||||
}
|
||||
})
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
return true
|
||||
}]},
|
||||
{type: "br"},
|
||||
])
|
||||
can.Show(event, -1, -1)
|
||||
},
|
||||
username: function(event, can, value, cmd, output) {can._username = value
|
||||
socket: function(event, can, value, cmd, output) {can._username = value
|
||||
// location.protocol.replace("http", "ws")+"//"+location.host+"/space/?"+
|
||||
return can._socket = can._socket || can.misc.WSS(can, function(event, msg) {
|
||||
if (msg.Option("_handle")) {return can.user.toast(msg.result.join(""))}
|
||||
if (typeof cmd == "function" && cmd(event, msg)) {return msg.Reply(msg)}
|
||||
@ -55,14 +64,7 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
msg.Reply(msg)
|
||||
})
|
||||
},
|
||||
login: function(event, can, value, cmd, output) {
|
||||
if (!can.user.Cookie("sessid")) {can.Show(event, 400, 400); return}
|
||||
can.run(event||{}, ["check"], function(msg) {var user = msg.nickname && msg.nickname[0] || msg.Result()
|
||||
user? can.Export(event, user, "username"): can.Show(event, -1, -1)
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "组件交互", list: []})
|
||||
Volcanos("onchoice", {help: "组件菜单", list: []})
|
||||
Volcanos("ondetail", {help: "组件详情", list: []})
|
||||
Volcanos("onexport", {help: "导出数据", list: []})
|
||||
|
@ -1,21 +1,16 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_init: function(can, conf, output, action, option, field) {
|
||||
},
|
||||
init: function(event, can, msg, key, output) {output.innerHTML = "";
|
||||
can.page.AppendItem(can, output, msg.Table(), can.user.Search(can, "river"), function(event, line, item) {
|
||||
can.Export(event, line.key, "river")
|
||||
})
|
||||
},
|
||||
username: function(event, can, value, key, output) {
|
||||
river: function(event, can, value, key, output) {if (value == "update") {
|
||||
can.run(event, [], function(msg) {
|
||||
can.onimport.init(event, can, msg, key, output)
|
||||
})
|
||||
},
|
||||
river: function(event, can, value, key, output) {
|
||||
if (value == "update") {
|
||||
can.run(event, [], function(msg) {
|
||||
can.onimport.init(event, can, msg, key, 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}
|
||||
@ -34,23 +29,18 @@ Volcanos("onaction", {help: "组件交互", list: ["创建", "刷新"],
|
||||
can.Export(event, "create", "ocean")
|
||||
},
|
||||
"刷新": function(event, can, meta, key, output) {
|
||||
can.run(event, [], function(msg) {
|
||||
can.onimport.init(event, can, msg, key, output)
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件菜单", list: ["创建", "刷新"],
|
||||
"创建": function(event, can, msg, key, target) {
|
||||
can.Export(event, "create", "ocean")
|
||||
},
|
||||
"刷新": function(event, can, msg, key, target) {
|
||||
can.onaction[key](event, can, key, can.output)
|
||||
can.Import(event, "update", "river")
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件菜单", list: ["创建", "刷新"]})
|
||||
Volcanos("ondetail", {help: "组件详情", list: ["共享"],
|
||||
"共享": function(event, can, line, key, target) {
|
||||
can.Export(event, "river", "share")
|
||||
},
|
||||
})
|
||||
Volcanos("onexport", {help: "导出数据", list: [],
|
||||
share: function(event, can, line, key, target) {
|
||||
can.user.toast(can.user.Share(can, {river: line.key}), "共享链接", 10000)
|
||||
},
|
||||
})
|
||||
Volcanos("onexport", {help: "导出数据", list: []})
|
||||
|
||||
|
13
plugin/chrome/chrome.html
Normal file
13
plugin/chrome/chrome.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script src="/proto.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="chrome.js"></script>
|
||||
</body>
|
||||
<html>
|
||||
|
142
plugin/chrome/chrome.js
Normal file
142
plugin/chrome/chrome.js
Normal file
@ -0,0 +1,142 @@
|
||||
var can = Volcanos("chrome", {
|
||||
_send: function(msg, cb) {chrome.extension.sendRequest(msg, cb)},
|
||||
_open: function(url) {chrome.windows.create({url: url})},
|
||||
|
||||
run: function(can, msg, cb) {
|
||||
can.misc.Run({names: "chrome", msg: msg}, can, {}, null, cb)
|
||||
},
|
||||
|
||||
open: function(msg, cmd, cb) {
|
||||
chrome.windows.create({url: cmd[0]})
|
||||
typeof cb == "function" && cb(msg)
|
||||
},
|
||||
wins: function(msg, cmd, cb) {
|
||||
if (cmd.length == 0) {
|
||||
// 窗口列表
|
||||
chrome.windows.getAll(function(wins) {
|
||||
can.core.List(wins, function(win) {win.wid = win.id
|
||||
msg.Push(win, ["wid", "state", "left", "top", "width", "height"])
|
||||
})
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (cmd.length > 1) {
|
||||
// 新建标签
|
||||
chrome.tabs.create({windowId: parseInt(cmd[0]), url: cmd[1], selected: false}, function() {
|
||||
can.wins(msg, [cmd[0]], cb)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 标签列表
|
||||
chrome.tabs.getAllInWindow(parseInt(cmd[0]), function(tabs) {
|
||||
can.core.List(tabs, function(tab) {tab.tid = tab.id
|
||||
msg.Push(tab, ["tid", "active", "width", "height", "index", "title", "url"])
|
||||
})
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
},
|
||||
tabs: function(msg, cmd, cb) {
|
||||
if (cmd.length == 0) {
|
||||
chrome.tabs.getAllInWindow(function(tabs) {
|
||||
can.core.List(tabs, function(tab) {
|
||||
msg.Push("id", tab.id)
|
||||
msg.Push("active", tab.active)
|
||||
msg.Push("index", tab.index)
|
||||
msg.Push("title", tab.title)
|
||||
msg.Push("url", tab.url)
|
||||
})
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
chrome.tabs[cmd[1]](parseInt(cmd[0]), cb)
|
||||
},
|
||||
cookie: function(msg, cmd, cb) {
|
||||
if (cmd[0] == "modify") {var data = {}; data[cmd[1]] = cmd[2]
|
||||
chrome.bookmarks.update(cmd[4], data, function() {
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
} else if (cmd[0] == "delete") {
|
||||
chrome.bookmarks.remove(cmd[2], function() {
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
} else if (cmd.length > 2) {
|
||||
chrome.bookmarks.create({parentId: cmd[0], url: cmd[1], title: cmd[2], index: cmd[3]||0}, cb)
|
||||
}
|
||||
|
||||
chrome.cookies.getAll({name: ""}, function(cs) {
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
},
|
||||
history: function(msg, cmd, cb) {
|
||||
chrome.tabs.getAllInWindow(function(tabs) {
|
||||
can.core.List(tabs, function(tab) {
|
||||
msg.Push("id", tab.id)
|
||||
msg.Push("active", tab.active)
|
||||
msg.Push("index", tab.index)
|
||||
msg.Push("title", tab.title)
|
||||
msg.Push("url", tab.url)
|
||||
})
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
},
|
||||
bookmark: function(msg, cmd, cb) {
|
||||
if (cmd[0] == "modify") {var data = {}; data[cmd[1]] = cmd[2]
|
||||
chrome.bookmarks.update(cmd[4], data, function() {
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
} else if (cmd[0] == "delete") {
|
||||
chrome.bookmarks.remove(cmd[2], function() {
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
return
|
||||
} else if (cmd.length > 2) {
|
||||
chrome.bookmarks.create({parentId: cmd[0], url: cmd[1], title: cmd[2], index: cmd[3]||0}, cb)
|
||||
}
|
||||
|
||||
chrome.bookmarks.getSubTree(cmd[0]||"0", function(labs) {
|
||||
for (var i = 0; i < labs.length; i++) {labs[i].pid = labs[i].parentId
|
||||
msg.Push("time", can.base.Time(labs[i].dateAdded))
|
||||
msg.Push(labs[i], ["pid", "id", "index", "title", "url"])
|
||||
labs = labs.concat(labs[i].children||[])
|
||||
}
|
||||
typeof cb == "function" && cb(msg)
|
||||
})
|
||||
},
|
||||
}, Config.libs.concat(Config.list), function(can) {can.Conf(Config)
|
||||
can.user.toast = function(message, title) {chrome.notifications.create(null, {
|
||||
message: message, title: title||Config.title, iconUrl: "/favicon.ico", type: "basic",
|
||||
})},
|
||||
|
||||
can.socket = can.socket || can.misc.WSS(can, "ws://localhost:9020/space/", {node: "chrome", name: chrome.runtime.id}, function(event, msg) {
|
||||
if (msg.Option("_handle")) {return can.user.toast(msg.result.join(""))}
|
||||
|
||||
can.user.toast(msg.detail.join(" "))
|
||||
switch (msg.detail[0]) {
|
||||
case "space": can._share = msg.detail[2]; break
|
||||
case "pwd": msg.Echo("hello world"); break
|
||||
default: (can[msg.detail[0]]||can.chrome[msg.detail[0]])(msg, msg.detail.slice(1), function(msg) {
|
||||
msg.Reply(msg)
|
||||
}); return
|
||||
}
|
||||
msg.Reply(msg)
|
||||
}, function() {can.user.toast("wss connect", "iceberg")})
|
||||
|
||||
chrome.history.onVisited.addListener(function(item) {
|
||||
can.run(can, {names: "crx", cmd: ["history", item.id, item.url, item.title]}, function(msg) {
|
||||
can.user.toast(item.url, item.title)
|
||||
})
|
||||
})
|
||||
|
||||
chrome.extension.onRequest.addListener(function(msg, sender, cb) {
|
||||
can.run(can, msg, cb)
|
||||
})
|
||||
})
|
||||
|
41
plugin/chrome/config.js
Normal file
41
plugin/chrome/config.js
Normal file
@ -0,0 +1,41 @@
|
||||
var Config = {iceberg: "http://localhost:9020/chat/", volcano: "/",
|
||||
libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"],
|
||||
main: "chat", list: ["page/chat",
|
||||
"pane/Toast", "pane/Tutor", "pane/Debug",
|
||||
"pane/Carte", "pane/Favor", "pane/Login",
|
||||
|
||||
"pane/Header",
|
||||
"pane/Ocean", "pane/River", "pane/Storm", "pane/Steam",
|
||||
"pane/Target", "pane/Source", "pane/Action",
|
||||
"pane/Footer",
|
||||
|
||||
"plugin/state", "plugin/input", "plugin/table", "plugin/inner", "plugin/media",
|
||||
], pane: [
|
||||
{group: "index", name: "Toast", pos: "dialog", duration: 3000},
|
||||
{group: "index", name: "Tutor", pos: "dialog"},
|
||||
{group: "index", name: "Debug", pos: "dialog"},
|
||||
{group: "index", name: "Carte", pos: "dialog"},
|
||||
{group: "index", name: "Favor", pos: "dialog"},
|
||||
{group: "index", name: "Login", pos: "dialog"},
|
||||
|
||||
{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: "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", state: ["ntxt", "ncmd"], title: '<a href="mailto:shylinux@163.com">shylinux@163.com</a>'},
|
||||
|
||||
], title: "范晓旭", layout: {def: "办公", list: ["工作", "办公", "聊天"], size: {
|
||||
"最大": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
|
||||
"工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0},
|
||||
"办公": {head: 30, foot: 30, left: 100, right: 100, bottom: -1, center: 0, top: 0},
|
||||
"聊天": {head: 30, foot: 30, left: 100, right: 100, bottom: 300, center: 40, top: -2},
|
||||
"全屏": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
|
||||
}, border: 4,
|
||||
},
|
||||
}
|
||||
|
13
plugin/chrome/popup.html
Normal file
13
plugin/chrome/popup.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body style="min-height:400px">
|
||||
<script src="/proto.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="/frame.js"></script>
|
||||
<!-- <script src="popup.js"></script> -->
|
||||
</body>
|
||||
<html>
|
19
plugin/chrome/popup.js
Normal file
19
plugin/chrome/popup.js
Normal file
@ -0,0 +1,19 @@
|
||||
var can = Volcanos("popup", {
|
||||
demo: function() {
|
||||
can.chrome.notice("hi", "hello")
|
||||
},
|
||||
}, Config.libs.concat(Config.list), function(can) {can.Conf(Config)
|
||||
can.page.Append(can, document.body, [{button: ["baidu", function() {
|
||||
can.chrome.open("https://www.baidu.com")
|
||||
}]}])
|
||||
can.page.Append(can, document.body, [{button: ["volcanos", function() {
|
||||
can.chrome.open("http://localhost:9020")
|
||||
}]}])
|
||||
|
||||
can.page.Append(can, document.body, [{button: ["send", function() {
|
||||
can.chrome.send({names: "crx", cmds: ["hi"]}, function(msg) {
|
||||
can.chrome.notice("hi", "hello")
|
||||
console.log(msg)
|
||||
})
|
||||
}]}])
|
||||
})
|
108
plugin/input.js
108
plugin/input.js
@ -1,4 +1,6 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_begin: function(can) {},
|
||||
_start: function(can) {},
|
||||
init: shy("添加控件", function(can, item, name, value, option) {
|
||||
var input = {type: "input", name: name, data: item};
|
||||
item.type = item.type || item._type || item._input;
|
||||
@ -41,8 +43,112 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
return target.value + (target.value == "" || target.value.endsWith("/")? "": "/") + value
|
||||
},
|
||||
})
|
||||
Volcanos("onfigure", {help: "控件详情", list: [],
|
||||
date: {click: function(event, can, value, cmd, target) {if (can.date) {return}
|
||||
target.style.width = "120px"
|
||||
function set(now) {
|
||||
target.value = can.base.Time(now);
|
||||
if (can.item.action == "auto") {
|
||||
can.run({});
|
||||
}
|
||||
}
|
||||
|
||||
can.stick = false
|
||||
can.now = target.value? new Date(target.value): new Date();
|
||||
can.date = can.page.Append(can, document.body, [{view: ["date input", "fieldset"], style: {
|
||||
position: "absolute", left: event.clientX+"px", top: event.clientY+10+"px",
|
||||
}, onmouseleave: function(event) {
|
||||
if (can.stick) {can.stick = false; return}
|
||||
can.page.Remove(can, can.date); delete(can.date);
|
||||
}}]).last
|
||||
|
||||
var action = can.page.Append(can, can.date, [{view: ["action"]}]).last
|
||||
var control = can.page.AppendAction(can, action, ["今天", "随机",
|
||||
["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)), {view: ["", "br"]},
|
||||
"上一月", ["year"].concat(can.core.List(can.now.getFullYear() - 20, can.now.getFullYear() + 20)),
|
||||
["month"].concat(can.core.List(1, 13)), "下一月", {view: ["", "br"]},
|
||||
], function(event, value, cmd) {can.stick = true;
|
||||
switch (cmd) {
|
||||
case "year": can.now.setFullYear(parseInt(value)); show(can.now); return;
|
||||
case "month": can.now.setMonth(parseInt(value)-1); show(can.now); return;
|
||||
case "hour": can.now.setHours(parseInt(value)); show(can.now); set(can.now); return;
|
||||
case "minute": can.now.setMinutes(parseInt(value)); show(can.now); set(can.now); return;
|
||||
case "second": can.now.setSeconds(parseInt(value)); show(can.now); set(can.now); return;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case "今天": can.now = new Date(); show(can.now); set(can.now); break;
|
||||
case "随机": can.now.setDate((Math.random() * 100 - 50) + can.now.getDate()); show(can.now); set(can.now); break;
|
||||
case "关闭":can.page.Remove(can, can.date); delete(can.date);
|
||||
case "前一年": can.now.setFullYear(can.now.getFullYear()-1); show(can.now); break;
|
||||
case "后一年": can.now.setFullYear(can.now.getFullYear()+1); show(can.now); break;
|
||||
case "上一月": can.now.setMonth(can.now.getMonth()-1); show(can.now); break;
|
||||
case "下一月": can.now.setMonth(can.now.getMonth()+1); show(can.now); break;
|
||||
}
|
||||
})
|
||||
|
||||
var table = can.page.Append(can, can.date, [{type: "table"}]).table
|
||||
function click(event) {
|
||||
var day = new Date(parseInt(event.target.dataset.date))
|
||||
can.now = day;
|
||||
set(can.now);
|
||||
}
|
||||
function show(now) {
|
||||
control.month.value = now.getMonth()+1;
|
||||
control.year.value = now.getFullYear();
|
||||
control.hour.value = now.getHours();
|
||||
control.minute.value = parseInt(now.getMinutes()/5)*5;
|
||||
control.second.value = parseInt(now.getSeconds()/5)*5;
|
||||
var meta = ["日", "一", "二", "三", "四", "五", "六"]
|
||||
can.page.Appends(can, table, [{type: "tr", list: can.core.List(meta, function(day) {return {text: [day, "th"]}})}])
|
||||
|
||||
var one = new Date(now); one.setDate(1);
|
||||
var end = new Date(now); end.setMonth(now.getMonth()+1); end.setDate(1);
|
||||
var head = new Date(one); head.setDate(one.getDate()-one.getDay());
|
||||
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay());
|
||||
|
||||
var tr;
|
||||
function add(day, type) {
|
||||
if (day.getDay() == 0) {tr = can.page.Append(can, table, [{type: "tr"}]).tr}
|
||||
can.page.Append(can, tr, [{className: can.base.Time(day).split(" ")[0] == can.base.Time(now).split(" ")[0]? "now": type,
|
||||
text: [day.getDate(), "td"], dataset: {date: day.getTime()}, click: click,
|
||||
}])
|
||||
}
|
||||
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) {add(day, "last")}
|
||||
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")}
|
||||
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")}
|
||||
}
|
||||
|
||||
show(can.now);
|
||||
set(can.now);
|
||||
}},
|
||||
province: {click: function(event, can, value, cmd, target) {if (can.figure) {return}
|
||||
can.figure = can.page.Append(can, document.body, [{view: ["date input", "fieldset"], style: {
|
||||
position: "absolute", left: "20px", top: event.clientY+10+"px",
|
||||
}, onmouseleave: function(event) {
|
||||
can.page.Remove(can, can.figure); delete(can.figure);
|
||||
}}]).last
|
||||
|
||||
can.page.Append(can, can.figure, [{include: ["/plugin/github.com/shylinux/echarts/echarts.js", function(event) {
|
||||
can.page.Append(can, can.figure, [{include: ["/plugin/github.com/shylinux/echarts/china.js", function(event) {
|
||||
var china_chart = echarts.init(can.page.Append(can, can.figure, [{type: "div", style: {width: "600px", height: "400px"}}]).last);
|
||||
|
||||
var option = {geo: {map: 'china'}};
|
||||
china_chart.setOption(option);
|
||||
|
||||
china_chart.on('click', function (params) {
|
||||
target.value = params.name;
|
||||
});
|
||||
}]}]);
|
||||
}]}]);
|
||||
},
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "控件交互", list: [],
|
||||
onclick: function(event, can) {can.Select(event); can.item.type == "button" && can.run(event)},
|
||||
onclick: function(event, can) {can.Select(event);
|
||||
var figure = can.onfigure[can.item.figure]
|
||||
figure? figure.click(event, can, can.item, can.item.name, event.target): can.item.type == "button" && can.run(event)
|
||||
},
|
||||
onkeydown: function(event, can) {
|
||||
can.page.oninput(event, can, function(event) {
|
||||
switch (event.key) {
|
||||
|
@ -27,7 +27,8 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
var sub = can.Event(event);
|
||||
msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
|
||||
typeof cb == "function"? cb(event, can, msg, index, key, cmd, target):
|
||||
can.run(event, [id, typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
// can.run(event, [id, typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.run(event, ["action", typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.onimport.init(can, msg, cb, output, option)
|
||||
}, true)
|
||||
}))
|
||||
@ -82,7 +83,8 @@ Volcanos("ondetail", {help: "组件详情", list: ["选择", "编辑", "删除",
|
||||
if (event.key == " ") {return event.stopPropagation()}
|
||||
if (event.key != "Enter") {return}
|
||||
if (key == "value" && msg.key) {key = msg.key[index]}
|
||||
can.run(event, [msg.Ids(index), "modify", key, event.target.value, text], function(msg) {
|
||||
// can.run(event, [msg.Ids(index), "modify", key, event.target.value, text], function(msg) {
|
||||
can.run(event, ["action", "modify", key, event.target.value, text, msg.Ids(index)], function(msg) {
|
||||
td.innerHTML = event.target.value;
|
||||
can.user.toast("修改成功")
|
||||
}, true)
|
||||
|
149
plugin/team/plan.js
Normal file
149
plugin/team/plan.js
Normal file
@ -0,0 +1,149 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
|
||||
if (!msg.append || msg.append.length == 0) {
|
||||
var code = can.page.Append(can, output, [{view: ["code", "div", msg.Result()]}]).code;
|
||||
return typeof cb == "function" && cb(msg), code;
|
||||
}
|
||||
|
||||
var table = can.page.AppendTable(can, output, msg, msg.append);
|
||||
table.onclick = function(event) {switch (event.target.tagName) {
|
||||
case "TD":
|
||||
can.onimport.which(event, table, msg.append, function(index, key) {
|
||||
can.ondetail["复制"](event, can, msg, event.target.innerHTML, index, key, event.target);
|
||||
can.Export(event, event.target.innerHTML.trim(), key, index)
|
||||
})
|
||||
break
|
||||
case "TH":
|
||||
break
|
||||
case "TR":
|
||||
case "TABLE":
|
||||
}}
|
||||
table.oncontextmenu = function(event) {var target = event.target;
|
||||
switch (event.target.tagName) {
|
||||
case "TD":
|
||||
can.onimport.which(event, table, msg.append, function(index, key) {
|
||||
can.user.carte(event, shy("", can.ondetail, can.feature.detail || can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
|
||||
var id = msg.Ids(index);
|
||||
var sub = can.Event(event);
|
||||
msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
|
||||
typeof cb == "function"? cb(event, can, msg, index, key, cmd, target):
|
||||
// can.run(event, [id, typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.run(event, ["action", typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.onimport.init(can, msg, cb, output, option)
|
||||
}, true)
|
||||
}))
|
||||
})
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
break
|
||||
case "TH":
|
||||
case "TR":
|
||||
case "TABLE":
|
||||
}
|
||||
}
|
||||
|
||||
can.page.Select(can, table, "div.miss", function(item) {
|
||||
item.setAttribute("draggable", true)
|
||||
item.ondragstart = function(event) {can.drag = event.target}
|
||||
item.ondragover = function(event) {event.preventDefault()}
|
||||
item.ondrop = function(event) {event.preventDefault()
|
||||
can.preview.insertBefore(can.drag, item)
|
||||
}
|
||||
})
|
||||
|
||||
can.page.Select(can, table, "tr", function(tr) {tr.list = [];
|
||||
can.page.Select(can, tr, "td", function(item, index) {tr.list.push(item);
|
||||
// item.setAttribute("draggable", true)
|
||||
// item.ondragstart = function(event) {can.drag = event.target}
|
||||
item.ondragover = function(event) {event.preventDefault(), can.page.Select(can, table, "td.over", function(item) {
|
||||
can.page.ClassList.del(can, item, "over")
|
||||
}), can.page.ClassList.add(can, item, "over")}
|
||||
item.ondrop = function(event) {event.preventDefault()
|
||||
item.append(can.drag)
|
||||
|
||||
var data = can.drag.dataset;
|
||||
var begin_time = new Date(data.begin_time);
|
||||
begin_time.setHours(parseInt(tr.list[0].innerText));
|
||||
begin_time.setMinutes(0);
|
||||
begin_time.setSeconds(0);
|
||||
if (can.Option("scale") == "week") {
|
||||
begin_time.setDate(begin_time.getDate() - (begin_time.getDay() - index + 1))
|
||||
}
|
||||
can.run(event, ["action", "modify", "begin_time", can.base.Time(begin_time), data.begin_time, data.id, data.name], function(msg) {
|
||||
can.user.toast("修改成功")
|
||||
}, true);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return typeof cb == "function" && cb(msg), table;
|
||||
},
|
||||
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
|
||||
can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
|
||||
can.page.Select(can, tr, "th,td", function(td, order) {
|
||||
if (event.target == td) {return cb(index-1, list[order])}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
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: ["返回", "清空", "复制", "下载"],
|
||||
"返回": function(event, can, msg, cmd, target) {
|
||||
can.run(event, ["", "Last"])
|
||||
},
|
||||
"清空": 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) {msg = msg || can.msg;
|
||||
var list = can.onexport.Format(can, msg, msg._plugin_name||"data");
|
||||
can.page.Download(can, list[0]+list[1], list[2]);
|
||||
},
|
||||
})
|
||||
Volcanos("ondetail", {help: "组件详情", list: ["选择", "编辑", "删除", "复制", "下载"],
|
||||
"选择": "select",
|
||||
"删除": "delete",
|
||||
"编辑": function(event, can, msg, index, key, cmd, td) {
|
||||
var text = td.innerHTML;
|
||||
var input = can.page.Appends(can, td, [{type: "input", value: text, style: {width: td.clientWidth+"px"}, data: {onkeydown: function(event) {
|
||||
if (event.key == " ") {return event.stopPropagation()}
|
||||
if (event.key != "Enter") {return}
|
||||
if (key == "value" && msg.key) {key = msg.key[index]}
|
||||
// can.run(event, [msg.Ids(index), "modify", key, event.target.value, text], function(msg) {
|
||||
can.run(event, ["action", "modify", key, event.target.value, text, msg.Ids(index)], function(msg) {
|
||||
td.innerHTML = event.target.value;
|
||||
can.user.toast("修改成功")
|
||||
}, true)
|
||||
}}}]).first;
|
||||
input.focus();
|
||||
input.setSelectionRange(0, input.value.length);
|
||||
},
|
||||
"复制": function(event, can, msg, index, key, cmd, target) {
|
||||
can.user.toast(can.page.CopyText(can, target.innerHTML), "复制成功")
|
||||
},
|
||||
"下载": function(event, can, msg, index, key, cmd, target) {
|
||||
can.page.Download(can, key, target.innerHTML);
|
||||
},
|
||||
})
|
||||
Volcanos("onexport", {help: "导出数据", list: [],
|
||||
Format: function(can, msg, name) {
|
||||
var ext = ".csv", txt = can.page.Select(can, can.target, "tr", function(tr) {
|
||||
return can.page.Select(can, tr, "td,th", function(td) {return td.innerText}).join(",")
|
||||
}).join("\n");
|
||||
|
||||
!txt && (ext = ".txt", txt = msg.result && msg.result.join("") || "");
|
||||
return [name, ext, txt]
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
@ -12,11 +12,12 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
|
||||
var items = item.path.split(".");
|
||||
switch (items[items.length-1]) {
|
||||
case "png":
|
||||
case "JPG":
|
||||
return {img: "/share/local/web.wiki.feel/"+item.path, width: width, oncontextmenu: menu}
|
||||
return {className: "preview", img: "/share/local/web.wiki.feel/"+item.path, width: width, oncontextmenu: menu}
|
||||
case "MOV":
|
||||
case "m4v":
|
||||
return {type: "video", width: width, oncontextmenu: menu,
|
||||
return {className: "preview", type: "video", width: width, oncontextmenu: menu,
|
||||
onplay: cb, onpause: cb,
|
||||
onloadedmetadata: cb,
|
||||
onloadeddata: cb,
|
||||
@ -31,7 +32,7 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
var table = can.page.AppendTable(can, output, msg, msg.append);
|
||||
|
||||
var begin = 0, limit = 3;
|
||||
var rate = 1, width = 200;
|
||||
var rate = 1, width = 600;
|
||||
var control = can.page.Append(can, output, [{view: ["control"], list: [
|
||||
{select: [["width", 100, 200, 400, 600, 800], function(event, value) {width = parseInt(value), page(begin, limit)}]},
|
||||
{select: [["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10], function(event, value) {rate = value}]},
|
||||
@ -63,23 +64,27 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
page(begin, limit);
|
||||
|
||||
function show(index) {var item = list[can.page.Select(can, table, "tr")[index+1].dataset.index];
|
||||
var video;
|
||||
var video = {};
|
||||
var timer = can.user.toast({text: "", list: [{view: "control", list: [
|
||||
{button: ["close", function(event) {video.pause(), timer.toast.Hide()}]},
|
||||
{select: [["width", 100, 200, 400, 600, 800], function(event, value) {timer.toast.Show(event, parseInt(value)+20), video.width = value}]},
|
||||
{select: [["width", 100, 200, 400, 600, 800], function(event, value) {timer.toast.Show(event, parseInt(value)+20),
|
||||
width = value
|
||||
timer.toast.preview.setAttribute("width", value)
|
||||
// video.width = value
|
||||
}]},
|
||||
{select: [["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10], function(event, value) {rate = video.playbackRate = value}]},
|
||||
{button: ["prev", function(event) {show(index-1)}]},
|
||||
{text: index+"/"+list.length},
|
||||
{button: ["next", function(event) {show(index+1)}]},
|
||||
{type: "br"}, {text: item.path},
|
||||
{type: "br"}, {text: item.label},
|
||||
]}].concat([view(index, 400, true, function(event) {video = event.target;
|
||||
]}].concat([view(index, 600, true, function(event) {video = event.target;
|
||||
switch (event.type) {
|
||||
case "loadeddata": video.playbackRate = rate; break
|
||||
case "ended": show(index+1); break
|
||||
}
|
||||
})]), width: 400+20, height: 620, duration: -1})
|
||||
timer.toast.width.value = 400;
|
||||
})]), width: 600+20, height: 620, duration: -1})
|
||||
timer.toast.width.value = 600;
|
||||
timer.toast.rate.value = rate;
|
||||
}
|
||||
|
||||
@ -99,6 +104,29 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
case "TR":
|
||||
case "TABLE":
|
||||
}}
|
||||
table.oncontextmenu = function(event) {var target = event.target;
|
||||
switch (event.target.tagName) {
|
||||
case "TD":
|
||||
can.onimport.which(event, table, msg.append, function(index, key) {
|
||||
can.user.carte(event, shy("", can.ondetail, can.feature.detail || can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
|
||||
var id = msg.Ids(index);
|
||||
var sub = can.Event(event);
|
||||
msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
|
||||
typeof cb == "function"? cb(event, can, msg, index, key, cmd, target):
|
||||
// can.run(event, [id, typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.run(event, ["action", typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
|
||||
can.onimport.init(can, msg, cb, output, option)
|
||||
}, true)
|
||||
}))
|
||||
})
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
break
|
||||
case "TH":
|
||||
case "TR":
|
||||
case "TABLE":
|
||||
}
|
||||
}
|
||||
return typeof cb == "function" && cb(msg), table;
|
||||
},
|
||||
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
|
||||
@ -123,17 +151,12 @@ Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空", ["rect",
|
||||
console.log("choice", cmd)
|
||||
},
|
||||
})
|
||||
Volcanos("ondetail", {help: "组件详情", list: ["标签", "删除"],
|
||||
Volcanos("ondetail", {help: "组件详情", list: ["标签"],
|
||||
"标签": function(event, can, msg, index, key, cmd, target) {
|
||||
can.user.prompt("目标", function(kind) {
|
||||
can.run(event, ["action", "标签", msg.path, kind], function() {
|
||||
}, true)
|
||||
})
|
||||
var figure = can.onfigure[target.tagName]
|
||||
figure.copy(event, can, target)
|
||||
},
|
||||
"删除": function(event, can, msg, index, key, cmd, target) {
|
||||
can.page.Remove(can, target)
|
||||
},
|
||||
})
|
||||
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"],
|
||||
|
@ -1,13 +1,19 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_begin: function(can) {
|
||||
},
|
||||
_start: function(can) {
|
||||
can.Action("stroke-width", 2)
|
||||
can.Action("stroke", "yellow")
|
||||
can.Action("fill", "purple")
|
||||
can.Action("grid", "20")
|
||||
},
|
||||
init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
|
||||
if (msg.append && msg.append.length > 0) {
|
||||
if (msg.append && msg.append.length > 0) {action.innerHTML = "";
|
||||
var table = can.page.AppendTable(can, output, msg, msg.append);
|
||||
table.onclick = function(event) {switch (event.target.tagName) {
|
||||
case "TD":
|
||||
can.onimport.which(event, table, msg.append, function(index, key) {
|
||||
var name = event.target.innerHTML.trim()
|
||||
can.Option("name", name)
|
||||
can.run(event, [name])
|
||||
can.run(event, [can.Option("name", event.target.innerHTML.trim())])
|
||||
})
|
||||
break
|
||||
case "TH":
|
||||
@ -19,18 +25,19 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
}
|
||||
|
||||
var code = can.page.Append(can, output, [{view: ["code", "div", msg.Result()||can.Export(event, null, "file")]}]).code;
|
||||
can.page.Select(can, output, "svg", function(svg) {can.group = can.svg = svg
|
||||
can.page.Select(can, output, "svg", function(svg) {can.group = can.svg = svg;
|
||||
can.onaction.init(event, can, msg, "init", svg);
|
||||
can.onaction.list[1] = ["group", "svg", "add"]
|
||||
can.onaction.list[2] = ["group", "svg", "add"];
|
||||
can.page.Select(can, svg, "*", function(item, index) {
|
||||
can.onaction.init(event, can, msg, index, item);
|
||||
switch (item.tagName) {
|
||||
case "g":
|
||||
can.onaction.list[1].push(item.Value("class"))
|
||||
can.onaction.list[2].push(item.Value("class"));
|
||||
break
|
||||
}
|
||||
})
|
||||
}), can.point = [];
|
||||
|
||||
return typeof cb == "function" && cb(msg), code;
|
||||
},
|
||||
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
|
||||
@ -42,53 +49,65 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
},
|
||||
})
|
||||
Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
move: {
|
||||
draw: function(event, can, point) {
|
||||
if (point.length == 1) {
|
||||
if (event.type != "click") {return}
|
||||
// 记录图形
|
||||
can.current = {target: event.target}
|
||||
} else if (point.length == 2) {
|
||||
if (event.type == "click") {return can.point = [], delete(can.current)}
|
||||
}
|
||||
select: {draw: function(event, can, point) {if (point.length == 1) {return}
|
||||
var p0 = point[0], p1 = point[1];
|
||||
var data = {
|
||||
"x": p0.x > p1.x? p1.x: p0.x,
|
||||
"y": p0.y > p1.y? p1.y: p0.y,
|
||||
"width": Math.abs(p0.x-p1.x),
|
||||
"height": Math.abs(p0.y-p1.y),
|
||||
"fill": "#11000000",
|
||||
"class": "temp",
|
||||
}
|
||||
can.Status(event, data, "width");
|
||||
event.type == "click" && point.length == 2 && (can.point = [])
|
||||
return data;
|
||||
}},
|
||||
resize: {draw: function(event, can, point) {
|
||||
if (point.length == 1) {if (event.type != "click") {return}
|
||||
// 记录图形
|
||||
can.current = {target: event.target}
|
||||
} else if (point.length == 2) {
|
||||
if (event.type == "click") {can.point = [], delete(can.current); return}
|
||||
}
|
||||
|
||||
var target = can.current.target
|
||||
var figure = can.onfigure[can.current.target.tagName];
|
||||
var move = figure.data.move || {x: "x", y: "y"}
|
||||
if (point.length == 1) {
|
||||
// 记录起点
|
||||
can.current.x = parseInt(target.Value(move.x))
|
||||
can.current.y = parseInt(target.Value(move.y))
|
||||
} else {
|
||||
// 移动图形
|
||||
target.Value(move.x, can.current.x+point[1].x-point[0].x)
|
||||
target.Value(move.y, can.current.y+point[1].y-point[0].y)
|
||||
}
|
||||
},
|
||||
},
|
||||
resize: {
|
||||
draw: function(event, can, point) {
|
||||
if (point.length == 1) {
|
||||
if (event.type != "click") {return}
|
||||
// 记录图形
|
||||
can.current = {target: event.target}
|
||||
} else if (point.length == 2) {
|
||||
if (event.type == "click") {return can.point = [], delete(can.current)}
|
||||
}
|
||||
var target = can.current.target
|
||||
var figure = can.onfigure[target.tagName];
|
||||
if (point.length == 1) {
|
||||
// 记录起点
|
||||
can.core.Item(figure.data.resize, function(key, value) {
|
||||
can.current[key] = parseInt(target.Value(value))
|
||||
})
|
||||
} else {
|
||||
var resize = figure.data.resize;
|
||||
target.Value(resize.width, can.current.width + point[1].x - point[0].x)
|
||||
target.Value(resize.height, can.current.height + point[1].y - point[0].y)
|
||||
}
|
||||
}},
|
||||
move: {draw: function(event, can, point) {
|
||||
if (point.length == 1) {if (event.type != "click") {return}
|
||||
// 记录图形
|
||||
can.current = {target: event.target}
|
||||
} else if (point.length == 2) {
|
||||
if (event.type == "click") {return can.point = [], delete(can.current), null}
|
||||
}
|
||||
|
||||
var target = can.current.target
|
||||
var figure = can.onfigure[can.current.target.tagName];
|
||||
var move = figure.data.move || {x: "x", y: "y"}
|
||||
if (point.length == 1) {
|
||||
// 记录起点
|
||||
can.core.List(figure.data.resize, function(item) {
|
||||
can.current[item] = parseInt(target.Value(item))
|
||||
})
|
||||
} else {
|
||||
// 绽放图形
|
||||
figure.resize(event, can, point, can.current, target)
|
||||
}
|
||||
},
|
||||
var target = can.current.target
|
||||
var figure = can.onfigure[can.current.target.tagName];
|
||||
var move = figure.data.move || {x: "x", y: "y"}
|
||||
if (point.length == 1) {
|
||||
// 记录起点
|
||||
can.current.x = parseInt(target.Value(move.x))
|
||||
can.current.y = parseInt(target.Value(move.y))
|
||||
} else {
|
||||
// 移动图形
|
||||
target.Value(move.x, can.current.x+point[1].x-point[0].x)
|
||||
target.Value(move.y, can.current.y+point[1].y-point[0].y)
|
||||
}
|
||||
}},
|
||||
svg: {
|
||||
data: {resize: {width: "width", height: "height"}},
|
||||
show: function(event, can, value, target) {},
|
||||
},
|
||||
text: {
|
||||
data: {move: {x: "x", y: "y"}}, // <text x="60" y="10">hi<text>
|
||||
@ -96,29 +115,22 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
},
|
||||
rect: {
|
||||
data: {
|
||||
resize: ["width", "height", "rx"],
|
||||
resize: {width: "width", height: "height"},
|
||||
move: {x: "x", y: "y"}, copy: ["width", "height", "rx", "ry"],
|
||||
rx: 4, ry: 4,
|
||||
}, // <rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
|
||||
draw: function(event, can, point) {
|
||||
if (point.length == 1) {return}
|
||||
draw: function(event, can, point) {if (point.length < 2) {return}
|
||||
var p0 = point[0], p1 = point[1];
|
||||
var data = {
|
||||
"x": p0.x > p1.x? p1.x: p0.x,
|
||||
"y": p0.y > p1.y? p1.y: p0.y,
|
||||
"width": Math.abs(p0.x-p1.x),
|
||||
"height": Math.abs(p0.y-p1.y),
|
||||
"rx": this.data.rx,
|
||||
"ry": this.data.ry,
|
||||
}
|
||||
can.core.Item(can.onfigure.rect.data, function(key, value) {
|
||||
data[key] = value
|
||||
})
|
||||
can.Status(event, data, "width");
|
||||
event.type == "click" && point.length == 2 && (can.point = [])
|
||||
return data;
|
||||
},
|
||||
resize: function(event, can, point, current, target) {
|
||||
target.Value("width", current.width + point[1].x - point[0].x)
|
||||
target.Value("height", current.height + point[1].y - point[0].y)
|
||||
return event.type == "click" && point.length == 2 && (can.point = []), data;
|
||||
},
|
||||
text: function(event, can, data, target) {
|
||||
data.x = target.x.baseVal.value+target.width.baseVal.value/2
|
||||
@ -131,6 +143,30 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
+ " + (" + value.width.baseVal.value + "," + value.height.baseVal.value+ ")"
|
||||
},
|
||||
},
|
||||
line: {
|
||||
data: {
|
||||
resize: {width: "x2", height: "y2"},
|
||||
move: {x: "x1", y: "y1"}, copy: ["x1", "y1", "x2", "y2"],
|
||||
}, // <line x1="10" x2="50" y1="110" y2="150"/>
|
||||
draw: function(event, can, point) {if (point.length < 2) {return}
|
||||
var p0 = point[0], p1 = point[1];
|
||||
var data = {
|
||||
"x1": p0.x, "y1": p0.y,
|
||||
"x2": p1.x, "y2": p1.y,
|
||||
}
|
||||
return event.type == "click" && point.length == 2 && (can.point = []), data;
|
||||
},
|
||||
text: function(event, can, data, target) {
|
||||
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
|
||||
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
|
||||
return data
|
||||
},
|
||||
show: function(event, can, value, target) {
|
||||
return value.tagName
|
||||
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
|
||||
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
|
||||
},
|
||||
},
|
||||
circle: {
|
||||
data: {move: {x: "cx", y: "cy"}, copy: ["r"]}, // <circle cx="25" cy="75" r="20"/>
|
||||
draw: function(event, can, point) {
|
||||
@ -176,28 +212,6 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
+ " > (" + parseInt(value.rx.baseVal.value) + parseInt(value.ry.baseVal.value) + ")"
|
||||
},
|
||||
},
|
||||
line: {
|
||||
data: {}, // <line x1="10" x2="50" y1="110" y2="150"/>
|
||||
draw: function(event, can, point) {
|
||||
var p0 = point[0], p1 = point[1];
|
||||
var data = {
|
||||
"x1": p0.x, "y1": p0.y,
|
||||
"x2": p1.x, "y2": p1.y,
|
||||
}
|
||||
event.type == "click" && point.length == 2 && (can.point = [])
|
||||
return data;
|
||||
},
|
||||
text: function(event, can, data, target) {
|
||||
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
|
||||
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
|
||||
return data
|
||||
},
|
||||
show: function(event, can, value, target) {
|
||||
return value.tagName
|
||||
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
|
||||
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
|
||||
},
|
||||
},
|
||||
path: {
|
||||
data: {}, // <path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
|
||||
draw: function(event, can, point) {
|
||||
@ -211,7 +225,6 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
}
|
||||
}).join(" ")
|
||||
}
|
||||
console.log(data)
|
||||
event.type == "click" && point.length == 4 && (can.point = [])
|
||||
return data;
|
||||
},
|
||||
@ -261,24 +274,27 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "组件菜单", list: ["保存",
|
||||
Volcanos("onaction", {help: "组件菜单", list: ["保存", "清空",
|
||||
["group", "svg", "add"],
|
||||
["stroke-width", 1, 2, 3, 4, 5],
|
||||
["stroke", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black"],
|
||||
["fill", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black"],
|
||||
["shape", "move", "resize", "rect", "circle", "ellipse", "path", "line", "polyline", "polygon"],
|
||||
["fill", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black", "#0000"],
|
||||
["shape", "move", "select", "resize", "rect", "circle", "ellipse", "path", "line", "polyline", "polygon"],
|
||||
["grid", 1, 2, 3, 4, 5, 10, 20],
|
||||
],
|
||||
"保存": function(event, can, msg, cmd, target) {
|
||||
can.run(event, ["action", cmd, can.Option("name"), can.Export(event, can.svg, "file")], function() {
|
||||
can.user.toast("保存成功")
|
||||
}, true)
|
||||
},
|
||||
"清空": function(event, can, msg, cmd, target) {can.svg.innerHTML = ""},
|
||||
|
||||
group: function(event, can, value, cmd, target) {
|
||||
switch (value) {
|
||||
case "svg": return can.group = can.svg;
|
||||
case "add":
|
||||
can.user.prompt("add group", function(name) {
|
||||
can.svg.append(can.group = document.createElementNS('http://www.w3.org/2000/svg', 'g'))
|
||||
can.svg.append(can.onaction.init(event, can, value, cmd, can.group = document.createElementNS('http://www.w3.org/2000/svg', 'g')))
|
||||
can.group.Value("class", name)
|
||||
can.core.List(["stroke-width", "stroke", "fill"], function(name) {
|
||||
can.group.Value(name, can.Action(name))
|
||||
@ -300,11 +316,7 @@ Volcanos("onaction", {help: "组件菜单", list: ["保存",
|
||||
stroke: function(event, can, value, cmd, target) {can.group.Value(cmd, value)},
|
||||
fill: function(event, can, value, cmd, target) {can.group.Value(cmd, value)},
|
||||
shape: function(event, can, value, cmd, target) {can.shape = value},
|
||||
|
||||
resize: function(event, can, value, cmd, item) {var target = can.target.firstChild;
|
||||
if (cmd == "x") {target.style.width = target.offsetHeight + value + "px"}
|
||||
if (cmd == "y") {target.style.height = target.offsetHeight + value + "px"}
|
||||
},
|
||||
grid: function(event, can, value, cmd, target) {can.grid = value},
|
||||
|
||||
init: function(event, can, msg, cmd, item) {
|
||||
item.ondblclick = item.oncontextmenu = function(event) {can.user.carte(event, shy("", can.ondetail, can.ondetail.list, function(event, key, meta) {var cb = meta[key];
|
||||
@ -312,10 +324,10 @@ Volcanos("onaction", {help: "组件菜单", list: ["保存",
|
||||
}), can), event.stopPropagation(), event.preventDefault()}
|
||||
item.onclick = function() {
|
||||
}
|
||||
item.Value = function(key, value) {return value && item.setAttribute(key, value), item.getAttribute(key||"class")||""}
|
||||
item.Value = function(key, value) {return value && item.setAttribute(key, value), item.getAttribute(key||"class")||item[key]&&item[key].baseVal&&item[key].baseVal.value||item[key]&&item[key].baseVal||""}
|
||||
return item;
|
||||
},
|
||||
push: function(event, can, msg, cmd, target) {
|
||||
push: function(event, can, msg, cmd, target) {cmd = {select: "rect"}[cmd] || cmd
|
||||
var rect = document.createElementNS("http://www.w3.org/2000/svg", cmd);
|
||||
target.appendChild(can.onaction.init(event, can, msg, cmd, rect));
|
||||
can.core.Item(msg, function(key, value) {rect.Value(key, value)});
|
||||
@ -333,11 +345,14 @@ Volcanos("onaction", {help: "组件菜单", list: ["保存",
|
||||
},
|
||||
|
||||
onclick: function(event, can) {if (!can.svg) {return}
|
||||
var p = can.svg.getBoundingClientRect()
|
||||
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
|
||||
var p = can.svg.getBoundingClientRect();
|
||||
var point = {x: event.clientX-p.x, y: event.clientY-p.y};
|
||||
point.x = point.x - point.x % parseInt(can.Action("grid"));
|
||||
point.y = point.y - point.y % parseInt(can.Action("grid"));
|
||||
|
||||
can.point = (can.point || []).concat([point])
|
||||
can.onaction.draw(event, can, can.point)
|
||||
can.point = (can.point || []).concat([point]);
|
||||
can.temp && can.page.Remove(can, can.temp) && delete(can.temp);
|
||||
can.onaction.draw(event, can, can.point);
|
||||
},
|
||||
onmouseover: function(event, can) {
|
||||
can.Status(event, event.target, "which")
|
||||
@ -345,24 +360,16 @@ Volcanos("onaction", {help: "组件菜单", list: ["保存",
|
||||
onmousemove: function(event, can) {if (!can.svg || can.point.length == 0) {return}
|
||||
var p = can.svg.getBoundingClientRect()
|
||||
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
|
||||
point.x = point.x - point.x % parseInt(can.Action("grid"));
|
||||
point.y = point.y - point.y % parseInt(can.Action("grid"));
|
||||
|
||||
can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
|
||||
can.temp = can.onaction.draw(event, can, can.point.concat(point))
|
||||
|
||||
can.Status(event, point, "point")
|
||||
},
|
||||
onkeydown: function(event, can) {
|
||||
if (event.key == "Enter") {
|
||||
can.point = []
|
||||
return
|
||||
}
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空", ["rect", "rect", "line", "circle"]],
|
||||
"清空": function(event, can, msg, cmd, target) {
|
||||
console.log("choice", cmd)
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空"]})
|
||||
Volcanos("ondetail", {help: "组件详情", list: ["编辑", "复制", "删除"],
|
||||
"编辑": function(event, can, msg, index, key, cmd, target) {
|
||||
can.user.prompt("文字", function(text) {
|
||||
@ -387,9 +394,7 @@ Volcanos("ondetail", {help: "组件详情", list: ["编辑", "复制", "删除"]
|
||||
can.core.List(figure.copy, function(item) {data[item] = target.Value(item)});
|
||||
return data && can.onaction.push(event, can, data, target.tagName, can.group||can.svg)
|
||||
},
|
||||
"删除": function(event, can, msg, index, key, cmd, target) {
|
||||
can.page.Remove(can, target)
|
||||
},
|
||||
"删除": function(event, can, msg, index, key, cmd, target) {can.page.Remove(can, target)},
|
||||
})
|
||||
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"],
|
||||
"begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
|
||||
|
@ -1,4 +1,6 @@
|
||||
Volcanos("onimport", {help: "导入数据", list: [],
|
||||
_begin: function(can) {},
|
||||
_start: function(can) {},
|
||||
init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
|
||||
if (msg.append && msg.append.length > 0) {
|
||||
var table = can.page.AppendTable(can, output, msg, msg.append);
|
||||
@ -17,12 +19,21 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
return typeof cb == "function" && cb(msg), table;
|
||||
}
|
||||
|
||||
can.page.Append(can, output, [{view: "preview", inner: msg.Option("preview"), style: {
|
||||
float: "left", "max-height": "250px", overflow: "auto",
|
||||
border: "solid 2px red",
|
||||
}}])
|
||||
var last = can.page.Append(can, output, [{type: "textarea", cols: 32, rows: 19, inner: msg.Result()}]).last;
|
||||
return typeof cb == "function" && cb(msg), can.view = last;
|
||||
can.preview = can.page.Append(can, output, [{view: "preview", inner: msg.Result(),
|
||||
style: {border: "solid 2px red"},
|
||||
}]).last
|
||||
|
||||
can.page.Select(can, can.preview, ".story", function(item) {
|
||||
var figure = can.onfigure[item.dataset.type] || can.onfigure[item.localName];
|
||||
|
||||
item.onclick = function(event) {can.node = item}
|
||||
item.oncontextmenu = function(event) {var target = event.target; can.user.carte(event, shy("", can.ondetail, figure.menu||can.ondetail.list, function(event, key, meta) {var cb = meta[key];
|
||||
typeof cb == "function" && cb(event, can, msg, 0, key, key, target);
|
||||
}), can), event.stopPropagation(), event.preventDefault()}
|
||||
|
||||
figure && figure.init && figure.init({}, can, item.localName, "init", item)
|
||||
})
|
||||
return typeof cb == "function" && cb(msg), can.preview;
|
||||
},
|
||||
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
|
||||
can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
|
||||
@ -32,12 +43,235 @@ Volcanos("onimport", {help: "导入数据", list: [],
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "组件菜单", list: ["保存"],
|
||||
"保存": function(event, can, msg, cmd, target) {
|
||||
can.run(event, ["action", cmd, can.Option("name"), can.view.value], function() {
|
||||
Volcanos("onfigure", {help: "图形绘制", list: [],
|
||||
premenu: {
|
||||
init: function(event, can, value, cmd, target) {
|
||||
can.page.Append(can, target, can.page.Select(can, can.preview, "h1.story,h2.story,h3.story", function(item) {var data = item.dataset;
|
||||
return {text: [item.innerHTML, "li"], onclick: function(event) {
|
||||
item.scrollIntoView();
|
||||
}};
|
||||
}))
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {return "premenu"},
|
||||
},
|
||||
endmenu: {
|
||||
init: function(event, can, value, cmd, target) {},
|
||||
save: function(event, can, value, cmd, target) {return "endmenu"},
|
||||
},
|
||||
h1: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "h1", "h1"], dataset: {type: "title", name: "", text: ""}, inner: "h1...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'title "' + value.replace(data.name+" ", "") + '"': ""
|
||||
},
|
||||
},
|
||||
h2: {
|
||||
push: function(event, can, value, cmd, target) {
|
||||
return [{view: ["story", "h2", "h2"], dataset: {type: "title", name: "", text: ""}, inner: "h2...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'chapter "' + value.replace(data.name+" ", "") + '"': ""
|
||||
},
|
||||
},
|
||||
h3: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "h3", "h3"], dataset: {type: "title", name: "", text: ""}, inner: "h3...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'section "' + value.replace(data.name+" ", "") + '"': ""
|
||||
},
|
||||
},
|
||||
brief: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "p", "p"], dataset: {type: "brief", name: "", text: ""}, inner: "brief...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'brief "'+data.name+'" `' + value + '`': ""
|
||||
},
|
||||
},
|
||||
refer: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "ul"], dataset: {type: "refer", name: "", text: ""}, list: [{type: "li", inner: "refer...."}]}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'refer "'+data.name+'" `\n' + can.page.Select(can, target, "li", function(item) {
|
||||
return item.innerHTML.replace(": ", " ")
|
||||
}).join("\n") + '\n`': ""
|
||||
},
|
||||
},
|
||||
spark: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "p", "p"], dataset: {type: "spark", name: "", text: ""}, inner: "spark...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'spark "'+data.name+'" `' + value + '`': ""
|
||||
},
|
||||
},
|
||||
|
||||
local: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "div"], dataset: {type: "local", name: "", text: ""}, inner: "local...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'local "'+data.name+'" '+' `' + data.text + '`': ""
|
||||
},
|
||||
},
|
||||
shell: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "code", "code"], dataset: {type: "shell", name: "", text: "", dir: "./"}, inner: "shell...."}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'shell "'+data.name+'" '+'"'+data.dir+'"' +' `' + data.text + '`': ""
|
||||
},
|
||||
},
|
||||
order: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "ul"], dataset: {type: "order", name: "", text: ""}, list: [{type: "li", inner: "order...."}]}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'order "'+data.name+'" `\n' + can.page.Select(can, target, "li", function(item) {
|
||||
return item.innerHTML
|
||||
}).join("\n") + '\n`': ""
|
||||
},
|
||||
},
|
||||
table: {
|
||||
data: {menu: ["追加行", "追加列", "删除行", "删除列"]},
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "table", "table"], dataset: {type: "table", name: "", text: ""}, list: [
|
||||
{type: "tr", list: [{type: "th"}, {type: "th"}]},
|
||||
{type: "tr", list: [{type: "td"}, {type: "td"}]},
|
||||
]}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'table "'+data.name+'" `\n' + can.page.Select(can, target, "tr", function(tr) {
|
||||
return can.page.Select(can, tr, "th,td", function(td) {
|
||||
return td.innerHTML
|
||||
}).join(" ")
|
||||
}).join("\n") + '\n`': ""
|
||||
},
|
||||
},
|
||||
stack: {
|
||||
init: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
can.page.Select(can, target, "div.stack", function(stack) {var data = stack.dataset||{};
|
||||
function fold(stack) {
|
||||
stack.nextSibling && (stack.nextSibling.style.display = "none")
|
||||
can.page.Select(can, stack, "span.state", function(state) {
|
||||
if (state.innerText == "o") {return}
|
||||
can.page.ClassList.add(can, stack, "fold")
|
||||
can.page.ClassList.del(can, stack, "span")
|
||||
state.innerText = ">"
|
||||
})
|
||||
}
|
||||
function span(stack) {
|
||||
stack.nextSibling && (stack.nextSibling.style.display = "")
|
||||
can.page.Select(can, stack, "span.state", function(state) {
|
||||
if (state.innerText == "o") {return}
|
||||
can.page.ClassList.add(can, stack, "span")
|
||||
can.page.ClassList.del(can, stack, "fold")
|
||||
state.innerText = "v"
|
||||
})
|
||||
}
|
||||
function mark(stack, color) {
|
||||
stack.style.background = color;
|
||||
stack.style.color = color == ""? "": "white";
|
||||
}
|
||||
|
||||
stack.onclick = function(event) {stack.nextSibling && (stack.nextSibling.style.display == "none"? span(stack): fold(stack))}
|
||||
stack.oncontextmenu = function(event) {var detail = can.feature.detail || can.ondetail.list, target = event.target;
|
||||
can.user.carte(event, shy("", can.ondetail, ["全部折叠", "全部展开", "标记颜色", "清除颜色", "red", "green", "blue"], function(event, cmd, meta) {var cb = meta[cmd];
|
||||
switch (cmd) {
|
||||
case "red":
|
||||
case "green":
|
||||
case "blue":
|
||||
mark(target, cmd)
|
||||
break
|
||||
case "标记颜色":
|
||||
can.user.prompt("请输入颜色:", function(color) {
|
||||
mark(target, color)
|
||||
})
|
||||
break
|
||||
case "清除颜色":
|
||||
mark(target, "")
|
||||
break
|
||||
case "全部折叠":
|
||||
fold(stack), can.page.Select(can, stack.nextSibling, "div.stack", fold)
|
||||
break
|
||||
case "全部展开":
|
||||
span(stack), can.page.Select(can, stack.nextSibling, "div.stack", span)
|
||||
break
|
||||
}
|
||||
}))
|
||||
}
|
||||
})
|
||||
},
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["stack", "div"], dataset: {type: "stack", name: "", text: ""}}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'stack "'+data.name+'"' +' `' + data.text + '`': ""
|
||||
},
|
||||
},
|
||||
|
||||
label: {
|
||||
init: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
target.Value = function(key, value) {return value && target.setAttribute(key, value), target.getAttribute(key||"class")||target[key]&&target[key].baseVal&&target[key].baseVal.value||target[key]&&target[key].baseVal||""}
|
||||
},
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "svg"], dataset: {type: "story", name: "", text: ""}}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'label "'+data.name+'"' +' `\n' + data.text + '\n`' + " " + [
|
||||
target.Value("font-size")||16, target.Value("stroke")||"yellow", target.Value("fill")||"blue",
|
||||
].join(" "): ""
|
||||
},
|
||||
},
|
||||
chain: {
|
||||
push: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return [{view: ["story", "svg"], dataset: {type: "story", name: "", text: ""}}]
|
||||
},
|
||||
save: function(event, can, value, cmd, target) {var data = target.dataset;
|
||||
return value? 'chain "'+data.name+'"' +' `\n' + data.text + '\n`': ""
|
||||
},
|
||||
},
|
||||
})
|
||||
Volcanos("onaction", {help: "组件菜单", list: ["保存", ["操作", "只读", "排序", "编辑"],
|
||||
"插入", ["元素", "h1", "h2", "h3", "brief", "refer", "spark", "shell", "order", "table", "stack"]],
|
||||
|
||||
"保存": function(event, can, value, cmd, target) {
|
||||
var save = can.page.Select(can, target, ".story", function(story) {
|
||||
var figure = can.onfigure[story.dataset.type] || can.onfigure[story.localName];
|
||||
return figure && figure.save && figure.save(event, can, story.innerHTML, cmd, story) || story.innerHTML
|
||||
}).join("\n\n")
|
||||
|
||||
can.run(event, ["action", cmd, can.Option("name"), save], function(msg) {
|
||||
can.user.toast("保存成功")
|
||||
}, true)
|
||||
},
|
||||
"只读": function(event, can, value, cmd, target) {
|
||||
can.page.Select(can, can.preview, ".story", function(item) {
|
||||
item.setAttribute("contenteditable", false)
|
||||
item.setAttribute("draggable", false)
|
||||
})
|
||||
},
|
||||
"排序": function(event, can, value, cmd, target) {
|
||||
can.page.Select(can, can.preview, ".story", function(item) {
|
||||
item.setAttribute("draggable", true)
|
||||
item.ondragstart = function(event) {can.drag = event.target}
|
||||
item.ondragover = function(event) {event.preventDefault()}
|
||||
item.ondrop = function(event) {event.preventDefault()
|
||||
can.preview.insertBefore(can.drag, item)
|
||||
}
|
||||
})
|
||||
},
|
||||
"编辑": function(event, can, value, cmd, target) {
|
||||
can.page.Select(can, can.preview, ".story", function(item) {
|
||||
item.setAttribute("contenteditable", true)
|
||||
})
|
||||
},
|
||||
"插入": function(event, can, value, cmd, target) {var figure = can.onfigure[can.Action("元素")];
|
||||
can.page.Append(can, can.preview, figure.push(event, can, value, cmd, target)).first.setAttribute("contenteditable", true)
|
||||
},
|
||||
})
|
||||
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空", ["rect", "rect", "line", "circle"]],
|
||||
"清空": function(event, can, msg, cmd, target) {
|
||||
@ -60,20 +294,32 @@ Volcanos("ondetail", {help: "组件详情", list: ["编辑", "删除"],
|
||||
target.Text = p
|
||||
}, target.Text && target.Text.innerText || "")
|
||||
},
|
||||
"复制": function(event, can, msg, index, key, cmd, target) {
|
||||
var figure = can.onfigure[target.tagName]
|
||||
figure.copy(event, can, target)
|
||||
},
|
||||
"删除": function(event, can, msg, index, key, cmd, target) {
|
||||
can.page.Remove(can, target)
|
||||
},
|
||||
})
|
||||
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"],
|
||||
"begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
|
||||
"width": function(event, can, value, cmd, target) {target.innerHTML = value? value.width+","+value.height: ""},
|
||||
"point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y},
|
||||
"which": function(event, can, value, cmd, target) {var figure = can.onfigure[value.tagName];
|
||||
target.innerHTML = figure? figure.show(event, can, value, target): value.tagName;
|
||||
|
||||
"删除行": function(event, can, msg, index, key, cmd, target) {
|
||||
var table = target.parentNode.parentNode
|
||||
var tr = target.parentNode
|
||||
table.removeChild(tr)
|
||||
},
|
||||
"追加行": function(event, can, msg, index, key, cmd, target) {
|
||||
var tr = document.createElement("tr")
|
||||
can.page.Append(can, tr, can.page.Select(can, target.parentNode, "td,th", function() {
|
||||
return {type: "td", inner: " "}
|
||||
}))
|
||||
target.parentNode.parentNode.append(tr)
|
||||
},
|
||||
"追加列": function(event, can, msg, index, key, cmd, target) {
|
||||
var table = target.parentNode.parentNode
|
||||
var tr = target.parentNode
|
||||
var index = can.page.Select(can, tr, "th,td", function(item, index) {
|
||||
return item == target && index || undefined
|
||||
})[0]
|
||||
|
||||
can.page.Select(can, table, "tr", function(tr, index) {
|
||||
can.page.Append(can, tr, [{type: index == 0? "th": "td", inner: " "}])
|
||||
})
|
||||
},
|
||||
})
|
||||
Volcanos("onexport", {help: "导出数据", list: []})
|
||||
|
128
proto.js
128
proto.js
@ -14,35 +14,66 @@ function shy(help, meta, list, cb) { // 封装函数
|
||||
return cb;
|
||||
}
|
||||
function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
// 全局属性
|
||||
var list = arguments.callee.list || [], meta = arguments.callee.meta || {
|
||||
create_time: new Date(), path: "/static/volcanos/", index: 1, cache: {},
|
||||
};
|
||||
|
||||
can = can || {};
|
||||
can._name = name;
|
||||
// 全局缓存
|
||||
var list = arguments.callee.list || [], meta = arguments.callee.meta || {index: 1, cache: {}};
|
||||
arguments.callee.meta = meta, arguments.callee.list = list;
|
||||
|
||||
// 定义原型
|
||||
var id = 1, conf = {}, conf_cb = {}, sync = {}, cache = {};
|
||||
can[name] || list.push({_name: name, can: can, create_time: new Date()}) && (can.__proto__ = {
|
||||
_create_time: new Date(), _name: name, _path: "", _help: "插件模块", load: function(name) {
|
||||
can = can || {}, list.push(can) && (can.__proto__ = {_name: name, _help: "插件模块", _create_time: new Date(), _load: function(name) {
|
||||
if (meta.cache[name]) {var cache = meta.cache[name];
|
||||
for (var i = 0; i < cache.length; i++) {var item = cache[i];
|
||||
if (item.can._name == can._name) {continue}
|
||||
can[item._name] = item.can;
|
||||
if (item._name == can._name) {continue}
|
||||
can[item._name] = item;
|
||||
}
|
||||
return can
|
||||
}
|
||||
|
||||
meta.cache[name] = []
|
||||
for (var i = meta.index; i < list.length; i++) {var item = list[i];
|
||||
if (item.can._name == can._name || item.can._type == "local") {continue}
|
||||
can[item._name] = item.can;
|
||||
if (item._name == can._name || item._type == "local") {continue}
|
||||
can[item._name] = item;
|
||||
meta.cache[name].push(item);
|
||||
}
|
||||
meta.index = i;
|
||||
return can
|
||||
},
|
||||
require: function(libs, cb) {
|
||||
if (!libs || libs.length == 0) {
|
||||
// 加载完成
|
||||
typeof cb == "function" && setTimeout(function() {cb(can)}, 10);
|
||||
return
|
||||
}
|
||||
|
||||
if (can[libs[0]]) {
|
||||
// 已经加载
|
||||
can.require(libs.slice(1), cb)
|
||||
return
|
||||
}
|
||||
if (meta.cache[libs[0]]) {
|
||||
// 缓存加载
|
||||
can._load(libs[0]), can.require(libs.slice(1), cb)
|
||||
return
|
||||
}
|
||||
|
||||
if (libs[0].endsWith(".wasm")) {var go = new Go();
|
||||
// 加载汇编
|
||||
WebAssembly.instantiateStreaming(fetch(libs[0]), go.importObject).then((result) => {
|
||||
go.argv = [can];
|
||||
go.run(result.instance);
|
||||
can.require(libs.slice(1), cb);
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
// 加载脚本
|
||||
can.Dream(document.body, libs[0].indexOf(".") == -1? libs[0]+".js": libs[0], function() {
|
||||
can._load(libs[0]), can.require(libs.slice(1), cb);
|
||||
})
|
||||
},
|
||||
|
||||
ID: shy("生成器", function() {return id++}),
|
||||
Log: shy("日志器", function() {console.log(arguments)}),
|
||||
Conf: shy("配置器", function(key, value, cb) {if (key == undefined) {return conf}
|
||||
@ -78,8 +109,7 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
msg = event.msg = msg || event.msg || {}, msg.__proto__ = proto || {
|
||||
_create_time: can.base.Time(), _source: can,
|
||||
Log: shy("输出日志", function() {console.log(arguments)}),
|
||||
Ids: function(index, key) {
|
||||
var id = index;
|
||||
Ids: function(index, key) {var id = index;
|
||||
msg && msg.id && (id = msg.id[index]) || msg && msg.name && (id = msg.name[index]);
|
||||
return id;
|
||||
},
|
||||
@ -96,6 +126,25 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
for (var i = 0; i < arguments.length; i++) {msg.result.push(arguments[i])}
|
||||
return msg;
|
||||
}),
|
||||
Push: function(key, value) {msg.append = msg.append || []
|
||||
if (typeof key == "object") {
|
||||
value? can.core.List(value, function(item) {
|
||||
msg.Push(item, key[item]||"")
|
||||
}): can.core.Item(key, function(key, value) {
|
||||
msg.Push(key, value||"")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
for (var i = 0; i < msg.append.length; i++) {
|
||||
if (msg.append[i] == key) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (i >= msg.append.length) {msg.append.push(key)}
|
||||
msg[key] = msg[key] || []
|
||||
msg[key].push(""+value)
|
||||
},
|
||||
Copy: function(res) {
|
||||
res.result && (msg.result = res.result)
|
||||
res.append && (msg.append = res.append) && res.append.forEach(function(item) {
|
||||
@ -128,21 +177,20 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
return [name, ext, txt]
|
||||
},
|
||||
};
|
||||
msg.event = event
|
||||
return msg
|
||||
return msg.event = event, 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 = (type.startsWith("/")? "": (can._path||meta.path))+type
|
||||
style.href = (type.startsWith("/")? "": Config.volcano)+type;
|
||||
style.onload = line;
|
||||
target.appendChild(style);
|
||||
return style
|
||||
}
|
||||
if (type.endsWith(".js")) {
|
||||
var script = document.createElement("script");
|
||||
script.src = (type.startsWith("/")? "": (can._path||meta.path))+type,
|
||||
script.src = (type.startsWith("/")? "": Config.volcano)+type;
|
||||
script.onload = line;
|
||||
target.appendChild(script);
|
||||
return script
|
||||
@ -181,11 +229,13 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
}),
|
||||
Story: shy("存储器", function(type, meta, list) {
|
||||
}),
|
||||
}), arguments.callee.meta = meta, arguments.callee.list = list;
|
||||
});
|
||||
|
||||
// 加载模块
|
||||
function next() {
|
||||
libs && libs.length > 1? Volcanos(name, can, libs.slice(1), cb): typeof cb == "function" && setTimeout(function() {cb(can); if (can.target) {
|
||||
can.require(libs, function() {
|
||||
can.onimport && can.onimport._begin && can.onimport._begin(can)
|
||||
typeof cb == "function" && cb(can);
|
||||
if (can.target) {
|
||||
// 初始化主模块
|
||||
function run(event, msg, key, cb) {
|
||||
if (typeof cb == "function") {
|
||||
// 本地命令
|
||||
@ -199,41 +249,15 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
|
||||
can.core.Item(can.onaction, function(key, cb) {key.indexOf("on") == 0 && (can.target[key] = function(event) {cb(event, can)})});
|
||||
// 注册action
|
||||
can.action && (can.action.innerHTML = ""), can.onaction && can.page.AppendAction(can, can.action, can.onaction.list, function(event, value, key) {
|
||||
key? run(event, value, key, can.onaction[key]): run(event, msg, value, can.onaction[value]);
|
||||
key? run(event, value, key, can.onaction[key]||can.onaction[value]): run(event, msg, value, can.onaction[value]);
|
||||
})
|
||||
// 注册choice
|
||||
can.target.oncontextmenu = function(event) {can.user.carte(event, shy("", can.onchoice, can.onchoice.list, function(event, key, meta) {
|
||||
run(event, msg, key, can.onchoice[key] || can.onaction[key]);
|
||||
}), can), event.stopPropagation(), event.preventDefault()}
|
||||
}}, 10);
|
||||
}
|
||||
if (libs && libs.length > 0) {
|
||||
if (can[libs[0]]) {
|
||||
// 重复加载
|
||||
next()
|
||||
} else if (meta.cache[libs[0]]) {
|
||||
// 缓存加载
|
||||
can.load(libs[0]), next()
|
||||
} else {
|
||||
// 加载脚本
|
||||
if (libs[0].endsWith(".wasm")) {var go = new Go();
|
||||
WebAssembly.instantiateStreaming(fetch(libs[0]), go.importObject).then((result) => {
|
||||
go.argv = [can];
|
||||
go.run(result.instance);
|
||||
next();
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
} else {
|
||||
can.Dream(document.body, libs[0].indexOf(".") == -1? libs[0]+".js": libs[0], function() {
|
||||
can.load(libs[0]), next();
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 独立模块
|
||||
next()
|
||||
}
|
||||
can.onimport && can.onimport._start && can.onimport._start(can)
|
||||
})
|
||||
return can
|
||||
}
|
||||
|
||||
|
74
style.css
74
style.css
@ -254,6 +254,49 @@ fieldset table td.select {
|
||||
background-color:red;
|
||||
}
|
||||
|
||||
fieldset 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.code span.red {
|
||||
color:red;
|
||||
}
|
||||
fieldset div.code span.green {
|
||||
color:green;
|
||||
}
|
||||
|
||||
fieldset .story {
|
||||
border:solid 2px #f000;
|
||||
}
|
||||
fieldset .story:hover {
|
||||
border:solid 2px red;
|
||||
}
|
||||
|
||||
fieldset ul.story li:hover {
|
||||
border:solid 2px red;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
fieldset code.story {
|
||||
display:block;
|
||||
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.stack:hover {
|
||||
background-color:red;
|
||||
}
|
||||
@ -272,20 +315,25 @@ fieldset ul.stack:hover {
|
||||
border:solid 2px red;
|
||||
}
|
||||
|
||||
fieldset 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 td.over {
|
||||
border:solid 2px red;
|
||||
}
|
||||
fieldset div.code span.red {
|
||||
|
||||
sup.more {
|
||||
color:red;
|
||||
}
|
||||
fieldset div.code span.green {
|
||||
color:green;
|
||||
|
||||
fieldset.input {
|
||||
z-index: 10000;
|
||||
border:solid 2px yellow;
|
||||
}
|
||||
fieldset.input.date table tr:hover {
|
||||
background-color:yellow;
|
||||
}
|
||||
fieldset.input.date table td:hover {
|
||||
background-color:red;
|
||||
cursor:pointer;
|
||||
}
|
||||
fieldset.input.date table td.now {
|
||||
background-color:red;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user