1
0
forked from x/volcanos
This commit is contained in:
shaoying 2021-05-16 01:05:22 +08:00
parent d23369ccaf
commit 4756adbd22
23 changed files with 1090 additions and 1149 deletions

555
frame.js
View File

@ -1,5 +1,5 @@
var _can_name = "/frame.js" var _can_name = "/frame.js"
Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta, list, cb, target) { Volcanos("onengine", {help: "搜索引擎", list: [], _init: function(can, meta, list, cb, target) {
can.core.Next(list, function(item, next) { item.type = "panel" can.core.Next(list, function(item, next) { item.type = "panel"
can.onappend._init(can, item, item.list, function(panel) { can.onappend._init(can, item, item.list, function(panel) {
panel.onaction && panel.onappend._action(panel, item.action||panel.onaction.list) panel.onaction && panel.onappend._action(panel, item.action||panel.onaction.list)
@ -8,10 +8,6 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
panel.run = function(event, cmds, cb) { var msg = panel.request(event); cmds = cmds || [] panel.run = function(event, cmds, cb) { var msg = panel.request(event); cmds = cmds || []
return (can.onengine[cmds[0]]||can.onengine[meta.main.engine]||can.onengine.remote)(event, can, msg, panel, cmds, cb) return (can.onengine[cmds[0]]||can.onengine[meta.main.engine]||can.onengine.remote)(event, can, msg, panel, cmds, cb)
}, can[item.name] = panel, next() }, can[item.name] = panel, next()
panel.page.Modify(panel, panel._output, {onmouseover: function(event) {
Volcanos.meta.data.menu && panel.page.Remove(panel, Volcanos.meta.data.menu.first)
}})
}, target) }, target)
}, function() { }, function() {
var panel = can[meta.main.name], msg = can.request() var panel = can[meta.main.name], msg = can.request()
@ -23,7 +19,7 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
var sub, mod = can, fun = can, key = ""; can.core.List(cmds[1].split("."), function(value) { var sub, mod = can, fun = can, key = ""; can.core.List(cmds[1].split("."), function(value) {
fun && (sub = mod, mod = fun, fun = mod[value], key = value) fun && (sub = mod, mod = fun, fun = mod[value], key = value)
}); if (!sub || !mod || !fun) { }); if (!sub || !mod || !fun) {
can.base.Warn("not found", cmds[1]) can.misc.Warn("not found", cmds[1])
can.base.isFunc(cb) && cb(msg.Echo("warn: ", "not found: ", cmds[1])) can.base.isFunc(cb) && cb(msg.Echo("warn: ", "not found: ", cmds[1]))
return return
} }
@ -37,7 +33,18 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
remote: function(event, can, msg, panel, cmds, cb) { remote: function(event, can, msg, panel, cmds, cb) {
delete(msg._handle), delete(msg._toast) delete(msg._handle), delete(msg._toast)
if (panel.onengine.engine(event, can, msg, panel, cmds, cb)) { return } if (panel.onengine.engine(event, can, msg, panel, cmds, cb)) { return }
can.misc.Runs(event, can, {names: panel._name, daemon: can._daemon+"."+msg._daemon}, cmds, cb)
var key = panel._name+"."+cmds.join(",")
if (can.user.isLocalFile) { var msg = can.request(event); msg.Clear("append")
var res = Volcanos.meta.pack[key]; res? msg.Copy(res): can.user.toast(can, "缺失数据")
return typeof cb == "function" && cb(msg)
}
can.misc.Run(event, can, {names: (can.Conf("iceberg")||"/chat/")+panel._name, daemon: can._daemon+"."+msg._daemon}, cmds, function(msg) {
Volcanos.meta.pack[key] = msg
can.base.isFunc(cb) && cb(msg)
})
panel.search(event, ["Footer.onimport.ncmd"]) panel.search(event, ["Footer.onimport.ncmd"])
}, engine: function(event, can, msg, panel, cmds, cb) { return false }, }, engine: function(event, can, msg, panel, cmds, cb) { return false },
listen: shy("事件回调", {}, [], function(can, name, cb) { listen: shy("事件回调", {}, [], function(can, name, cb) {
@ -170,7 +177,7 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
}}, }},
}, },
}) })
Volcanos("ondaemon", {help: "解析引擎", list: [], _init: function(can) { Volcanos("ondaemon", {help: "推荐引擎", list: [], _init: function(can) {
if (can.user.isLocalFile) { return } if (can.user.isLocalFile) { return }
can.misc.WSS(can, {type: "chrome", name: can.user.Search(can, "daemon")||""}, function(event, msg, cmd, arg) { if (!msg) { return } can.misc.WSS(can, {type: "chrome", name: can.user.Search(can, "daemon")||""}, function(event, msg, cmd, arg) { if (!msg) { return }
if (can.base.isFunc(can.ondaemon[cmd])) { if (can.base.isFunc(can.ondaemon[cmd])) {
@ -188,8 +195,8 @@ Volcanos("ondaemon", {help: "解析引擎", list: [], _init: function(can) {
}, },
_list: [{}], _list: [{}],
toast: function(can, msg, arg) { arg[0] = can toast: function(can, msg, arg) { arg[0] = can
can._toast && can._toast.Close() Volcanos.meta.float.toast && can.page.Remove(can, Volcanos.meta.float.toast._target)
can._toast = can.core.CallFunc(can.user.toast, arg) Volcanos.meta.float.toast = can.core.CallFunc(can.user.toast, {can: can, msg: msg, cmds: arg})
}, },
grow: function(can, msg, arg) { grow: function(can, msg, arg) {
var sub = can.ondaemon._list[msg.Option("_target")] var sub = can.ondaemon._list[msg.Option("_target")]
@ -199,7 +206,7 @@ Volcanos("ondaemon", {help: "解析引擎", list: [], _init: function(can) {
out.onimport._grow(out, arg.join("")) out.onimport._grow(out, arg.join(""))
}, },
pwd: function(can, msg, arg) { pwd: function(can, msg, arg) {
can.base.Log(msg) can.misc.Log(msg)
can._daemon = arg[0] can._daemon = arg[0]
}, },
}) })
@ -324,11 +331,9 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
can.core.CallFunc(meta[which], [event, can, which]) can.core.CallFunc(meta[which], [event, can, which])
can.core.CallFunc(meta[item[0]], [event, can, item[0], which]) can.core.CallFunc(meta[item[0]], [event, can, item[0], which])
}}: item.input? /*文本*/ {type: "input", name: item.input[0], onkeydown: function(event) { }}: /*其它*/ item
can.core.CallFunc(item.input[1], [event, can])
}}: typeof item == "object" && /*其它*/ item
, "", action)}) , "", action)})
return meta
}, },
_output: function(can, meta, event, cmds, cb, silent) { _output: function(can, meta, event, cmds, cb, silent) {
var msg = can.request(event); can.page.Select(can, can._output, "div.control .args", function(item) { var msg = can.request(event); can.page.Select(can, can._output, "div.control .args", function(item) {
@ -472,6 +477,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
break break
case "button": item.value = item.value||item.name||"查看"; break case "button": item.value = item.value||item.name||"查看"; break
case "upfile": item.type = "file"; break case "upfile": item.type = "file"; break
case "upload": item.type = "file", input.name = "upload"; break
} }
return can.page.Append(can, target, [{view: ["item "+item.type], list: [input]}])[item.name] return can.page.Append(can, target, [{view: ["item "+item.type], list: [input]}])[item.name]
@ -520,31 +526,23 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
}, },
figure: function(can, meta, key, target) { figure: function(can, meta, key, target) {
if (!key || key.indexOf("@") != 0) { return } if (!key || key[0] != "@") { return }
var list = can.core.Split(key, "@=", "@=") var list = can.core.Split(key, "@=", "@=")
var pkey = list[0], pval = list[1]||"" var pkey = list[0], pval = list[1]||""
target.type != "button" && target.value && target.value.indexOf("@") == 0 && (target.value = pval||"") target.type != "button" && (target.value = pval||""), can.require(["/plugin/input/"+pkey+".js"], function(can) {
pkey && can.require(["/plugin/input/"+pkey+".js"], function(can) { can.core.Item(can.onfigure[pkey], function(key, cb) { if (key.indexOf("on") == 0) { target[key] = function(event) {
can.onfigure && can.core.Item(can.onfigure[pkey], function(key, cb) { if (key.indexOf("on") == 0) {
target[key] = function(event) { can._figure && can.page.Remove(can, can._figure._target)
can.onappend._init(can, {type: "input", name: pkey, pos: "float"}, [], function(sub) { can.onappend._init(can, {type: "input", name: pkey, pos: "float"}, [], function(sub) {
sub.Conf(meta), sub.run = function(event, cmds, cb) { sub.run = function(event, cmds, cb) {
var msg = sub.request(event, can.Option()); var msg = sub.request(event, can.Option());
(meta.run||can.run)(event, cmds, cb, true) (meta.run||can.run)(event, cmds, cb, true)
}, can._figure = sub }, sub.Conf(meta)
Volcanos.meta.float.input && can.page.Remove(can, Volcanos.meta.float.input._target), Volcanos.meta.float.input = sub
meta.style && sub.page.Modify(sub, sub._target, {style: meta.style}) meta.style && sub.page.Modify(sub, sub._target, {style: meta.style})
var left = event.clientX-event.offsetX, top = event.clientY-event.offsetY+event.target.offsetHeight
var left = event.clientX, top = event.clientY
if (left+sub._target.offsetWidth>window.innerWidth) { left = window.innerWidth - sub._target.offsetWidth }
can.page.Modify(can, sub._target, {style: {left: left, top: top}})
cb(event, sub, meta, target) cb(event, sub, meta, target)
}, document.body) }, document.body)
} } } })
} })
}) })
}, },
_plugin: function(can, value, meta, cb, target) { _plugin: function(can, value, meta, cb, target) {
@ -612,20 +610,15 @@ Volcanos("onlayout", {help: "页面布局", list: [], _init: function(can) {
topic: function(can, topic) { topic && (can._topic = topic) topic: function(can, topic) { topic && (can._topic = topic)
can.user.topic(can, can._topic || can.user.Search(can, "topic") || ((can.user.Search(can, "pod")||can.base.isNight())? "black": "white")) can.user.topic(can, can._topic || can.user.Search(can, "topic") || ((can.user.Search(can, "pod")||can.base.isNight())? "black": "white"))
}, },
figure: function(event, can, target) { var p = target||can._target figure: function(event, can, target) { target = target||can._target
var layout = {left: event.clientX, top: event.clientY+10} if (!event.target) { return }
can.page.Modify(can, p, {style: layout}) var left = event.clientX-event.offsetX, top = event.clientY-event.offsetY+event.target.offsetHeight
can.onmotion.move(can, p, layout) if (left+target.offsetWidth>window.innerWidth) { left = window.innerWidth - target.offsetWidth }
if (top+target.offsetHeight>window.innerHeight) { top = window.innerHeight - target.offsetHeight }
var left = p.offsetLeft; if (p.offsetLeft+p.offsetWidth > window.innerWidth) { var layout = {left: left, top: top}
left = window.innerWidth - p.offsetWidth can.page.Modify(can, target, {style: layout})
} if (left < 120) { left = 120 } can.onmotion.move(can, target, layout)
var top = p.offsetTop; if (p.offsetTop+p.offsetHeight > window.innerHeight) {
top = window.innerHeight - p.offsetHeight
} if (top < 32) { top = 32 }
can.page.Modify(can, p, {style: {left: can.user.isMobile? 30: left, top: top+30}})
}, },
resize: function(can, name, cb) { resize: function(can, name, cb) {
var list = []; can.onengine.listen(can, name, function(width, height) { var list = []; can.onengine.listen(can, name, function(width, height) {
@ -667,155 +660,7 @@ Volcanos("onlayout", {help: "页面布局", list: [], _init: function(can) {
]}]) ]}])
}, },
}) })
Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, target) { Volcanos("onmotion", {help: "动态特效", list: [], _init: function(can, target) {
var focus = []; can.onengine.listen(can, "keymap.focus", function(cb) {
cb? focus.push(cb): focus.pop()
})
can.onkeypop._build(can)
target.onkeydown = function(event) {
if (focus.length > 0) { return focus[focus.length-1](event) }
if (event.target != target) { return }
can.page.Select(can, target, "fieldset.Action>div.output", function(item) {
target._keys = can.onkeypop._parse(event, can, "normal", target._keys||[], item)
})
}
},
_build: function(can) {
can.core.Item(can.onkeypop._mode, function(item, value) { var engine = {}
can.core.Item(value, function(key, cb) { var map = engine
for (var i = key.length-1; i > -1; i--) {
map = map[key[i]] = i == 0? cb: (map[key[i]]||{})
}
}), can.onkeypop._engine[item] = engine
})
},
_parse: function(event, can, mode, list, target) { list = list||[], list.push(event.key)
// can.Status("按键", list.join(""))
for (var pre = 0; pre < list.length; pre++) {
if ("0" <= list[pre] && list[pre] <= "9") { continue } break
}; var count = parseInt(list.slice(0, pre).join(""))||1
function repeat(cb, count) { list = []
for (var i = 1; i <= count; i++) { if (cb(event, can, target, count)) { break } }
event.stopPropagation(), event.preventDefault()
// can.Status("按键", list.join(""))
}
var map = can.onkeypop._mode[mode]
var cb = map && map[event.key]; if (can.base.isFunc(cb) && event.key.length > 1) {
repeat(cb, count); return list
}
var cb = map && map[event.key.toLowerCase()]; if (can.base.isFunc(cb) && event.key.length > 1) {
repeat(cb, count); return list
}
var map = can.onkeypop._engine[mode]; for (var i = list.length-1; i > pre-1; i--) {
var cb = map[list[i]]; switch (typeof cb) {
case "function": repeat(cb, count); return list
case "object": map = cb; continue
case "string":
default: return list
}
}
return list
},
_mode: {
normal: {
j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) },
k: function(event, can, target) { target.scrollBy(0, -30) },
b: function(event, can, target) { can.search(event, ["Header.onaction.black"]) },
w: function(event, can, target) { can.search(event, ["Header.onaction.white"]) },
s: function(event, can, target) { can.search(event, ["River.ondetail.添加应用"]) },
t: function(event, can, target) { can.search(event, ["River.ondetail.添加工具"]) },
" ": function(event, can, target) {
can.page.Select(can, document.body, "fieldset.panel.Header div.search input", function(target) {
target.focus()
})
},
enter: function(event, can, target) { can.base.Log("enter") },
escape: function(event, can, target) {
can.search(event, ["Search.onaction.hide"])
can.base.Log("enter")
},
},
insert: {
escape: function(event, can, target) {
target.blur()
},
jk: function(event, can, target) {
can.page.DelText(target, target.selectionStart-1, target.selectionStart)
target.blur()
},
enter: function(event, can, target) {
var his = target._history || []
his.push(target.value)
can.base.Log("input", target, his)
target.setSelectionRange(0, -1)
target._current = his.length
target._history = his
},
},
insert_ctrl: {
p: function(event, can, target) {
var his = target._history||[]
var pos = target._current||0
pos = --pos % (his.length+1)
if (pos < 0) { pos = his.length}
target.value = his[pos]||""
can.base.Log(pos, his)
target._current = pos
},
n: function(event, can, target) {
var his = target._history||[]
var pos = target._current||0
pos = ++pos % (his.length+1)
target.value = his[pos]||""
can.base.Log(pos, his)
target._current = pos
},
u: function(event, can, target) {
can.page.DelText(target, 0, target.selectionEnd)
},
k: function(event, can, target) {
can.page.DelText(target, target.selectionStart)
},
h: function(event, can, target) {
can.page.DelText(target, target.selectionStart-1, target.selectionStart)
},
d: function(event, can, target) {
can.page.DelText(target, 0, target.selectionStart)
},
w: function(event, can, target) {
var start = target.selectionStart-2
var end = target.selectionEnd-1
for (var i = start; i >= 0; i--) {
if (target.value[end] == " " && target.value[i] != " ") {
break
}
if (target.value[end] != " " && target.value[i] == " ") {
break
}
}
can.page.DelText(target, i+1, end-i)
},
},
}, _engine: {},
input: function(event, can) { var target = event.target
target._keys = can.onkeypop._parse(event, can, event.ctrlKey? "insert_ctrl": "insert", target._keys||[], target)
if (target._keys.length == 0) { event.stopPropagation(), event.preventDefault() }
},
})
Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can, target) {
if ((can.user.Search(can, "topic")||"").indexOf("print") > -1) { return } if ((can.user.Search(can, "topic")||"").indexOf("print") > -1) { return }
return return
@ -854,6 +699,10 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can, targe
}) })
}, },
focus: function(can, target) {
target.setSelectionRange(0, -1)
target.focus()
},
clear: function(can, target) { clear: function(can, target) {
can.page.Modify(can, target||can._output, "") can.page.Modify(can, target||can._output, "")
}, },
@ -882,7 +731,7 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can, targe
can.page.Modify(can, target||can._target, {style: {display: "none"}}) can.page.Modify(can, target||can._target, {style: {display: "none"}})
}, },
toggle: function(can, target) { toggle: function(can, target) {
return can.page.Toggle(can, target||can._target) return can.onmotion.Toggle(can, target||can._target)
}, },
select: function(can, target, name, which) { select: function(can, target, name, which) {
can.page.Select(can, target, name, function(item, index) { can.page.Select(can, target, name, function(item, index) {
@ -971,7 +820,6 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can, targe
can.page.Modify(can, target, {style: {width: begin+=space}}) can.page.Modify(can, target, {style: {width: begin+=space}})
}) })
}, },
autosize: function(can, target, max, min) { autosize: function(can, target, max, min) {
can.page.Modify(can, target, { can.page.Modify(can, target, {
onfocus: function(event) { onfocus: function(event) {
@ -984,6 +832,325 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can, targe
can.onmotion.resize(can, target, min, 5) can.onmotion.resize(can, target, min, 5)
}, },
}) })
},
EnableDrop: function(can, parent, search, target) {
return can.page.Modify(can, target, { draggable: true,
ondragstart: function(event) { var target = event.target; can.drop = function(event, tab) {
parent.insertBefore(target, tab)
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
})
} },
ondragover: function(event) { event.preventDefault()
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
}), can.page.ClassList.add(can, event.target, "over")
},
ondrop: function(event) { event.preventDefault()
can.drop(event, event.target)
},
})
},
Resizes: function(event, item, begin, p0, p1, pos) {
switch (pos) {
case 5:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("y", begin.y + p1.y - p0.y)
return
} }
switch (pos) {
case 1:
case 2:
case 3:
item.Value("y", begin.y + p1.y - p0.y)
item.Value("height", begin.height - p1.y + p0.y)
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("width", begin.width - p1.x + p0.x)
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.Value("width", begin.width + p1.x - p0.x)
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.Value("height", begin.height + p1.y - p0.y)
break
}
},
Resize: function(event, item, begin, pos) {
switch (pos) {
case 5:
item.style.left = begin.left + event.clientX - begin.x + "px"
item.style.top = begin.top + event.clientY - begin.y + "px"
return
}
switch (pos) {
case 1:
case 2:
case 3:
item.style.top = begin.top + event.clientY - begin.y + "px"
item.style.height = begin.height - event.clientY + begin.y + "px"
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.style.left = begin.left + event.clientX - begin.x + "px"
item.style.width = begin.width - event.clientX + begin.x + "px"
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.style.width = begin.width + event.clientX - begin.x + "px"
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.style.height = begin.height + event.clientY - begin.y + "px"
break
}
},
Anchor: function(event, target, pos, point) {
switch (pos) {
case 1:
case 2:
case 3:
point.y = target.Val("y")
break
case 4:
case 5:
case 6:
point.y = target.Val("y") + target.Val("height") / 2
break
case 7:
case 8:
case 9:
point.y = target.Val("y") + target.Val("height")
break
}
switch (pos) {
case 1:
case 4:
case 7:
point.x = target.Val("x")
break
case 2:
case 5:
case 8:
point.x = target.Val("x") + target.Val("width") / 2
break
case 3:
case 6:
case 9:
point.x = target.Val("x") + target.Val("width")
break
}
return point
},
Prepos: function(event, item, p, q) {
var max = 20
p = p || item.getBoundingClientRect()
q = q || {x: event.clientX, y: event.clientY}
var pos = 5
var y = (q.y - p.y) / p.height
if (y < 0.2 && q.y - p.y < max) {
pos -= 3
} else if (y > 0.8 && q.y - p.y - p.height > -max) {
pos += 3
}
var x = (q.x - p.x) / p.width
if (x < 0.2 && q.x - p.x < max) {
pos -= 1
} else if (x > 0.8 && q.x - p.x - p.width > -max) {
pos += 1
}
var cursor = [
"nw-resize", "n-resize", "ne-resize",
"w-resize", "move", "e-resize",
"sw-resize", "s-resize", "se-resize",
]
item.style.cursor = cursor[pos-1]
return pos
},
Toggle: function(can, target, show, hide) { var status = target.style.display == "none"
can.page.Modify(can, target, {style: {display: status? "": "none"}})
status? typeof show == "function" && show(): typeof hide == "function" && hide()
return status
},
})
Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, target) {
var focus = []; can.onengine.listen(can, "keymap.focus", function(cb) {
cb? focus.push(cb): focus.pop()
})
can.onkeypop._build(can)
target.onkeydown = function(event) {
if (focus.length > 0) { return focus[focus.length-1](event) }
if (event.target != target) { return }
can.page.Select(can, target, "fieldset.Action>div.output", function(item) {
target._keys = can.onkeypop._parse(event, can, "normal", target._keys||[], item)
})
}
},
_build: function(can) {
can.core.Item(can.onkeypop._mode, function(item, value) { var engine = {}
can.core.Item(value, function(key, cb) { var map = engine
for (var i = key.length-1; i > -1; i--) {
map = map[key[i]] = i == 0? cb: (map[key[i]]||{})
}
}), can.onkeypop._engine[item] = engine
})
},
_parse: function(event, can, mode, list, target) { list = list||[], list.push(event.key)
// can.Status("按键", list.join(""))
for (var pre = 0; pre < list.length; pre++) {
if ("0" <= list[pre] && list[pre] <= "9") { continue } break
}; var count = parseInt(list.slice(0, pre).join(""))||1
function repeat(cb, count) { list = []
for (var i = 1; i <= count; i++) { if (cb(event, can, target, count)) { break } }
event.stopPropagation(), event.preventDefault()
// can.Status("按键", list.join(""))
}
var map = can.onkeypop._mode[mode]
var cb = map && map[event.key]; if (can.base.isFunc(cb) && event.key.length > 1) {
repeat(cb, count); return list
}
var cb = map && map[event.key.toLowerCase()]; if (can.base.isFunc(cb) && event.key.length > 1) {
repeat(cb, count); return list
}
var map = can.onkeypop._engine[mode]; for (var i = list.length-1; i > pre-1; i--) {
var cb = map[list[i]]; switch (typeof cb) {
case "function": repeat(cb, count); return list
case "object": map = cb; continue
case "string":
default: return list
}
}
return list
},
_mode: {
normal: {
j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) },
k: function(event, can, target) { target.scrollBy(0, -30) },
b: function(event, can, target) { can.search(event, ["Header.onaction.black"]) },
w: function(event, can, target) { can.search(event, ["Header.onaction.white"]) },
s: function(event, can, target) { can.search(event, ["River.ondetail.添加应用"]) },
t: function(event, can, target) { can.search(event, ["River.ondetail.添加工具"]) },
" ": function(event, can, target) {
can.page.Select(can, document.body, "fieldset.panel.Header div.search input", function(target) {
target.focus()
})
},
enter: function(event, can, target) { can.misc.Log("enter") },
escape: function(event, can, target) {
can.search(event, ["Search.onaction.hide"])
can.misc.Log("enter")
},
},
insert: {
escape: function(event, can, target) {
target.blur()
},
jk: function(event, can, target) {
can.onkeypop.DelText(target, target.selectionStart-1, target.selectionStart)
target.blur()
},
enter: function(event, can, target) {
var his = target._history || []
his.push(target.value)
can.misc.Log("input", target, his)
target.setSelectionRange(0, -1)
target._current = his.length
target._history = his
},
},
insert_ctrl: {
p: function(event, can, target) {
var his = target._history||[]
var pos = target._current||0
pos = --pos % (his.length+1)
if (pos < 0) { pos = his.length}
target.value = his[pos]||""
can.misc.Log(pos, his)
target._current = pos
},
n: function(event, can, target) {
var his = target._history||[]
var pos = target._current||0
pos = ++pos % (his.length+1)
target.value = his[pos]||""
can.misc.Log(pos, his)
target._current = pos
},
u: function(event, can, target) {
can.onkeypop.DelText(target, 0, target.selectionEnd)
},
k: function(event, can, target) {
can.onkeypop.DelText(target, target.selectionStart)
},
h: function(event, can, target) {
can.onkeypop.DelText(target, target.selectionStart-1, target.selectionStart)
},
d: function(event, can, target) {
can.onkeypop.DelText(target, 0, target.selectionStart)
},
w: function(event, can, target) {
var start = target.selectionStart-2
var end = target.selectionEnd-1
for (var i = start; i >= 0; i--) {
if (target.value[end] == " " && target.value[i] != " ") {
break
}
if (target.value[end] != " " && target.value[i] == " ") {
break
}
}
can.onkeypop.DelText(target, i+1, end-i)
},
},
}, _engine: {},
DelText: function(target, start, count) {
target.value = target.value.substring(0, start)+target.value.substring(start+(count||target.value.length), target.value.length)
target.setSelectionRange(start, start)
},
input: function(event, can) { var target = event.target
target._keys = can.onkeypop._parse(event, can, event.ctrlKey? "insert_ctrl": "insert", target._keys||[], target)
if (target._keys.length == 0) { event.stopPropagation(), event.preventDefault() }
},
}) })

View File

@ -1,6 +1,7 @@
Volcanos("base", {help: "数据类型", Volcanos("base", {help: "数据类型",
isFunc: function(cb) { return typeof cb == "function" }, Int: function(value, def) {
Int: function(value, def) { return parseInt(value)||def||0 }, return parseInt(value)||def||0
},
Obj: function(value, def) { Obj: function(value, def) {
try { try {
return (typeof value == "string" && value != ""? JSON.parse(value): value) || def || {} return (typeof value == "string" && value != ""? JSON.parse(value): value) || def || {}
@ -9,8 +10,7 @@ Volcanos("base", {help: "数据类型",
} }
}, },
Copy: function(to, from, fields) { Copy: function(to, from, fields) {
var list = [] var list = []; for (var i = 2; i < arguments.length; i++) {
for (var i = 2; i < arguments.length; i++) {
list.push(arguments[i]) list.push(arguments[i])
} }
@ -18,24 +18,26 @@ Volcanos("base", {help: "数据类型",
to[list[i]] = from[list[i]] to[list[i]] = from[list[i]]
} }
}, },
Eq: function(obj, other) { var self = arguments.callee Eq: function(to, from) { var self = arguments.callee
if (typeof obj != typeof other) { return false } if (typeof to != typeof from) { return false }
if (typeof obj == "object") { if (typeof to == "object") {
if (obj.length != other.length) { return false } if (to.length != from.length) { return false }
for (var i = 0; i < obj.length; i++) { for (var i = 0; i < to.length; i++) {
if (!self(obj[i], other[i])) { return false } if (!self(to[i], from[i])) { return false }
} }
for (var k in obj) { for (var k in to) {
if (!self(obj[k], other[k])) { return false } if (!self(to[k], from[k])) { return false }
} }
return true return true
} }
return obj === other return to === from
}, },
Ext: function(file) { return (file.split("/").pop().split(".").pop()).toLowerCase() }, Ext: function(file) {
return (file.split("/").pop().split(".").pop()).toLowerCase()
},
Path: function() { var res = "" Path: function() { var res = ""
for (var i = 0; i < arguments.length; i++) { for (var i = 0; i < arguments.length; i++) {
res += (arguments[i][0]=="/" || res=="" || res[res.length-1]=="/"? "": "/") + arguments[i].trim() res += (arguments[i][0]=="/" || res=="" || res[res.length-1]=="/"? "": "/") + arguments[i].trim()
@ -56,20 +58,19 @@ Volcanos("base", {help: "数据类型",
}) })
for (var i = 1; i < arguments.length; i++) { for (var i = 1; i < arguments.length; i++) {
switch (typeof arguments[i]) { switch (typeof arguments[i]) {
case "string":
args[arguments[i]] = arguments[i+1], i++
break
case "object": case "object":
if (arguments[i].length > 0) { if (arguments[i].length > 0) {
for (var j = 0; j < arguments[i].length; j += 2) { for (var j = 0; j < arguments[i].length; j += 2) {
args[arguments[i][j]] = arguments[i][j] args[arguments[i][j]] = arguments[i][j]
} }
break } else {
}
for (var k in arguments[i]) { for (var k in arguments[i]) {
args[k] = arguments[i][k] args[k] = arguments[i][k]
} }
break }
case "string":
args[arguments[i]] = arguments[i+1]
i++
break break
} }
} }
@ -79,6 +80,45 @@ Volcanos("base", {help: "数据类型",
return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "") return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "")
}, },
Size: function(size) {size = parseInt(size)
if (size > 1000000000) {
return parseInt(size / 1000000000) + "." + parseInt(size / 10000000 % 100) + "G"
}
if (size > 1000000) {
return parseInt(size / 1000000) + "." + parseInt(size / 10000 % 100) + "M"
}
if (size > 1000) {
return parseInt(size / 1000) + "." + parseInt(size / 10 % 100) + "K"
}
return size + "B"
},
Number: function(d, n) { var result = []
while (d > 0) { result.push(d % 10); d = parseInt(d / 10); n-- }
while (n > 0) { result.push("0"); n-- }
return result.reverse(), result.join("")
},
Format: function(obj) {
return JSON.stringify(obj)
},
Simple: function() { var res = []
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]; switch (typeof arguments[i]) {
case "number": res.push(arg); break
case "string": res.push(arg); break
case "object":
if (arg.length > 0) {
res = res.concat(arg)
} else {
for (var k in arg) { res.push(k, arg[k]) }
}
}
}
return res
},
AddUniq: function(list, value) { list = list || []
return list.indexOf(value) > -1 && list.push(value), list
},
Date: function(time) { var now = new Date() Date: function(time) { var now = new Date()
if (typeof time == "string" && time != "") { var ls = time.split(" ") if (typeof time == "string" && time != "") { var ls = time.split(" ")
var vs = ls[0].split("-") var vs = ls[0].split("-")
@ -95,7 +135,7 @@ Volcanos("base", {help: "数据类型",
} }
return now return now
}, },
Time: shy("时间格式化", function(time, fmt) { var now = this.Date(time) Time: function(time, fmt) { var now = this.Date(time)
var list = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] var list = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
fmt = fmt || "%y-%m-%d %H:%M:%S" fmt = fmt || "%y-%m-%d %H:%M:%S"
fmt = fmt.replace("%y", now.getFullYear()) fmt = fmt.replace("%y", now.getFullYear())
@ -106,7 +146,10 @@ Volcanos("base", {help: "数据类型",
fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2)) fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2))
fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2)) fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2))
return fmt return fmt
}), },
TimeAdd: function(t, d) {
return new Date(t - t%(24*3600*1000) - 8*3600*1000 + d*24*3600*1000)
},
Duration: function(n) { var res = "", h = 0 Duration: function(n) { var res = "", h = 0
h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24) h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24)
h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000 h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000
@ -114,40 +157,22 @@ Volcanos("base", {help: "数据类型",
h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000 h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000
return res + (n > 0? "."+parseInt(n/10): "") + "s" return res + (n > 0? "."+parseInt(n/10): "") + "s"
}, },
Format: shy("数据格式化", function(obj) { return JSON.stringify(obj) }),
Simple: function() { var res = []
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]; switch (typeof arguments[i]) {
case "number": res.push(arg); break
case "string": res.push(arg); break
case "object":
if (arg.length > 0) {
res = res.concat(arg)
} else {
for (var k in arg) { res.push(k, arg[k]) }
}
}
}
return res
},
Number: shy("数字格式化", function(d, n) { var result = []
while (d > 0) { result.push(d % 10); d = parseInt(d / 10); n-- }
while (n > 0) { result.push("0"); n-- }
return result.reverse(), result.join("")
}),
Size: function(size) {size = parseInt(size)
if (size > 1000000000) {
return parseInt(size / 1000000000) + "." + parseInt(size / 10000000 % 100) + "G"
}
if (size > 1000000) {
return parseInt(size / 1000000) + "." + parseInt(size / 10000 % 100) + "M"
}
if (size > 1000) {
return parseInt(size / 1000) + "." + parseInt(size / 10 % 100) + "K"
}
return size + "B"
},
parseSize: function(size) { size = size.toLowerCase()
if (size.endsWith("tb") || size.endsWith("t")) {
return parseInt(size) * 1024 * 1024 * 1024 * 1024
}
if (size.endsWith("gb") || size.endsWith("g")) {
return parseInt(size) * 1024 * 1024 * 1024
}
if (size.endsWith("mb") || size.endsWith("m")) {
return parseInt(size) * 1024 * 1024
}
if (size.endsWith("kb") || size.endsWith("k")) {
return parseInt(size) * 1024
}
return parseInt(size)
},
parseJSON: function(str) { var res parseJSON: function(str) { var res
if (typeof str == "object") { return str } if (typeof str == "object") { return str }
if (str.indexOf("http") == 0) { var ls = str.split("?") if (str.indexOf("http") == 0) { var ls = str.split("?")
@ -166,54 +191,11 @@ Volcanos("base", {help: "数据类型",
} }
return res return res
}, },
parseSize: function(size) { size = size.toLowerCase()
if (size.endsWith("tb") || size.endsWith("t")) {
return parseInt(size) * 1024 * 1024 * 1024 * 1024
}
if (size.endsWith("gb") || size.endsWith("g")) {
return parseInt(size) * 1024 * 1024 * 1024
}
if (size.endsWith("mb") || size.endsWith("m")) {
return parseInt(size) * 1024 * 1024
}
if (size.endsWith("kb") || size.endsWith("k")) {
return parseInt(size) * 1024
}
return parseInt(size)
},
isNight: function() { var now = new Date() isNight: function() { var now = new Date()
return now.getHours() < 7 || now.getHours() > 17 return now.getHours() < 7 || now.getHours() > 17
}, },
TimeAdd: shy("时间格式化", function(t, d) { isFunc: function(cb) {
return new Date(t - t%(24*3600*1000) - 8*3600*1000 + d*24*3600*1000) return typeof cb == "function"
}),
Debug: function() {
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3), "debug"]
for (var i in arguments) { args.push(arguments[i]) }
args.push(this.fileLine(2, 3))
console.log.apply(console, args)
},
Warn: function() {
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3), "warn"]
for (var i in arguments) { args.push(arguments[i]) }
args.push("\n", this._fileLine().split("\n").slice(2).join("\n"))
console.log.apply(console, args)
},
Log: function() {
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3)]
for (var i in arguments) { args.push(arguments[i]) }
console.log.apply(console, args)
},
FileLine: function(depth, length) {
return this.fileLine(depth+1).split("/").slice(3).slice(-length).join("/").split(")")[0]
},
fileLine: function(depth) {
return (this._fileLine().split("\n")[1+depth]||"").trim()
},
_fileLine: function() { var obj = {}
Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee)
return obj.stack || ""
}, },
}) })

View File

@ -1,150 +1,14 @@
Volcanos("core", {help: "数据结构", Volcanos("core", {help: "数据结构",
Split: shy("分词器", function(str) { if (!str || !str.length) { return [] } Keys: shy("连接器", function() { var list = []
var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) {
typeof arguments[i] == "object"? opt = arguments[i]: arg.push(arguments[i])
}
function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res }
// 空白符
var seps = _list(arg[0]||"\t ,\n")
// 分隔符
var sups = _list(arg[1]||"{[(.:)]}")
// 引用符
var subs = _list(arg[2]||"'\"`")
// 开始分词
var res = [], list = str
var left = "", space = true, begin = 0
for (var i = 0; i < list.length; i++) {
if (seps[list[i]]) {
// 空白符
if (left == "") {
if (!space) {
res.push(list.slice(begin, i))
}
opt.detail && res.push({text: list.slice(i, i+1), type: "space", left: left})
space = true, begin = i+1
}
} else if (subs[list[i]]) {
// 引用符
if (left == "") {
left = list[i], space = false, begin = i+1
} else if (left == list[i]) {
res.push({text: list.slice(begin, i), type: "string", left: left, right: left})
left = "", space = true, begin = i+1
}
} else if (sups[list[i]]) {
// 分隔符
if (left == "") {
if (!space) {
res.push(list.slice(begin, i))
}
res.push(list.slice(i, i+1))
space = true, begin = i+1
}
} else if (list[0] == '\\') {
// 转义符
for (var i = i; i < list.length-1; i++) {
list[i] = list[i+1]
}
list = list.slice(0, list.length-1)
space = false
} else {
space = false
}
}
// 末尾字符
if (left != "") {
res.push({text: list.slice(begin), type: "string", left: left, right: ""})
} else if (begin < list.length) {
res.push(list.slice(begin))
}
return res
}),
Timer: shy("定时器, value, [1,2,3,4], {interval, length}", function(interval, cb, cbs) {
interval = typeof interval == "object"? interval || []: [interval]
var timer = {stop: false}; function loop(timer, i) {
if (timer.stop || i >= interval.length && interval.length >= 0) {
return typeof cbs == "function" && cbs(timer, interval)
}
return typeof cb == "function" && cb(timer, interval.interval||interval[i], i, interval)?
typeof cbs == "function" && cbs(timer, interval): setTimeout(function() { loop(timer, i+1) }, interval.interval||interval[i+1])
}
if (interval.interval == 0) { cb(); return timer }
setTimeout(function() { loop(timer, 0) }, interval.interval||interval[0])
return timer
}),
Delay: shy("延时器", function(list, interval, cb, cbs) {
list.push(cb); this.Timer(interval, function() {
var cb = list.pop(); list.length = 0
typeof cb == "function" && cb()
}, cbs)
}),
Items: shy("迭代器", function(obj, cb) { var list = []
for (var key in obj) {
list = list.concat(this.List(obj[key], function(value, index, array) {
return typeof cb == "function" && cb(value, index, key, obj)
}))
}
return list
}),
Item: shy("迭代器", function(obj, cb) { var list = []
for (var k in obj) {
var res = typeof cb == "function"? cb(k, obj[k]): k
res && list.push(res)
}
return list
}),
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)
}
obj.length > 0 && setTimeout(function() { loop(0) }, interval/4)
return obj
}
var list = [], res
for (var i = 0; i < obj.length; i++) {
typeof cb == "function"? (res = cb(obj[i], i, obj)) != undefined && list.push(res): list.push(obj[i])
}
return list
}),
Next: shy("迭代器", function(obj, cb, cbs) { obj = typeof obj == "string"? [obj]: (obj || [])
function next(list, cb, index) {
list && list.length > 0? typeof cb == "function" && cb(list[0], function() {
list.length > 0 && next(list.slice(1), cb, index+1)
}, index, obj): typeof cbs == "function" && cbs()
}
next(obj, cb, 0)
}),
Keys: shy("生成器", function() { var list = []
for (var i = 0; i < arguments.length; i++) { var v = arguments[i] for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
switch (typeof v) { switch (typeof v) {
case "number": list.push(v+""); break case "object":
case "string": list.push(v); break for (var j = 0; j < v.length; j++) {
case "object": list.push(arguments.callee.apply(this, v)); break // list.push(arguments.callee.apply({}, v[j]))
case "function": list.push(v()); break list.push(v[j])
}
break
case "function": v = v()
default: v && list.push(v+"") default: v && list.push(v+"")
} }
} }
@ -153,6 +17,7 @@ Volcanos("core", {help: "数据结构",
Value: shy("存储器", function(data, key, value) { Value: shy("存储器", function(data, key, value) {
if (data == undefined) { return } if (data == undefined) { return }
if (key == undefined) { return data } if (key == undefined) { return data }
if (typeof key == "object") { for (var k in key) { if (typeof key == "object") { for (var k in key) {
arguments.callee.call(this, data, k, key[k]) arguments.callee.call(this, data, k, key[k])
}; return data } }; return data }
@ -165,17 +30,65 @@ Volcanos("core", {help: "数据结构",
p = p[ls[0]], ls = ls.slice(1) p = p[ls[0]], ls = ls.slice(1)
}; return p }; return p
}), }),
CallFunc: shy("调用器", function(func, args, mod) { args = args||{} Split: shy("分词器", function(str) { if (!str || !str.length) { return [] }
var can = args["can"]||args[0], msg = args["msg"]||args[1] var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) {
var cmds = args["cmds"]||[] typeof arguments[i] == "object"? opt = arguments[i]: arg.push(arguments[i])
}
// 字符定义
function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res }
var soos = _list("\\") // 转义符
var seps = _list(arg[0]||"\t ,;\n") // 空白符
var subs = _list(arg[1]||"{[(.:)]}") // 分隔符
var sups = _list(arg[2]||"'\"`") // 引用符
var res = [], begin = 0; function push(obj) {
obj != "" && res.push(typeof obj == "string" || opt.detail? obj: obj.text), begin = -1
}
// 开始分词
for (var s = "", i = 0; i < str.length; i++) {
if (soos[str[i]]) { // 转义符
begin == -1 && (begin = i++)
} else if (seps[str[i]]) { // 空白符
if (s) { continue }
begin > -1 && push(str.slice(begin, i))
opt.detail && push({type: "space", text: str.slice(i, i+1)})
} else if (subs[str[i]]) { // 分隔符
if (s) { continue }
begin > -1 && push(str.slice(begin, i))
push(str.slice(i, i+1))
} else if (sups[str[i]]) { // 引用符
if (s == "") {
s = str[i], begin = i+1
} else if (s == str[i]) {
push({type: "string", text: str.slice(begin, i), left: s, right: str[i]})
s = "", begin = -1
}
} else { // 普通符
begin == -1 && (begin = i)
}
}
// 剩余字符
begin > 0 && (s? push({type: "string", text: str.slice(begin), left: s, right: ""})
: push(str.slice(begin)))
return res
}),
CallFunc: shy("调用器", function(func, args, mod) { args = args || {}
func = typeof func == "function"? func: typeof func == "string"? this.Value(mod||can, func): func = typeof func == "function"? func: typeof func == "string"? this.Value(mod||can, func):
typeof func == "object" && func.slice? this.Value(func[0], this.Keys(func.slice(1))): null typeof func == "object" && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): null
if (typeof func != "function") { return } if (typeof func != "function") { return }
var cb = args["cb"] var can = args["can"]||args[0], msg = args["msg"]||args[1], cmds = args["cmds"]||[]
var ls = func.toString().split(")")[0].split("(")[1].split(",")
var list = [], echo = false; this.List(ls, function(item, index) { item = item.trim() var list = [], echo = false, cb = args["cb"]
this.List(func.toString().split(")")[0].split("(")[1].split(","), function(item, index) { item = item.trim()
list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || cmds[index] || args[index] || null) list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || cmds[index] || args[index] || null)
if (item == "cb") { echo = true } if (item == "cb") { echo = true }
}) })
@ -184,5 +97,78 @@ Volcanos("core", {help: "数据结构",
if (!echo && typeof cb == "function") { res && msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } if (!echo && typeof cb == "function") { res && msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) }
return res return res
}), }),
List: shy("迭代器", function(list, cb, interval, cbs) { list = list || []
if (typeof list == "string") { // 默认序列
list = [list]
} else if (typeof list == "number") { // 等差序列
var begin = 0, end = list, step = typeof interval == "number"? interval: 1
if (typeof cb == "number") { begin = list, end = cb, cb = null }
list = []; for (var i = begin; i < end; i += step) {
list.push(i)
}
}
if (interval > 0) { // 时间序列
function loop(i) { if (i >= list.length) { return typeof cbs == "function" && cbs(list) }
cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval)
}
typeof cb == "function" && list.length > 0 && setTimeout(function() { loop(0) }, interval/4)
} else { // 选择序列
var slice = [], res
for (var i = 0; i < list.length; i++) {
typeof cb == "function" && (res = cb(list[i], i, list)) != undefined? slice.push(res): slice.push(list[i])
}
list = slice
}
return list
}),
Next: shy("迭代器", function(list, cb, cbs) {
function next(i) {
i < list.length? cb(list[i], function(skip) {
next(i+1+(skip||0))
}, i, list): typeof cbs == "function" && cbs(list)
}
list = typeof list == "object"? list: [list]
list && list.length > 0 && typeof cb == "function"? next(0): typeof cbs == "function" && cbs(list)
}),
Timer: shy("定时器, value, [1,2,3,4], {interval, length}", function(interval, cb, cbs) {
var timer = {stop: false}; function loop(i) {
timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)?
typeof cbs == "function" && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1])
}
interval = typeof interval == "object"? interval: [interval]
if (interval.interval == 0) { cb(); return timer }
typeof cb == "function" && setTimeout(function() { loop(0) }, interval.interval||interval[0])
return timer
}),
Delay: shy("延时器", function(list, interval, cb, cbs) {
list.push(cb); this.Timer(interval, function() {
var cb = list.pop(); list.length = 0
typeof cb == "function" && cb()
}, cbs)
}),
Items: shy("迭代器", function(obj, cb) { var list = []
for (var k in obj) {
list = list.concat(this.List(obj[k], function(v, i) {
return typeof cb == "function" && cb(v, i, k, obj)
}))
}
return list
}),
Item: shy("迭代器", function(obj, cb) { var list = []
for (var k in obj) {
var res = typeof cb == "function"? cb(k, obj[k]): k
res != undefined && list.push(res)
}
return list
}),
}) })

View File

@ -4,36 +4,38 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
if (key == undefined) { return msg && msg.option || [] } if (key == undefined) { return msg && msg.option || [] }
if (typeof key == "object") { can.core.Item(key, msg.Option) } if (typeof key == "object") { can.core.Item(key, msg.Option) }
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" } if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
msg.option = msg.option || [], can.core.List(msg.option, function(k) { if (k == key) { return k } }).length > 0 || msg.option.push(key) return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val
return msg[key] = can.core.List(arguments).slice(1), val
}, },
Append: function(key, val) { Append: function(key, val) {
if (key == undefined) { return msg && msg.append || [] } if (key == undefined) { return msg && msg.append || [] }
if (typeof key == "object") { can.core.Item(key, msg.Append) } if (typeof key == "object") { can.core.Item(key, msg.Append) }
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" } if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
msg.append = msg.append || [], can.core.List(msg.append, function(k) { if (k == key) { return k } }).length > 0 || msg.append.push(key) return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val
return msg[key] = can.core.List(arguments).slice(1), val
}, },
Result: function() { return msg.result && msg.result.join("") || "" }, Result: function() { return msg.result && msg.result.join("") || "" },
Table: function(cb) { if (!msg.append || msg.append.length == 0 || !msg[msg.append[0]]) { return } Length: function() {
var max = "", len = 0; can.core.List(msg.append, function(key, index) {
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length }
})
return len
},
Table: function(cb) { if (!msg.append || msg.append.length == 0) { return }
var max = "", len = 0; can.core.List(msg.append, function(key, index) { var max = "", len = 0; can.core.List(msg.append, function(key, index) {
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length } if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length }
}) })
return can.core.List(msg[max], function(value, index, array) { var one = {}, res return can.core.List(msg[max], function(value, index, array) { var one = {}, res
can.core.List(msg.append, function(key) { one[key] = (msg[key]&&msg[key][index]||"") }) can.core.List(msg.append, function(key) { one[key] = (msg[key]&&msg[key][index]||"") })
return typeof cb == "function" && (res = cb(one, index, array)) && res != undefined && res || one return can.base.isFunc(cb) && (res = cb(one, index, array)) && res != undefined && res || one
}) })
}, },
Clear: function(key) { Clear: function(key) { switch (key) {
switch (key) {
case "append": case "append":
case "option": case "option":
can.core.List(msg[key], function(item) { delete(msg[item]) }) can.core.List(msg[key], function(item) { delete(msg[item]) })
default: msg[key] = [] default: msg[key] = []
} } },
},
Copy: function(res) { if (!res) { return msg } Copy: function(res) { if (!res) { return msg }
res.result && (msg.result = (msg.result||[]).concat(res.result)) res.result && (msg.result = (msg.result||[]).concat(res.result))
res.append && (msg.append = res.append) && res.append.forEach(function(item) { res.append && (msg.append = res.append) && res.append.forEach(function(item) {
@ -44,7 +46,7 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
}) })
return msg return msg
}, },
Push: function(key, value, detail) { msg.append = msg.append || [] Push: function(key, value, detail) {
if (typeof key == "object") { if (typeof key == "object") {
value = value || can.core.Item(key), can.core.List(value, function(item) { value = value || can.core.Item(key), can.core.List(value, function(item) {
detail? msg.Push("key", item).Push("value", key[item]||""): detail? msg.Push("key", item).Push("value", key[item]||""):
@ -53,11 +55,7 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
return msg return msg
} }
for (var i = 0; i < msg.append.length; i++) { msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key] || []
if (msg.append[i] == key) { break }
}; i >= msg.append.length && msg.append.push(key)
msg[key] = msg[key] || []
msg[key].push(typeof value == "string" || typeof value == "function"? value: JSON.stringify(value)) msg[key].push(typeof value == "string" || typeof value == "function"? value: JSON.stringify(value))
return msg return msg
}, },
@ -65,17 +63,12 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) } for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) }
return msg._hand = true, msg return msg._hand = true, msg
}, },
Length: function() { }; msg.__proto__ = proto
return msg.append && msg.append[0] && msg[msg.append[0]] && msg[msg.append[0]].length || 0
},
}
for (var k in proto) { msg[k] = proto[k] }
return msg return msg
}, },
POST: shy("请求后端", {order: 0}, function(can, msg, url, form, cb) { POST: function(can, msg, url, form, cb) {
var xhr = new XMLHttpRequest(); msg._xhr = xhr var xhr = new XMLHttpRequest(); msg._xhr = xhr
xhr.open("POST", url), xhr.onreadystatechange = function() { xhr.open(msg._method||"POST", url), xhr.onreadystatechange = function() {
if (xhr.readyState != 4) { return } if (xhr.readyState != 4) { return }
try { // 解析响应 try { // 解析响应
@ -83,17 +76,16 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
} catch (e) { } catch (e) {
var res = {"result": [xhr.responseText]} var res = {"result": [xhr.responseText]}
} }
xhr.status == 200 && typeof cb == "function" && cb(msg.Copy(res)) xhr.status == 200 && can.base.isFunc(cb) && cb(msg.Copy(res))
} }
if (msg.upload) { // 上传文件 if (msg._upload) { // 上传文件
var data = new FormData() var data = new FormData(); can.core.Items(form, function(value, index, key) {
can.core.Items(form, function(value, index, key) {
data.append(key, value) data.append(key, value)
}), data.append("upload", msg.upload) }), data.append("upload", msg._upload)
xhr.upload.onprogress = function(event) { xhr.upload.onprogress = function(event) {
typeof msg._progress == "function" && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded)
} }
} else { // 请求数据 } else { // 请求数据
var data = can.core.Items(form, function(value, index, key) { var data = can.core.Items(form, function(value, index, key) {
@ -105,48 +97,32 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
// 发送请求 // 发送请求
xhr.setRequestHeader("Accept", "application/json") xhr.setRequestHeader("Accept", "application/json")
try { xhr.send(data) } catch(e) { can.base.Log(e) } try { xhr.send(data) } catch(e) { can.misc.Log(e) }
}), },
Runs: shy("请求后端", {order: 0}, function(event, can, dataset, cmds, cb) { Run: function(event, can, dataset, cmds, cb) {
var key = dataset.names+"."+cmds.join(",") var msg = can.request(event||{})
if (can.user.isLocalFile) { var msg = can.request(event); msg.Clear("append") var form = {cmds: cmds||msg.cmd}; msg.option && msg.option.forEach(function(item) {
var res = Volcanos.meta.pack[key]; res? msg.Copy(res): can.user.toast(can, "缺失数据")
return typeof cb == "function" && cb(msg)
}
can.misc.Run(event, can, dataset, cmds, function(msg) {
Volcanos.meta.pack[key] = msg
typeof cb == "function" && cb(msg)
})
}),
Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmds, cb) {
var msg = can.request(event = event || {})
var form = {cmds: cmds||msg.cmd}
msg.option && msg.option.forEach(function(item) {
msg[item] && (form[item] = msg[item]) msg[item] && (form[item] = msg[item])
}) })
can.misc.POST(can, msg, can.base.MergeURL( can.misc.POST(can, msg, can.base.MergeURL(dataset.names.toLowerCase(),
(can.Conf("iceberg")||"/chat/")+dataset.names.toLowerCase(), "_", (msg._can.sup||msg._can)._name, "_daemon", dataset.daemon,
"_", (msg._can.sup||msg._can)._name, ), form, cb)
"_daemon", dataset.daemon, },
), form, function(msg) { WSS: function(can, args, cb, onopen, onclose, onerror) {
typeof cb == "function" && cb(msg)
})
}),
WSS: shy("请求后端", {order: 0}, function(can, args, cb, onopen, onclose, onerror) {
var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/" var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/"
if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" } if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" }
var socket = new WebSocket(can.base.MergeURL(url, args)) var socket = new WebSocket(can.base.MergeURL(url, args))
socket.onclose = function() { can.base.Log("wss", "close", args) socket.onclose = function() { can.misc.Log("wss", "close", args)
typeof onclose == "function"? onclose(socket): can.core.Timer(1000, function() { can.base.isFunc(onclose)? onclose(socket): can.core.Timer(1000, function() {
can.misc.WSS(can, args, cb, onopen, onerror, onclose) can.misc.WSS(can, args, cb, onopen, onerror, onclose)
}) })
}, socket.onerror = function() { can.base.Log("wss", "error", args) }, socket.onerror = function() { can.misc.Log("wss", "error", args)
typeof onerror == "function"? onerror(socket): socket.close() can.base.isFunc(onerror)? onerror(socket): socket.close()
}, socket.onopen = function() { can.base.Log("wss", "open", args) }, socket.onopen = function() { can.misc.Log("wss", "open", args)
typeof onopen == "function" && onopen(socket) can.base.isFunc(onopen) && onopen(socket)
} }
socket.onmessage = function(event) { socket.onmessage = function(event) {
@ -164,18 +140,49 @@ Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg
delete(msg._event) delete(msg._event)
msg.Option("_handle", true) msg.Option("_handle", true)
msg.Option("_target", msg.Option("_source")) msg.Option("_target", msg.Option("_source"))
can.base.Log("wss", "result", msg.result, msg) can.misc.Log("wss", "result", msg.result, msg)
socket.send(JSON.stringify(msg)) socket.send(JSON.stringify(msg))
}, msg.detail = data.detail, msg.Copy(data) }, msg.detail = data.detail, msg.Copy(data)
try { // 执行命令 // 执行命令
can.base.Log("wss", "detail", msg.detail, msg) try { can.misc.Log("wss", "detail", msg.detail, msg)
typeof cb == "function" && cb(event, msg, msg.detail[0], msg.detail.slice(1)) can.isFunc(cb) && cb(event, msg, msg.detail[0], msg.detail.slice(1))
} catch (e) { // 执行失败 } catch (e) { // 执行失败
can.base.Log(e) can.misc.Log(e), msg.Reply(e)
msg.Reply(e)
} }
} }
}), },
Log: function() {
var args = [this._time(), this.FileLine(2, 3)]
for (var i in arguments) { args.push(arguments[i]) }
console.log.apply(console, args)
},
Warn: function() {
var args = [this._time(), this.FileLine(2, 3), "warn"]
for (var i in arguments) { args.push(arguments[i]) }
args.push("\n", this._fileLine().split("\n").slice(2).join("\n"))
console.log.apply(console, args)
},
Debug: function() {
var args = [this._time(), this.FileLine(2, 3), "debug"]
for (var i in arguments) { args.push(arguments[i]) }
args.push(this.fileLine(2, 3))
console.log.apply(console, args)
navigator.userAgent.indexOf("Mobile") > -1 && alert(JSON.stringify(args.join(" ")))
},
FileLine: function(depth, length) {
return this.fileLine(depth+1).split("/").slice(3).slice(-length).join("/").split(")")[0]
},
fileLine: function(depth) {
return (this._fileLine().split("\n")[1+depth]||"").trim()
},
_fileLine: function() { var obj = {}
Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee)
return obj.stack || ""
},
_time: function() { var now = new Date()
return now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()
},
}) })

View File

@ -1,51 +1,40 @@
Volcanos("page", {help: "网页模块", Volcanos("page", {help: "网页模块", ClassList: {
ClassList: {
has: function(can, obj, key) { var list = obj.className? obj.className.split(" "): [] has: function(can, obj, key) { var list = obj.className? obj.className.split(" "): []
for (var i = 2; i < arguments.length; i++) { return list.indexOf(key) > -1
if (list.indexOf(arguments[i]) == -1) {return false}
}
return true
}, },
add: function(can, obj, key) { var list = obj.className? obj.className.split(" "): [] add: function(can, obj, key) { var list = obj.className? obj.className.split(" "): []
return obj.className = list.concat(can.core.List(key, function(value, index) { return obj.className = can.base.AddUniq(list, key).join(" ").trim()
return list.indexOf(value) == -1? value: undefined
})).join(" ").trim()
}, },
del: function(can, obj, key) {var list = can.core.List(arguments, function(value, index) {return index > 0? value: undefined}) del: function(can, obj, key) { var list = obj.className? obj.className.split(" "): []
return obj.className = can.core.List(obj.className.split(" "), function(value) { return obj.className = can.core.List(list, function(value) {
return list.indexOf(value) == -1? value: undefined return value == key? undefined: value
}).join(" ").trim() }).join(" ").trim()
}, },
set: function(can, obj, key, condition) { set: function(can, obj, key, condition) {
condition? can.page.ClassList.add(can, obj, key): can.page.ClassList.del(can, obj, key) condition? this.add(can, obj, key): this.del(can, obj, key)
}, },
neg: function(can, obj, key) { neg: function(can, obj, key) {
this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key) this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)
}, },
}, },
Select: shy("选择节点", function(can, target, key, cb, interval, cbs) { if (key == ".") { return [] }
Select: shy("选择节点", function(can, obj, key, cb, interval, cbs) {if (key == ".") {return []} return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs)
var item = obj && obj.querySelectorAll(key)
return can.core.List(item, cb, interval, cbs)
}), }),
Modify: shy("修改节点", function(can, target, value) { target = target || {} Modify: shy("修改节点", function(can, target, value) { target = target || {}
target = typeof target == "string"? document.querySelector(target): target target = typeof target == "string"? document.querySelector(target): target
typeof value == "string"? (target.innerHTML = value): can.core.Item(value, function(key, value) { typeof value == "string"? (target.innerHTML = value): can.core.Item(value, function(key, val) {
typeof value != "object"? (target[key] = value): can.core.Item(value, function(sub, value) { typeof val != "object"? (target[key] = val): can.core.Item(val, function(k, v) {
var size = { var size = {
"width": true, "max-width": true, "min-width": true, "width": true, "max-width": true, "min-width": true,
"height": true, "max-height": true, "min-height": true, "height": true, "max-height": true, "min-height": true,
"left": true, "right": true, "top": true, "bottom": true, "left": true, "right": true, "top": true, "bottom": true,
"margin-top": true, "margin-left": true, "margin-top": true, "margin-left": true,
}; if (size[k] && parseInt(v) < 0) { return target[key] && (target[key][k] = "") }
if (size[k] && v && (typeof v == "number" || v.indexOf && v.indexOf("px") == -1)) {
v += "px"
} }
if (parseInt(value) < 0 && sub == "height") { target[key] && (target[key][k] = v)
target[key] && (target[key][sub] = "")
return
}
if (size[sub] && value && (typeof value == "number" || value.indexOf && value.indexOf("px") == -1)) {
value += "px"
}
target[key] && (target[key][sub] = value)
}) })
}) })
return target return target
@ -53,6 +42,9 @@ Volcanos("page", {help: "网页模块",
Create: shy("创建节点", function(can, key, value) { Create: shy("创建节点", function(can, key, value) {
return can.page.Modify(can, document.createElement(key), value) return can.page.Modify(can, document.createElement(key), value)
}), }),
Remove: shy("删除节点", function(can, target) {
target && target.parentNode && target.parentNode.removeChild(target)
}),
Append: shy("添加节点", function(can, target, key, value) { Append: shy("添加节点", function(can, target, key, value) {
if (typeof key == "string") { var res = can.page.Create(can, key, value); return target.appendChild(res), res } if (typeof key == "string") { var res = can.page.Create(can, key, value); return target.appendChild(res), res }
@ -68,61 +60,50 @@ Volcanos("page", {help: "网页模块",
// 数据调整 // 数据调整
can.core.Item(item, function(key, value) { can.core.Item(item, function(key, value) {
switch (key) { switch (key) {
case "type": case "type": break
case "name": case "name": break
case "data": case "data": break
case "list": case "list": break
break case "inner": data.innerHTML = item.inner; break
case "click": case "click": data.onclick = item.click; break
data.onclick = item.click default: data[key] = item[key]
break
case "inner":
data.innerHTML = item.inner
break
default:
data[key] = item[key]
} }
}) })
if (item.view) { var list = can.core.List(item.view) if (item.view) { var list = can.core.List(item.view)
list.length > 0 && list[0] && can.page.ClassList.add(can, data, list[0]) list.length > 0 && list[0] && can.page.ClassList.add(can, data, list[0])
type = list[1] || "div" type = list[1] || "div"
data.innerHTML = can.user.trans(can, list[2]) || data.innerHTML || "" data.innerHTML = list[2] || data.innerHTML || ""
name = name || list[3] || "" name = name || list[3] || ""
} else if (item.text) { var list = can.core.List(item.text) } else if (item.text) { var list = can.core.List(item.text)
data.innerHTML = list[0] || data.innerHTML || "" data.innerHTML = list[0] || data.innerHTML || ""
type = list[1] || "span" type = list[1] || "span"
list.length > 2 && list[2] && can.page.ClassList.add(can, data, list[2]) list[2] && can.page.ClassList.add(can, data, list[2])
} else if (item.button) { var list = can.core.List(item.button) } else if (item.button) { var list = can.core.List(item.button)
type = "button", name = name || list[0] type = "button", name = name || list[0]
data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) { data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) {
typeof list[1] == "function" && list[1](event, name) typeof list[1] == "function" && list[1](event, name)
event.stopPropagation() event.stopPropagation(), event.preventDefault()
event.preventDefault()
return true return true
} }
} else if (item.select) { var list = item.select } else if (item.select) { var list = item.select
type = "select", name = name || list[0][0] type = "select", data.name = name = name || list[0][0]
data.onchange = function(event) { data.title = can.user.trans(can, data.title || name)
typeof list[1] == "function" && list[1](event, event.target.value, name) data.className = data.className || list[0][0] || ""
}
item.list = list[0].slice(1).map(function(value) { item.list = list[0].slice(1).map(function(value) {
return {type: "option", value: value, inner: can.user.trans(can, value)} return {type: "option", value: value, inner: can.user.trans(can, value)}
}) })
data.className = data.className || list[0][0] || "" data.onchange = function(event) {
data.title = can.user.trans(can, data.title || name) typeof list[1] == "function" && list[1](event, event.target.value, name)
data.name = name }
} else if (item.input) { var list = can.core.List(item.input) } else if (item.input) { var list = can.core.List(item.input)
type = "input", name = name || list[0] || "" type = "input", name = name || list[0] || "", data.name = data.name || name
data.name = data.name || name
data.className = data.className || data.name data.className = data.className || data.name
data.placeholder = data.placeholder || data.name
data.placeholder = data.placeholder.split(".").pop()
data.title = data.title || data.placeholder
data.autocomplete = "off" data.autocomplete = "off"
data.onfocus = data.onfocus || function(event) { data.onfocus = data.onfocus || function(event) {
@ -135,25 +116,18 @@ Volcanos("page", {help: "网页模块",
typeof list[2] == "function" && list[2](event) typeof list[2] == "function" && list[2](event)
} }
} else if (item.username) { var list = can.core.List(item.username) } else if (item.username) { var list = can.core.List(item.username)
type = "input", name = name || list[0] || "username" type = "input", name = name || list[0] || "username", data.name = data.name || name
data.name = data.name || name
data.className = list[1] || data.className || data.name data.className = list[1] || data.className || data.name
data.placeholder = data.placeholder || data.name
data.title = data.title || data.placeholder
data.autocomplete = data.autocomplete || "username" data.autocomplete = data.autocomplete || "username"
} else if (item.password) { var list = can.core.List(item.password) } else if (item.password) { var list = can.core.List(item.password)
type = "input", name = name || list[0] || "password" type = "input", name = name || list[0] || "password", data.name = data.name || name
data.type = "password" data.className = list[1] || data.className || data.name
data.name = data.name || name
data.className = list[1], data.className || data.name
data.placeholder = data.placeholder || data.name
data.title = data.title || data.placeholder
data.autocomplete = data.autocomplete || "current-password" data.autocomplete = data.autocomplete || "current-password"
data.type = "password"
} else if (item.img) { var list = can.core.List(item.img) } else if (item.img) { var list = can.core.List(item.img)
type = "img" type = "img", data.src = list[0]
data.src = list[0]
} else if (item.row) { type = "tr" } else if (item.row) { type = "tr"
item.list = item.row.map(function(text) { return {text: [text, item.sub||"td"]} }) item.list = item.row.map(function(text) { return {text: [text, item.sub||"td"]} })
@ -161,70 +135,61 @@ Volcanos("page", {help: "网页模块",
item.list = item.th.map(function(text) { return {text: [text, "th"]} }) item.list = item.th.map(function(text) { return {text: [text, "th"]} })
} else if (item.td) { type = "tr" } else if (item.td) { type = "tr"
item.list = item.td.map(function(text) { return {text: [text, "td"]} }) item.list = item.td.map(function(text) { return {text: [text, "td"]} })
} else if (item.include) {var list = can.core.List(item.include)
type = "script"
data.src = list[0]
data.onload = list[1]
} }
item.type == "input" && data.type == "button" && (data.value = can.user.trans(can, data.value)) if (type == "input") {
item.type == "input" && data.type == "text" && (data.autocomplete = data.autocomplete||"off") data.type == "button" && (data.value = can.user.trans(can, data.value))
data.placeholder && (data.placeholder = can.user.trans(can, data.placeholder)) data.type == "text" && (data.autocomplete = data.autocomplete||"off")
data.title && (data.title = can.user.trans(can, data.title)) (data.placeholder = can.user.trans(can, (data.placeholder||data.name).split(".").pop()))
data.title = can.user.trans(can, data.title||data.placeholder)
}
// 创建节点 // 创建节点
name = name || data.className || type || ""
!data.name && item.name && (data.name = item.name) !data.name && item.name && (data.name = item.name)
var node = can.page.Create(can, type, data) var node = can.page.Create(can, type, data)
value.last = node, value.first = value.first || node, value[name||""] = value[data.className||""] = value[type] = node // 创建索引
name = name || data.className || type || ""
value[name||""] = value[data.className||""] = value[type] = node
value.first = value.first || node, value.last = node
value._target = value._target || node
// 递归节点
item.list && can.page.Append(can, node, item.list, value) item.list && can.page.Append(can, node, item.list, value)
typeof item._init == "function" && item._init(node)
target && target.append && target.appendChild(node) target && target.append && target.appendChild(node)
target.appendChild(node) typeof item._init == "function" && item._init(node)
}) })
return value return value
}), }),
Appends: shy("添加节点", function(can, target, key, value) { Appends: shy("添加节点", function(can, target, key, value) {
return target.innerHTML = "", can.page.Append(can, target, key, value) return target.innerHTML = "", can.page.Append(can, target, key, value)
}), }),
Remove: shy("删除节点", function(can, target) {
target && target.parentNode && target.parentNode.removeChild(target)
}),
AppendAction: shy("添加控件", function(can, action, list, cb) {
return can.page.Append(can, action, can.core.List(list, function(line) {
return ["br", "hr"].indexOf(line.type) > -1? line: {view: "item", list: [typeof line == "string"? {button: [line, cb]}: line.length > 0? {select: [line, cb]}:
line.input && typeof line.input != "string" ? {input: [line.input[0], function(event) {
typeof line.input[1] == "function" && line.input[1](event, can)
}, function(event) {
typeof line.input[2] == "function" && line.input[2](event, can)
}]}: line]}
}))
}),
AppendTable: shy("添加表格", function(can, msg, target, list, cb) { AppendTable: shy("添加表格", function(can, msg, target, list, cb) {
if (!msg.append || msg.append.length == 0) {return} if (!msg.append || msg.append.length == 0) {return}
var table = can.page.Append(can, target, "table") var table = can.page.Append(can, target, "table")
var tr = can.page.Append(can, table, "tr", {dataset: {index: -1}}) can.page.Append(can, table, [{type: "tr", {dataset: {index: -1}}, list:
can.core.List(list, function(key, index) { if (key.indexOf("_") == 0) { return } can.core.List(list, function(key) {
key = can.Conf("feature.table.trans."+key) || {}[key] || key return key[0] == "_"? undefined: {text: [key.trim(), "th"]}
can.page.Append(can, tr, "th", key.trim()).onclick = function(event) {
var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
}) })
}])
can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) { can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) {
return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return } return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return }
return cb(can.page.Display(line[key]).trim(), key, index, line, array) return cb(can.page.Display(line[key]).trim(), key, index, line, array)
})} })}
})) }))
return table return can.page.OrderTable(can, table)
}), }),
OrderTable: function(can, table) {
can.page.Select(can, table, "th", function(th, index) {
th.onclick = function(event) { var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
})
return table
},
RangeTable: function(can, table, index, sort_asc) { RangeTable: function(can, table, index, sort_asc) {
var list = can.page.Select(can, table, "tr", function(tr) { var list = can.page.Select(can, table, "tr", function(tr) {
return tr.style.display == "none" || can.page.ClassList.has(can, tr, "hide")? null: tr return tr.style.display == "none" || can.page.ClassList.has(can, tr, "hide")? null: tr
@ -276,22 +241,14 @@ Volcanos("page", {help: "网页模块",
tbody.appendChild(list[i]) tbody.appendChild(list[i])
} }
}, },
OrderTable: function(can, table) {
can.page.Select(can, table, "th", function(th, index) {
table.onclick = function(event) {
var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
})
},
Display: function(text) { if (typeof text != "string") { return "" } Display: function(text) { if (typeof text != "string") { return "" }
if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) { if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) {
var ls = text.split(" ") var ls = text.split(" ");
return "<a href='"+ls[0]+"' target='_blank'>"+ls[0]+"</a>"+ls.slice(1).join(" ") text = "<a href='"+ls[0]+"' target='_blank'>"+ls[0]+"</a>"+ls.slice(1).join(" ")
} }; text = text.replace(/\\n/g, "<br>")
if (!text.indexOf("\033\[")) { return text }
text = text.replace(/\033\[31m/g, "<span style='color:#f00'>") text = text.replace(/\033\[31m/g, "<span style='color:#f00'>")
text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>") text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>")
text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>") text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>")
@ -302,213 +259,34 @@ Volcanos("page", {help: "网页模块",
text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>") text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>")
text = text.replace(/\033\[0m/g, "</span>") text = text.replace(/\033\[0m/g, "</span>")
text = text.replace(/\033\[m/g, "</span>") text = text.replace(/\033\[m/g, "</span>")
text = text.replace(/\\n/g, "<br>")
return text return text
}, },
Format: function(type, src) { Format: function(type, src) {
switch (type) { switch (type) {
case "a": case "a": return "<a href='"+arguments[1]+"' target='_blank'>"+(arguments[2]||arguments[1])+"</a>"
return "<a href='"+arguments[1]+"' target='_blank'>"+(arguments[2]||arguments[1])+"</a>" case "img": return arguments[2]? "<img src='"+arguments[1]+"' height="+arguments[2]+">": "<img src='"+arguments[1]+"'>"
case "img":
return arguments[2]? "<img src='"+arguments[1]+"' height="+arguments[2]+">": "<img src='"+arguments[1]+"'>"
} }
}, },
DelText: function(target, start, count) {
target.value = target.value.substring(0, start)+target.value.substring(start+(count||target.value.length), target.value.length)
target.setSelectionRange(start, start)
},
Cache: function(name, output, data) { var cache = output._cache || {}; output._cache = cache Cache: function(name, output, data) { var cache = output._cache || {}; output._cache = cache
if (data) { if (output.children.length == 0) { return } if (data) { if (output.children.length == 0) { return }
// 写缓存
var temp = document.createDocumentFragment() var temp = document.createDocumentFragment()
while (output.childNodes.length>0) { while (output.childNodes.length > 0) { // 写缓存
var item = output.childNodes[0] var item = output.childNodes[0]
item.parentNode.removeChild(item) item.parentNode.removeChild(item),
temp.appendChild(item) temp.appendChild(item)
} }
return cache[name] = {node: temp, data: data}, name
cache[name] = {node: temp, data: data}
return name
} }
output.innerHTML = "" output.innerHTML = ""
var list = cache[name]; if (!list) {return}
// 读缓存 var list = cache[name]; if (!list) { return }
while (list.node.childNodes.length>0) { while (list.node.childNodes.length > 0) { // 读缓存
var item = list.node.childNodes[0] var item = list.node.childNodes[0]
item.parentNode.removeChild(item) item.parentNode.removeChild(item)
output.appendChild(item) output.appendChild(item)
} }
delete(cache[name]) return delete(cache[name]), list.data
return list.data
},
Toggle: function(can, target, show, hide) { var status = target.style.display == "none"
can.page.Modify(can, target, {style: {display: status? "": "none"}})
status? typeof show == "function" && show(): typeof hide == "function" && hide()
return status
},
Anchor: function(event, target, pos, point) {
switch (pos) {
case 1:
case 2:
case 3:
point.y = target.Val("y")
break
case 4:
case 5:
case 6:
point.y = target.Val("y") + target.Val("height") / 2
break
case 7:
case 8:
case 9:
point.y = target.Val("y") + target.Val("height")
break
}
switch (pos) {
case 1:
case 4:
case 7:
point.x = target.Val("x")
break
case 2:
case 5:
case 8:
point.x = target.Val("x") + target.Val("width") / 2
break
case 3:
case 6:
case 9:
point.x = target.Val("x") + target.Val("width")
break
}
return point
},
Prepos: function(event, item, p, q) {
var max = 20
p = p || item.getBoundingClientRect()
q = q || {x: event.clientX, y: event.clientY}
var pos = 5
var y = (q.y - p.y) / p.height
if (y < 0.2 && q.y - p.y < max) {
pos -= 3
} else if (y > 0.8 && q.y - p.y - p.height > -max) {
pos += 3
}
var x = (q.x - p.x) / p.width
if (x < 0.2 && q.x - p.x < max) {
pos -= 1
} else if (x > 0.8 && q.x - p.x - p.width > -max) {
pos += 1
}
var cursor = [
"nw-resize", "n-resize", "ne-resize",
"w-resize", "move", "e-resize",
"sw-resize", "s-resize", "se-resize",
]
item.style.cursor = cursor[pos-1]
return pos
},
Resize: function(event, item, begin, pos) {
switch (pos) {
case 5:
item.style.left = begin.left + event.clientX - begin.x + "px"
item.style.top = begin.top + event.clientY - begin.y + "px"
return
}
switch (pos) {
case 1:
case 2:
case 3:
item.style.top = begin.top + event.clientY - begin.y + "px"
item.style.height = begin.height - event.clientY + begin.y + "px"
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.style.left = begin.left + event.clientX - begin.x + "px"
item.style.width = begin.width - event.clientX + begin.x + "px"
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.style.width = begin.width + event.clientX - begin.x + "px"
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.style.height = begin.height + event.clientY - begin.y + "px"
break
}
},
Resizes: function(event, item, begin, p0, p1, pos) {
switch (pos) {
case 5:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("y", begin.y + p1.y - p0.y)
return
}
switch (pos) {
case 1:
case 2:
case 3:
item.Value("y", begin.y + p1.y - p0.y)
item.Value("height", begin.height - p1.y + p0.y)
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("width", begin.width - p1.x + p0.x)
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.Value("width", begin.width + p1.x - p0.x)
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.Value("height", begin.height + p1.y - p0.y)
break
}
},
EnableDrop: function(can, parent, search, target) {
return can.page.Modify(can, target, { draggable: true,
ondragstart: function(event) { var target = event.target; can.drop = function(event, tab) {
parent.insertBefore(target, tab)
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
})
} },
ondragover: function(event) { event.preventDefault()
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
}), can.page.ClassList.add(can, event.target, "over")
},
ondrop: function(event) { event.preventDefault()
can.drop(event, event.target)
},
})
}, },
}) })

View File

@ -1,6 +1,6 @@
Volcanos("user", {help: "用户模块", agent: { Volcanos("user", {help: "用户模块", agent: {
scanQRCode: function(cb, can) { scanQRCode: function(cb, can) {
can.user.input(event, can, [{_input: "textarea"}], function(ev, button, data, list, args) { can.user.input(event, can, [{type: "textarea"}], function(ev, button, data, list, args) {
cb(list[0]) cb(list[0])
}) })
}, },
@ -28,10 +28,103 @@ Volcanos("user", {help: "用户模块", agent: {
confirm: function(text) { return confirm(JSON.stringify(text)) }, confirm: function(text) { return confirm(JSON.stringify(text)) },
prompt: function(text, cb, def, silent) { (text = silent? def: prompt(text, def||"")) != undefined && typeof cb == "function" && cb(text); return text }, prompt: function(text, cb, def, silent) { (text = silent? def: prompt(text, def||"")) != undefined && typeof cb == "function" && cb(text); return text },
reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() }, reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() },
title: function(text) { return text && (document.title = text), document.title },
jumps: function(url) { location.href = url }, jumps: function(url) { location.href = url },
open: function(url) { window.open(url) }, open: function(url) { window.open(url) },
title: function(text) { return text && (document.title = text), document.title },
topic: function(can, name) {
can.page.Modify(can, document.body, {className: name})
can.user.isMobile && can.page.ClassList.add(can, document.body, "mobile")
can.user.isMobile && can.page.ClassList.set(can, document.body, "landscape", can.user.isLandscape)
},
trans: function(can, text) { if (typeof text == "function") { text = text.name || "" }
return can._trans&&can._trans[text] || can.Conf("trans."+text) || can.Conf("feature.trans."+text) || {
"submit": "提交", "cancel": "取消",
"open": "打开", "close": "关闭",
"begin": "启动", "end": "结束",
}[text] || text
},
toast: function(can, content, title, duration, progress) {
var meta = typeof content == "object"? content: {content: content, title: title||can._help, duration: duration, progress: progress}
var width = meta.width||400, height = meta.height||100; if (width < 0) { width = window.innerWidth + width }
var ui = can.page.Append(can, document.body, [{view: "toast", style: {
left: (window.innerWidth-width)/2, width: width, bottom: 100,
}, list: [
{text: [meta.title||"", "div", "title"], title: "点击复制", onclick: function(event) {
can.user.copy(event, can, meta.title)
}},
{view: "duration", title: "点击关闭", onclick: function() { action.close() }},
typeof meta.content == "object"? meta.content: {text: [meta.content||"执行成功", "div", "content"]},
{view: "action"}, meta.progress != undefined && {view: "progress", style: {width: width}, list: [
{view: "current", style: {width: (meta.progress||0)/100*width}},
]},
] }])
var action = can.onappend._action(can, meta.action||["close"], ui.action, {
close: function(event) { can.page.Remove(can, action._target), action.timer.stop = true },
timer: can.core.Timer({interval: 100, length: (parseInt(meta.duration||1000))/100}, function(event, interval, index) {
if (index > 30) { ui.duration.innerHTML = parseInt(index/10)+"."+(index%10)+"s..." }
}, function() { action.close() }), _target: ui._target, ui: ui,
}); can.onmotion.story(can, ui._target)
can.search(can.request({}, {
title: meta.title, content: meta.content,
time: can.base.Time(), fileline: can.misc.FileLine(2, 2),
})._event, ["Footer.onimport.toast"])
return action
},
share: function(can, msg, cmd) {
can.run(msg._event, cmd||["action", "share"], function(msg) {
can.user.toast(can, {height: 300, width: 500,
title: msg.Append("name"), duration: -1,
content: msg.Append("text"), button: ["close"],
})
})
},
login: function(can, cb) {
var ui = can.user.input({}, can, [
{username: "username"}, {password: "password"},
], function(event, button, data, list) { return {
"登录": function() {
can.run({}, ["action", "login", data["username"], data["password"]], function(msg) {
if (msg.Option("user.name")) {
can.page.Remove(can, ui._target), can.base.isFunc(cb) && cb()
} else {
can.user.toast(can, "用户名或密码错误")
}
})
return true
},
"扫码": function() {
can.misc.WSS(can, {type: "chrome"}, function(event, msg, cmd, arg) { if (!msg) { return }
if (cmd == "pwd") {
return can.user.toast(can, arg[2], arg[1], -1), msg.Reply()
}
if (cmd == "sessid") {
return can.user.Cookie(can, "sessid", arg[0]), msg.Reply(), can.user.reload(true)
}
can.search(event, msg["detail"]||[], function(msg) { msg.Reply() })
})
},
}[button]() }, ["登录", "扫码"])
can.page.Modify(can, ui._target, {className: "input login", style: {left: (window.innerWidth-ui._target.offsetWidth)/2, top: window.innerHeight/6}})
},
logout: function(can, force) { if (force||can.user.confirm("logout?")) {
can.run({}, ["action", "logout"], function(msg) { can.user.Cookie(can, "sessid", "")
can.user.Search(can, "share")? can.user.Search(can, "share", ""): can.user.reload(true)
})
} },
camera: function(can, msg, cb) {
navigator.getUserMedia({video: true}, cb, function(error) {
can.misc.Log(error)
})
},
copy: function(event, can, text) { copy: function(event, can, text) {
if (navigator.clipboard) { var ok = false if (navigator.clipboard) { var ok = false
navigator.clipboard.writeText(text).then(() => { ok = true }) navigator.clipboard.writeText(text).then(() => { ok = true })
@ -43,179 +136,64 @@ Volcanos("user", {help: "用户模块", agent: {
can.page.Remove(can, input), can.user.toast(can, text, "复制成功") can.page.Remove(can, input), can.user.toast(can, text, "复制成功")
event.stopPropagation(), event.preventDefault() event.stopPropagation(), event.preventDefault()
}, },
camera: function(can, msg, cb) {
navigator.getUserMedia({video: true}, cb, function(error) {
can.base.Log(error)
})
},
trans: function(can, text) {
if (typeof text == "function") { text = text.name || "" }
return can._trans && can._trans[text] || can.Conf("trans."+text) || can.Conf("feature.trans."+text) || {
"submit": "提交", "cancel": "取消",
"begin": "启动", "end": "结束",
"close": "关闭",
}[text] || text
},
topic: function(can, name) {
can.page.Modify(can, document.body, {className: name})
var width = window.innerWidth, height = window.innerHeight
can.user.isMobile && can.page.ClassList.add(can, document.body, "mobile")
can.user.isMobile && can.page.ClassList.set(can, document.body, "landscape", width > height)
},
toast: function(can, content, title, duration, progress) {
var meta = typeof content == "object"? content: {content: content, title: title||can._help, duration: duration, progress: progress}
var width = meta.width||400, height = meta.height||100; if (width < 0) { width = window.innerWidth + width }
var ui = can.page.Append(can, document.body, [{view: "toast", style: {
width: width, bottom: 100, left: (window.innerWidth-width)/2,
}, list: [
{text: [meta.title||"", "div", "title"]},
typeof meta.content == "object"? meta.content: {text: [meta.content||"执行成功", "div", "content"]},
{view: "button"},
{view: "duration"}, meta.progress != undefined && {view: "progress", style: {width: width}, list: [
{view: "current", style: {width: (meta.progress||0)/100*width}},
]},
] }]); can.onmotion.story(can, ui.first)
ui.Close = function() { can.page.Remove(can, ui.first), timer.stop = true }
var timer = can.core.Timer({interval: 100, length: (parseInt(meta.duration||1000))/100}, function(event, interval, index) {
if (index > 30) { ui.duration.innerHTML = parseInt(index/10)+"."+(index%10)+"s..." }
}, ui.Close)
can.onappend._action(can, meta.button||[], ui.button, {
close: function(event) { ui.Close() },
})
can.search && can.search(can.request({}, {
title: meta.title, content: meta.content,
time: can.base.Time(), fileline: can.base.FileLine(2, 2),
})._event, ["Footer.onimport.toast"], null, true)
return ui
},
share: function(can, msg, cmd) {
can.run(msg._event, cmd||["action", "share"], function(msg) {
var ui = can.user.toast(can, {
title: msg.Append("name"), content: msg.Append("text"),
button: ["close"], duration: 100000,
height: 300,
})
})
},
login: function(can, cb) {
var ui = can.user.input({clientX: 100, clientY: 100}, can, [
{username: "username", name: "用户"},
{password: "password", name: "密码"},
{button: ["登录", "扫码", "注册"]},
], function(event, button, data, list) {
switch (button) {
case "登录": can.user.Cookie(can, "sessid", "")
can.run({}, ["login", ui["用户"].value, ui["密码"].value], function(msg) {
if (can.user.Cookie(can, "sessid")||msg.Option("user.name")||msg.Result()) {
can.page.Remove(can, ui.first); return typeof cb == "function" && cb()
}
can.user.alert("用户或密码错误")
})
break
case "扫码":
can.misc.WSS(can, {type: "chrome"}, function(event, msg, cmd, arg) { if (!msg) { return }
if (cmd == "pwd") {
can.user.toast(can, arg[2], arg[1], 1000000)
msg.Reply()
return
}
if (cmd == "sessid") {
can.user.Cookie(can, "sessid", arg[0])
can.user.reload(true)
return
}
can.search(event, msg["detail"]||[], function(msg) {
msg.Reply()
})
})
return true
break
case "注册":
break
}
})
can.page.Modify(can, ui.first, {style: {left: (window.innerWidth-ui.first.offsetWidth)/2}})
},
carte: function(event, can, meta, list, cb) { carte: function(event, can, meta, list, cb) {
meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||[]; if (list.length == 0) { return } meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||[]; if (list.length == 0) { return }
cb = cb||function(ev, item, meta) { var cb = meta[item]; can.base.isFunc(cb) && cb(event, can, item) } cb = cb||function(ev, item, meta) { var cb = meta[item]; can.base.isFunc(cb) && cb(event, can, item) }
var ui = can.page.Append(can, document.body, [{view: "carte", style: {left: 0, top: 0}, onmouseleave: function(event) { var ui = can.page.Append(can, document.body, [{view: "carte", style: {left: 0, top: 0}, onmouseleave: function(event) {
can.page.Remove(can, ui.first) can.page.Remove(can, ui._target)
}, list: can.core.List(list, function(item) { }, list: can.core.List(list, function(item) {
return {view: "item", list: [{text: can.user.trans(can, item), click: function(event) { return {view: "item", list: [{text: can.user.trans(can, item), click: function(event) {
can.user.isMobile && can.page.Remove(can, ui.first) can.user.isMobile && can.page.Remove(can, ui._target)
can.base.isFunc(cb) && cb(event, item, meta) can.base.isFunc(cb) && cb(event, item, meta)
} }] } } }] }
}) }] ) }) }] ); can.onlayout.figure(event, can, ui._target)
var left = event.clientX-event.offsetX, top = event.clientY-event.offsetY+event.target.offsetHeight Volcanos.meta.float.carte && can.page.Remove(can, Volcanos.meta.float.carte._target)
if (left+ui.first.offsetWidth>window.innerWidth) { left = window.innerWidth - ui.first.offsetWidth } return event.stopPropagation(), event.preventDefault(), Volcanos.meta.float.carte = ui, {_target: ui._target}
can.page.Modify(can, ui.first, {style: {left: left, top: top}})
Volcanos.meta.data.menu && can.page.Remove(can, Volcanos.meta.data.menu.first)
return event.stopPropagation(), event.preventDefault(), Volcanos.meta.data.menu = ui
}, },
input: function(event, can, form, cb) { // form [ string, array, object, {_input: }, {button: []} ] input: function(event, can, form, cb, button) { // form [ string, array, object, {_input: "select", values: []}
var msg = can.request(event, can.Option()) var msg = can.request(event, can.Option())
var x = event.clientX||can.user.isMobile? 20: 200, y = event.clientY+10||48 var ui = can.page.Append(can, document.body, [{view: ["input"], style: {left: 0, top: 0}, list: [
var button; var ui = can.page.Append(can, document.body, [{view: ["input inputs", "fieldset"], style: {left: x, top: y}, list: [
{view: ["option", "table"], list: can.core.List(form, function(item) { {view: ["option", "table"], list: can.core.List(form, function(item) {
if (item.button) { button = item.button; return } item._input == "select" && (item = {select: [[item.name].concat(item.values)], data: item, name: item.name})
item = typeof item == "string"? {input: item, name: item}: item.length > 0? {select: [item], name: item[0]}: item
item.type = item.type||"input", item.type == "input" && (item.data=item.data||{}, item.data.type = item.data.type||"text")
function _init(target) { item._init = item._init||function(target) {
item.run = function(event, cmds, cb) { item.run = function(event, cmds, cb) {
var msg = can.request(event, function() { var value = {_handle: "true"} var msg = can.request(event, function() { var value = {_handle: "true"}
can.page.Select(can, ui.table, "textarea,input,select", function(item) { can.page.Select(can, ui.table, "textarea,input,select", function(item) {
item.name && item.value && (value[item.name] = item.value) item.name && item.value && (value[item.name] = item.value)
}); return value }); return value
}) }); can.run(event, cmds, cb, true)
can.run(event, cmds, cb, true)
} }
can.onappend.figure(can, item, item.value, target) can.onappend.figure(can, item, item.value, target)
target.value = target.value || msg.Option(item.name) target.value = target.value || msg.Option(item.name)
} }
item = typeof item == "string"? {_input: "text", name: item}: return {type: "tr", list: [{type: "td", list: [{text: item.name||""}]}, {type: "td", list: [item]} ]}
item.length > 0? {_input: "select", name: item[0], values: item.slice(1)}: item
item._input = item.type||item._input||"text"
return {type: "tr", list: [{type: "td", list: [{text: item.name||""}]}, {type: "td", list: [
item._input == "textarea"? /* textarea */ {type: "textarea", data: item, _init: _init}:
item._input == "select"? /* select */ {select: [[item.name].concat(item.values)], data: item}:
item._input? /* input */ {type: "input", data: (item.type = item._input, item), _init: _init}:
/* other */ item,
]} ]}
})}, })},
{view: "action"}, {view: "action"},
]}]) ]}]); can.onlayout.figure(event, can, ui._target)
function cbs(event, button) { var data = {}, args = [], list = [] var action = can.onappend._action(can, button||["submit", "cancel"], ui.action, {
cancel: function(event) { can.page.Remove(can, ui._target) },
_engine: function(event, can, button) { action.submit(event, can, button) },
submit: function(event, can, button) { var data = {}, args = [], list = []
list = can.page.Select(can, ui.table, "textarea,input,select", function(item) { list = can.page.Select(can, ui.table, "textarea,input,select", function(item) {
return args.push(item.name, item.value), data[item.name] = item.value return args.push(item.name, item.value), data[item.name] = item.value
}) })
typeof cb == "function" && !cb(event, button, data, list, args) && can.page.Remove(can, ui.first) can.base.isFunc(cb) && !cb(event, button, data, list, args) && action.cancel()
} }, _target: ui._target,
can.onappend._action(can, button||["submit", "cancel"], ui.action, {
cancel: function(event) { can.page.Remove(can, ui.first) },
_engine: function(event, can, key) { cbs(event, key) },
submit: function(event) { cbs(event, "submit") },
}) })
can.onlayout.figure(event, can, ui.first), can.page.Select(can, ui.table, "textarea,input", function(item, index) { can.page.Select(can, ui._target, "input", function(item, index) {
index == 0 && can.core.Timer(100, function() { item.focus(), item.setSelectionRange(0, -1) }) index == 0 && can.onmotion.focus(can, item)
}) })
return ui
return action
}, },
select: function(event, can, type, fields, cb, cbs) { select: function(event, can, type, fields, cb, cbs) {
var msg = can.request(event, {fields: fields||"type,name,text"}) var msg = can.request(event, {fields: fields||"type,name,text"})
@ -226,69 +204,49 @@ Volcanos("user", {help: "用户模块", agent: {
}) })
}, },
upload: function(event, can) { var begin = new Date() upload: function(event, can) { var begin = new Date()
var x = event.clientX, y = event.clientY; y += 10; if (x > 400) { x -= 200 } var ui = can.page.Append(can, document.body, [{view: "upload", style: {left: 0, top: 0}, list: [
if (can.user.isMobile) { x = 100, y = 100 } {view: "action"}, {view: "output", list: [{view: "progress"}]},
var ui = can.page.Append(can, document.body, [{view: "upload", style: {left: x, top: y}, list: [ {view: "status", list: [{view: "show"}, {view: "cost"}, {view: "size"}]},
{view: "action"}, {view: "output"}, ]}]); can.onlayout.figure(event, can, ui._target)
]}])
function show(event, value, total, loaded) { var action = can.onappend._action(can, [
var now = new Date(); can.page.Appends(can, ui.output, [ {type: "upload", onchange: function(event) {
{view: ["progress"], style: {height: "10px", border: "solid 2px red"}, list: [{ action.show(event, 0, event.target.files[0].size, 0)
view: ["progress"], style: {height: "10px", width: value + "%", background: "red"}, }}, "close",
}]}, ], ui.action, {
{text: [value+"%", "div"], style: {"float": "right"}}, close: function(event) { can.page.Remove(can, ui._target) },
{text: [can.base.Duration(now - begin), "div"], style: {"float": "left"}}, begin: function(event) { begin = new Date()
{text: [can.base.Size(loaded)+"/"+can.base.Size(total), "div"], style: {"text-align": "center"}}, var upload = can.page.Select(can, ui.action, "input[type=file]")
]) if (upload[0].files.length == 0) { return upload[0].focus() }
}
var action = can.page.AppendAction(can, ui.action, [ var msg = can.request(event, can.Option(), {_handle: "true"})
{type: "input", data: {name: "upload", type: "file", onchange: function(event) { msg._upload = upload[0].files[0], msg._progress = action.show
var file = action.upload.files[0]
show(event, 0, file.size, 0)
}}, style: {width: "200px"}}, "上传", "关闭"], function(event, value, cmd) {
if (value == "关闭") { return can.page.Remove(can, ui.first) }
if (action.upload.files.length == 0) {return action.upload.focus()}
var msg = can.request(event, can.Option(), {_upload: "file", _handle: "true"})
// 上传文件
begin = new Date()
msg._progress = show
msg.upload = action.upload.files[0]
can.run(event, ["action", "upload"], function(msg) { can.run(event, ["action", "upload"], function(msg) {
can.user.toast(can, "上传成功"), can.run() can.user.toast(can, "上传成功"), can.run()
}, true) }, true)
}) },
action.upload.click() show: function (event, value, total, loaded) { now = new Date()
return ui value == 0 && action.begin(event)
ui.show.innerHTML = value+"%"
ui.cost.innerHTML = can.base.Duration(now - begin)
ui.size.innerHTML = can.base.Size(loaded)+"/"+can.base.Size(total)
can.page.Modify(can, ui.progress, {style: {width: value*(ui.output.offsetWidth-2)/100}})
},
}); can.page.Select(can, ui.action, "input[type=file]")[0].click()
return action
}, },
download: function(can, path, name) { download: function(can, path, name) {
var a = can.page.Append(can, document.body, [{type: "a", href: path, download: name||path.split("/").pop()}]).first var a = can.page.Append(can, document.body, [{type: "a", href: path, download: name||path.split("/").pop()}]).first
a.click(), can.page.Remove(can, a) a.click(), can.page.Remove(can, a)
}, },
logout: function(can) { downloads: function(can, text, name) { can.user.download(can, URL.createObjectURL(new Blob([text])), name) },
if (can.user.confirm("logout?")) {
can.run({}, ["action", "logout"], function(msg) {
can.user.Cookie(can, "sessid", "")
if (can.user.Search(can, "share")) { MergeURL: shy("地址链接", function(can, objs, clear) {
can.user.Search(can, "share", "") var path = location.pathname; objs._path && (path = objs._path, delete(objs._path))
} else { return can.base.MergeURL(location.origin+path+(clear?"":location.search), objs)
can.user.reload(true)
}
})
}
},
MergeURL: shy("地址链接", function(can, objs, clear) { var obj = objs || {}; var path = location.pathname;
obj._path && (path = obj._path, delete(obj._path))
!clear && can.core.Item(can.user.Search(), function(key, value) {obj[key] || (obj[key] = value)});
return can.core.List([location.origin+path, can.core.Item(obj, function(key, value) {
if (!value) { return }
return can.core.List(value, function(value) {return key+"="+encodeURIComponent(value)}).join("&")
}).join("&")], function(item) { return item? item: undefined }).join("?")
}), }),
Search: shy("请求参数", function(can, key, value) { var args = {} Search: shy("请求参数", function(can, key, value) { var args = {}
location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("=") location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("=")

View File

@ -1,4 +1,5 @@
a { a {
color:yellow; color:yellow;
} }
body.mobile.landscape fieldset.Header.head { body.mobile.landscape fieldset.Header.head {
@ -62,6 +63,9 @@ body.mobile select {
body.mobile div.carte { body.mobile div.carte {
font-size:24px; font-size:24px;
} }
body.mobile div.input.login input {
font-size:24px
}
body { body {
margin:0; padding:0; margin:0; padding:0;
@ -105,24 +109,26 @@ input[type=text] {
input[type=text]:hover { input[type=text]:hover {
background-color:white; background-color:white;
} }
input[type=button] {
background-color:black; color:cyan;
letter-spacing:4px;
padding-left:10px;
cursor:pointer;
}
input[type=button]:hover {
background-color:gray; color:cyan;
}
td>input[type=button][name=remove] { td>input[type=button][name=remove] {
background-color:red; background-color:red;
} }
td>input[type=button][name=create] { td>input[type=button][name=create] {
background-color:blue; background-color:blue;
} }
input[type=button] {
background-color:black; color:cyan;
letter-spacing:4px;
padding-left:10px;
}
input[type=button]:hover {
background-color:gray; color:cyan;
}
select { select {
box-shadow: 4px 4px 10px 1px #626bd0; box-shadow: 4px 4px 10px 1px #626bd0;
background-color:black; color:cyan; background-color:black; color:cyan;
padding:0 10px; padding:0 10px;
cursor:pointer;
} }
option { option {
font-family:monospace; font-family:monospace;
@ -147,7 +153,7 @@ table.content {
/* width:-webkit-fill-available; */ /* width:-webkit-fill-available; */
border:0; white-space:pre; border:0; white-space:pre;
font-size:14px; font-family:monospace; font-size:14px; font-family:monospace;
cursor:pointer; overflow: auto; overflow: auto;
} }
table.content tr { table.content tr {
background-color:#04272f45; background-color:#04272f45;
@ -185,6 +191,13 @@ table.content td:hover {
h1 { h1 {
margin:0; margin:0;
clear:both;
}
h2 {
clear:both;
}
h2 {
clear:both;
} }
h1:hover { h1:hover {
background:green; background:green;
@ -198,6 +211,9 @@ h3:hover {
background:green; background:green;
cursor:pointer; cursor:pointer;
} }
div.item {
cursor:pointer;
}
div.code { div.code {
background-color:#343a3445; color:white; background-color:#343a3445; color:white;
font-size:14px; font-family:monospace; font-size:14px; font-family:monospace;
@ -216,33 +232,37 @@ div.hidden {
div.toast { div.toast {
background:#0e3369b3; color:yellow; background:#0e3369b3; color:yellow;
position:fixed; position:fixed; z-index:100;
overflow:auto; padding:5px; overflow:auto;
padding:5px;
z-index:100;
} }
div.toast a { div.toast a {
color:yellow; color:yellow;
} }
div.toast div.title { div.toast div.title {
font-size:14px; color:#cae850; font-size:14px;
color:#cae850; cursor:copy;
float:left;
}
div.toast div.duration {
color:gray; font-size:14px;
float:right;
cursor:pointer;
} }
div.toast div.content { div.toast div.content {
text-align:center; text-align:center;
white-space:pre; white-space:pre;
clear:both;
} }
div.toast div.duration { div.toast div.action div.item {
font-size:14px; float:left;
color:gray;
} }
div.toast div.progress { div.toast div.progress {
border:solid 2px green; height:10px; border:solid 2px green;
height:10px; margin-left:-2px;
clear:both;
} }
div.toast div.progress div.current { div.toast div.progress div.current {
background:red; height:10px; background:red;
height:10px;
} }
div.carte { div.carte {
@ -255,11 +275,24 @@ div.carte {
} }
div.carte div.item { div.carte div.item {
padding:3px 12px; padding:3px 12px;
cursor:pointer;
} }
div.carte div.item:hover { div.carte div.item:hover {
background:red; background:red;
} }
div.input {
position:fixed;
background-color:#0d4142a6;
z-index:50;
}
div.input div.item {
float:left;
}
div.input.login {
padding:10px;
}
div.input.login input {
font-size:18px
}
div.upload { div.upload {
background:black; color:yellow; background:black; color:yellow;
@ -270,6 +303,26 @@ div.upload {
div.upload div.item { div.upload div.item {
float:left; float:left;
} }
div.upload div.output {
border:solid 1px red;
clear:both;
}
div.upload div.progress {
width:0; height:10px;
background:red;
}
div.upload div.status div.cost {
float:left;
}
div.upload div.status div.show {
float:right;
}
div.upload div.status div.size {
text-align:center;
}
div.upload input[type=file] {
width: 240px;
}
div.story[data-type=spark] { div.story[data-type=spark] {
background-color:#2169a9a6; color:white; background-color:#2169a9a6; color:white;
@ -388,6 +441,9 @@ fieldset>div.output div.project div.list {
margin-left:10px; margin-left:10px;
} }
body>fieldset.input table {
color:white;
}
body>fieldset.input td { body>fieldset.input td {
word-break:keep-all; word-break:keep-all;
} }

View File

@ -19,7 +19,6 @@ fieldset.Action>div.action div.item {
fieldset.Action>div.action div.item:hover { fieldset.Action>div.action div.item:hover {
border-bottom:solid 2px red; border-bottom:solid 2px red;
background-color:#2e515f; background-color:#2e515f;
cursor:pointer;
} }
fieldset.Action>div.action div.item.select { fieldset.Action>div.action div.item.select {
border-bottom:solid 2px red; border-bottom:solid 2px red;

View File

@ -15,12 +15,17 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg)
}, function() { }, function() {
can.onaction._layout(can, can.Conf(can._LAYOUT)||can.user.Search(can, can._LAYOUT)) can.onaction._layout(can, can.Conf(can._LAYOUT)||can.user.Search(can, can._LAYOUT))
}) })
can.page.Modify(can, can._output, {onmouseover: function(event) {
Volcanos.meta.float.carte && can.page.Remove(can, Volcanos.meta.float.carte._target)
// Volcanos.meta.float.input && can.page.Remove(can, Volcanos.meta.float.input._target)
}})
}, },
_plugin: function(can, river, storm, sub, item) { _plugin: function(can, river, storm, sub, item) {
sub.run = function(event, cmds, cb) { var msg = sub.request(event) sub.run = function(event, cmds, cb) { var msg = sub.request(event)
var toast = msg.Option("_toast") && can.user.toast(can, msg.Option("_toast"), "", 1000000) var toast = msg.Option("_toast") && can.user.toast(can, msg.Option("_toast"), "", 1000000)
return can.run(event, (can.onengine[cmds[0]]? []: [river, storm, item.id||item.index||item.key+"."+item.name]).concat(cmds), function(msg) { return can.run(event, (can.onengine[cmds[0]]? []: [river, storm, item.id||item.index||item.key+"."+item.name]).concat(cmds), function(msg) {
toast && toast.Close(), can.base.isFunc(cb) && cb(msg) toast && toast.close(), can.base.isFunc(cb) && cb(msg)
}) })
}, can._plugins = (can._plugins||[]).concat([sub]) }, can._plugins = (can._plugins||[]).concat([sub])
@ -66,7 +71,7 @@ Volcanos("onengine", {help: "解析引擎", list: [],
if (!storm || cmds.length != 2) { return false } if (!storm || cmds.length != 2) { return false }
if (storm.index) { cmds = [can._ACTION, "command"].concat(storm.index) if (storm.index) { cmds = [can._ACTION, "command"].concat(storm.index)
can.misc.Runs(event, can, {names: can._name}, cmds, cb) can.run(event, cmds, cb)
} else { } else {
can.core.List(storm.action, function(value) { can.core.List(storm.action, function(value) {
msg.Push("name", value.name||"") msg.Push("name", value.name||"")

View File

@ -32,6 +32,11 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.onimport._menu(can, msg, target) can.onimport._menu(can, msg, target)
can.base.isFunc(cb) && cb(msg) can.base.isFunc(cb) && cb(msg)
can.page.Modify(can, can._output, {onmouseover: function(event) {
Volcanos.meta.float.carte && can.page.Remove(can, Volcanos.meta.float.carte._target)
Volcanos.meta.float.input && can.page.Remove(can, Volcanos.meta.float.input._target)
}})
}, },
_title: function(can, msg, target) { _title: function(can, msg, target) {
can.user.title(can.user.Search(can, can._TITLE)||can.user.Search(can, "pod")) can.user.title(can.user.Search(can, can._TITLE)||can.user.Search(can, "pod"))
@ -122,7 +127,12 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
_time: function(can, target) { _time: function(can, target) {
can.core.Timer({interval: 1000}, function() { can.onimport.time(can, target) }) can.core.Timer({interval: 1000}, function() { can.onimport.time(can, target) })
can.onappend.figure(can, {style: {left: "", right: "0", top: can._target.offsetHeight, "min-width": 310}}, "@date", target) can.onappend.figure(can, {style: {"min-width": 306}}, "@date", target)
target.onmouseenter = function(event) { target.click()
can.core.Timer(10, function() {
can.onlayout.figure(event, can, Volcanos.meta.float.input._target)
})
}
}, },
time: function(can, target) { can.onlayout.topic(can) time: function(can, target) { can.onlayout.topic(can)
target.innerHTML = can.base.Time(null, "%w %H:%M:%S") target.innerHTML = can.base.Time(null, "%w %H:%M:%S")
@ -201,7 +211,7 @@ Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg,
}) })
can.user.jumps(can.user.MergeURL(can, args, true)) can.user.jumps(can.user.MergeURL(can, args, true))
}, },
carte: function(event, can, list, cb) { can.user.carte(event, can, can.onaction, list) }, carte: function(event, can, list, cb) { can.user.carte(event, can, can.onaction, list, cb) },
river: function(event, can) { can.onaction.River(can) }, river: function(event, can) { can.onaction.River(can) },
black: function(event, can, button) { black: function(event, can, button) {
can.onlayout.topic(can, button) can.onlayout.topic(can, button)
@ -239,7 +249,7 @@ Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg,
var toast = can.user.toast(can, "打包中...", "webpack", 1000000) var toast = can.user.toast(can, "打包中...", "webpack", 1000000)
can.run(event, ["webpack"], function(msg) { can.run(event, ["webpack"], function(msg) {
toast.Close(), can.user.toast(can, "打包成功", "webpack") toast.close(), can.user.toast(can, "打包成功", "webpack")
can.user.download(can, "/share/local/"+msg.Result(), name+".html") can.user.download(can, "/share/local/"+msg.Result(), name+".html")
}) })
}) })
@ -255,7 +265,7 @@ Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg,
can.user.share(can, can.request(event), [can._ACTION, can._SHARE].concat(arg)) can.user.share(can, can.request(event), [can._ACTION, can._SHARE].concat(arg))
}, },
usernick: function(event, can) { usernick: function(event, can) {
can.user.input(event, can, [{_input: "text", name: "usernick", value: can.Conf(can._USERNAME)}], function(ev, button, data, list, args) { can.user.input(event, can, [{name: "usernick", value: can.Conf(can._USERNAME)}], function(ev, button, data, list, args) {
can.run(event, ["usernick", list[0]], function(msg) { can.run(event, ["usernick", list[0]], function(msg) {
can.page.Select(can, can._output, "div.username", function(item) { can.page.Select(can, can._output, "div.username", function(item) {
can.page.Modify(can, item, can.Conf(can._USERNAME, list[0])) can.page.Modify(can, item, can.Conf(can._USERNAME, list[0]))

View File

@ -4,7 +4,6 @@ fieldset.River {
fieldset.River>div.output div.item { fieldset.River>div.output div.item {
border-left:solid 3px #00ffae; border-left:solid 3px #00ffae;
padding:3px 16px; padding:3px 16px;
cursor:pointer;
} }
fieldset.River>div.output div.item:hover { fieldset.River>div.output div.item:hover {
background-color:#2e515f; background-color:#2e515f;

View File

@ -9,7 +9,14 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
var select; msg.Table(function(value, index, array) { var select; msg.Table(function(value, index, array) {
var item = can.onimport._river(can, value) var item = can.onimport._river(can, value)
if (index == 0 || [value.hash, value.name].indexOf(can._main_river) > -1) { select = item } if (index == 0 || [value.hash, value.name].indexOf(can._main_river) > -1) { select = item }
}), select && select.click() })
select && select.click()
can.page.Modify(can, can._output, {onmouseover: function(event) {
Volcanos.meta.float.carte && can.page.Remove(can, Volcanos.meta.float.carte._target)
Volcanos.meta.float.input && can.page.Remove(can, Volcanos.meta.float.input._target)
}})
}, },
_main: function(can, msg) { _main: function(can, msg) {
can._main_river = "project", can._main_storm = "studio" can._main_river = "project", can._main_storm = "studio"
@ -41,18 +48,37 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.onaction.storm(event, can, meta.hash) can.onaction.storm(event, can, meta.hash)
}, function(event) { }, function(event) {
// 右键菜单 // 右键菜单
can.onaction.carte(event, can, can.ondetail.list, function(ev, button, module) { can.onaction.carte(event, can, can.ondetail.list, function(event, button, module) {
module[button](event, can, button, meta.hash) module[button](event, can, button, meta.hash)
}) })
}) })
!can.user.isMobile && can.page.Modify(can, item, {onmouseenter: function(event) { !can.user.isMobile && can.page.Modify(can, item, {onmouseenter: function(event) {
can.onaction.carte(event, can, can.ondetail.list, function(ev, button, module) { can.onaction.carte(event, can, can.ondetail.list, function(event, button, module) {
module[button](event, can, item, meta.hash) module[button](event, can, item, meta.hash)
}) })
}}) }})
return item return item
}, },
_storm: function(can, meta, river) {
return {text: [meta.name, "div", "item"], onclick: function(event) {
// 左键点击
can.onaction.action(event, can, river, meta.hash)
can.user.title(can._main_title || meta.name)
}, onmouseenter: function(event) {
can.onaction.carte(event, can, ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], function(event, button, module) {
module[button](event, can, button, river, meta.hash)
})
}, oncontextmenu: function(event) {
can.onaction.action(event, can, river, meta.hash)
can.user.title(can._main_title || meta.name)
// 右键点击
can.onaction.carte(event, can, ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], function(event, button, module) {
module[button](event, can, button, river, meta.hash)
})
}}
},
height: function(can, height) { height: function(can, height) {
can.page.Modify(can, can._target, {style: { can.page.Modify(can, can._target, {style: {
@ -86,29 +112,16 @@ Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg,
can.onengine.listen(can, "action.touch", function() { can.onengine.listen(can, "action.touch", function() {
can.user.isMobile && can.onmotion.hidden(can) can.user.isMobile && can.onmotion.hidden(can)
Volcanos.meta.data.menu && can.page.Remove(can, Volcanos.meta.data.menu.first) Volcanos.meta.float.carte && can.page.Remove(can, Volcanos.meta.float.carte._target)
}) })
}, },
storm: function(event, can, river) { storm: function(event, can, river) {
var list = can.sublist[river]; if (list) { return can.page.Toggle(can, list) } var list = can.sublist[river]; if (list) { return can.onmotion.Toggle(can, list) }
can.run({}, [river, "tool"], function(msg) { can.run({}, [river, "tool"], function(msg) {
var select = 0; list = can.page.Append(can, can._output, [{view: "list", list: msg.Table(function(storm, index) { var select = 0; list = can.page.Append(can, can._output, [{view: "list", list: msg.Table(function(meta, index) {
river == can._main_river && storm.hash == can._main_storm && (select = index) river == can._main_river && meta.hash == can._main_storm && (select = index)
return can.onimport._storm(can, meta, river)
return {text: [storm.name, "div", "item"], onclick: function(event) {
// 左键点击
can.onaction.action(event, can, river, storm.hash)
can.user.title(can._main_title || storm.name)
}, oncontextmenu: function(event) {
can.onaction.action(event, can, river, storm.hash)
can.user.title(can._main_title || storm.name)
// 右键点击
can.onaction.carte(event, can, ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], function(ev, button, module) {
module[button](event, can, button, river, storm.hash)
})
}}
}) }]).first, list.children.length > 0 && list.children[select].click() }) }]).first, list.children.length > 0 && list.children[select].click()
event.target.nextSibling && can._output.insertBefore(list, event.target.nextSibling) event.target.nextSibling && can._output.insertBefore(list, event.target.nextSibling)
@ -127,8 +140,8 @@ Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg,
create: function(event, can) { create: function(event, can) {
can.user.input(event, can, [ can.user.input(event, can, [
["类型", "public", "protected", "private"], ["类型", "public", "protected", "private"],
{_input: "text", name: "群名", value: "hi"}, {name: "群名", value: "hi"},
{_input: "text", name: "简介", value: "hello"}, {name: "简介", value: "hello"},
], function(event, button, meta, list) { ], function(event, button, meta, list) {
can.run(event, ["action", "create"].concat(["type", list[0], "name", list[1], "text", list[2]]), function(msg) { can.run(event, ["action", "create"].concat(["type", list[0], "name", list[1], "text", list[2]]), function(msg) {
can.user.Search(can, {river: msg.Result()}) can.user.Search(can, {river: msg.Result()})
@ -136,8 +149,8 @@ Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg,
}) })
}, },
carte: function(event, can, list, cb) { carte: function(event, can, list, cb) {
var ui = can.user.carte(event, can, can.ondetail, list, cb) var carte = can.user.carte(event, can, can.ondetail, list, cb)
can.page.Modify(can, ui.first, {style: { can.page.Modify(can, carte._target, {style: {
left: event.clientX-event.offsetX+event.target.offsetWidth-3, top: event.clientY-event.offsetY, left: event.clientX-event.offsetX+event.target.offsetWidth-3, top: event.clientY-event.offsetY,
}}) }})
}, },
@ -156,7 +169,7 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
"共享群组": function(event, can, button, river) { "共享群组": function(event, can, button, river) {
can.user.input(event, can, [ can.user.input(event, can, [
{_input: "text", name: "name", value: river}, {name: "name", value: river},
], function(event, button, meta, list) { ], function(event, button, meta, list) {
var msg = can.request(event) var msg = can.request(event)
can.user.share(can, msg, [river, "action", "share", "type", can._RIVER, "name", meta.name]) can.user.share(can, msg, [river, "action", "share", "type", can._RIVER, "name", meta.name])
@ -179,8 +192,8 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
"添加应用": function(event, can, button, river) { "添加应用": function(event, can, button, river) {
can.user.input(event, can, [ can.user.input(event, can, [
["类型", "public", "protected", "private"], ["类型", "public", "protected", "private"],
{_input: "text", name: "名称", value: "hi"}, {name: "名称", value: "hi"},
{_input: "text", name: "简介", value: "hello"}, {name: "简介", value: "hello"},
], function(event, button, meta, list) { ], function(event, button, meta, list) {
can.run({}, [river, "tool", "action", "create"].concat(["type", list[0], "name", list[1], "text", list[2]]), function(msg) { can.run({}, [river, "tool", "action", "create"].concat(["type", list[0], "name", list[1], "text", list[2]]), function(msg) {
can.user.Search(can, {river: river, storm: msg.Result()}) can.user.Search(can, {river: river, storm: msg.Result()})
@ -203,7 +216,7 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
"共享应用": function(event, can, button, river, storm) { "共享应用": function(event, can, button, river, storm) {
can.user.input(event, can, [ can.user.input(event, can, [
{_input: "text", name: "name", value: storm}, {name: "name", value: storm},
], function(event, button, meta, list) { ], function(event, button, meta, list) {
var msg = can.request(event) var msg = can.request(event)
can.user.share(can, msg, [river, "action", "share", "type", can._STORM, "name", meta.name, can.user.share(can, msg, [river, "action", "share", "type", can._STORM, "name", meta.name,
@ -224,7 +237,7 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
can.search(event, ["Action.onexport.args"], function(item, next, index, array) { can.search(event, ["Action.onexport.args"], function(item, next, index, array) {
var msg = can.request({}, {hash: storm, id: item.dataset.id}) var msg = can.request({}, {hash: storm, id: item.dataset.id})
can.run(msg._event, [river, "tool", "action", "modify", "arg", item.dataset.args], function(msg) { can.run(msg._event, [river, "tool", "action", "modify", "arg", item.dataset.args], function(msg) {
can.user.toast(can, "保存"+(index+1)+"/"+array.length) can.user.toast(can, (index+1)+"/"+array.length, "保存参数", 10000, (index+1)/array.length)
next() next()
}) })
}) })
@ -268,7 +281,7 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
"共享主机": function(event, can, button, river, storm) { "共享主机": function(event, can, button, river, storm) {
can.run(event, ["action", "invite"], function(msg) { can.run(event, ["action", "invite"], function(msg) {
var toast = can.user.toast(can, { can.user.toast(can, {
title: "共享主机", content: msg.Result(), title: "共享主机", content: msg.Result(),
button: ["close"], duration: -1, width: -100, button: ["close"], duration: -1, width: -100,
}) })
@ -288,9 +301,9 @@ Volcanos("ondetail", {help: "菜单交互", list: ["共享群组", "添加用户
var msg = can.request(event, {action: "start"}) var msg = can.request(event, {action: "start"})
can.run(event, cmds, cb, silent) can.run(event, cmds, cb, silent)
}}, [ }}, [
{_input: "text", name: "name", value: "@key"}, {name: "name", value: "@key"},
{_input: "text", name: "repos", value: "@key"}, {name: "repos", value: "@key"},
{_input: "text", name: "template", value: "@key"}, {name: "template", value: "@key"},
], function(event, button, data, list, args) { ], function(event, button, data, list, args) {
can.run(event, ["action", "start"].concat(args), function(msg) { can.run(event, ["action", "start"].concat(args), function(msg) {
can.user.open(can.user.MergeURL(can, {pod: can.core.Keys(can.user.Search(can, "pod"), msg.Option("name"))})) can.user.open(can.user.MergeURL(can, {pod: can.core.Keys(can.user.Search(can, "pod"), msg.Option("name"))}))

View File

@ -13,7 +13,7 @@ Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, meta,
} }
}, },
"upload": function(event, can) { can.user.upload(event, can) }, upload: function(event, can) { can.user.upload(event, can) },
"执行": function(event, can) { can.run(event) }, "执行": function(event, can) { can.run(event) },
"刷新": function(event, can) { can.run(event) }, "刷新": function(event, can) { can.run(event) },
"查看": function(event, can) { can.run(event) }, "查看": function(event, can) { can.run(event) },

View File

@ -7,3 +7,7 @@ fieldset.input.date div.output td.last {
fieldset.input.date div.output td.next { fieldset.input.date div.output td.next {
color:gray; color:gray;
} }
fieldset.input.date div.output td {
padding:2px 12px;
}

View File

@ -56,7 +56,7 @@ Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(e
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")} 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")} for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")}
can.onlayout.figure(event, can); return now return can.onlayout.figure(event, can), now
}; show(now) }; show(now)
}} }, ["/plugin/input/date.css"]) }} }, ["/plugin/input/date.css"])

View File

@ -24,7 +24,7 @@ Volcanos("onaction", {help: "操作数据", list: [], _init: function(can, msg,
video.srcObject = stream, video.play() video.srcObject = stream, video.play()
can.ui.video = video can.ui.video = video
}, function(error) { }, function(error) {
can.base.Log("open camera", error) can.misc.Log("open camera", error)
}) })
}, },
snapshot: function(event, can) { snapshot: function(event, can) {

View File

@ -95,7 +95,7 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb,
can.onimport.tabview(can, path, file, "", cb) can.onimport.tabview(can, path, file, "", cb)
}, _init: function(item) { }, _init: function(item) {
can.core.Timer(10, function() { item.click() }) can.core.Timer(10, function() { item.click() })
can.page.EnableDrop(can, can._action, "div.file", item) can.onmotion.EnableDrop(can, can._action, "div.file", item)
}} }}
]).last ]).last
}, true) }, true)
@ -264,7 +264,7 @@ Volcanos("onaction", {help: "控件交互", list: ["项目"],
can.page.Modify(can, can.ui.search, {style: {display: ""}}) can.page.Modify(can, can.ui.search, {style: {display: ""}})
value = can.ui.word.value = value || can.ui.word.value || "main" value = can.ui.word.value = value || can.ui.word.value || "main"
var msg = can.request(event, {_toast: "搜索中..."}) can.request(event, {_toast: "搜索中..."})
can.run(event, ["action", "search", can.parse, value, can.Option("path")], function(msg) { can.run(event, ["action", "search", can.parse, value, can.Option("path")], function(msg) {
can.onmotion.clear(can, can.ui.tags) can.onmotion.clear(can, can.ui.tags)
@ -304,8 +304,8 @@ Volcanos("onaction", {help: "控件交互", list: ["项目"],
favorLine: function(can, value) { favorLine: function(can, value) {
can.user.input(event, can, [ can.user.input(event, can, [
{_input: "text", name: "topic", value: "@key"}, {name: "topic", value: "@key"},
{_input: "text", name: "name", value: "@key"}, {name: "name", value: "@key"},
], function(event, button, meta, list) { ], function(event, button, meta, list) {
can.run(event, ["action", "favor", can.run(event, ["action", "favor",
"action", "insert", "topic", meta.topic||"some", "action", "insert", "topic", meta.topic||"some",

View File

@ -86,9 +86,8 @@ Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"
can.ui.current.focus() can.ui.current.focus()
}, },
_remote: function(event, can, key, arg, cb) { _remote: function(event, can, key, arg, cb) { can.request(event, {_toast: "执行中..."})
var toast = can.user.toast(can, "执行中...", key, 1000000) can.run(event, arg||["action", key, can.parse, can.Option("file"), can.Option("path")], cb||function(msg) {
can.run(event, arg||["action", key, can.parse, can.Option("file"), can.Option("path")], cb||function(msg) { toast.Close()
can.onappend.table(can, msg, function(value, key, index) { return {text: [value, "td"]} }, can.ui.output) can.onappend.table(can, msg, function(value, key, index) { return {text: [value, "td"]} }, can.ui.output)
can.onappend.board(can, msg.Result(), can.ui.output) can.onappend.board(can, msg.Result(), can.ui.output)
}, true) }, true)
@ -273,7 +272,7 @@ Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"
can.ui.current.setSelectionRange(can.ui.current.selectionStart, can.ui.current.selectionEnd) can.ui.current.setSelectionRange(can.ui.current.selectionStart, can.ui.current.selectionEnd)
}, },
jk: function(event, can) { jk: function(event, can) {
can.page.DelText(can.ui.current, can.ui.current.selectionStart-1, 1) can.onkeypop.DelText(can.ui.current, can.ui.current.selectionStart-1, 1)
can.onkeymap.insert.Escape(event, can) can.onkeymap.insert.Escape(event, can)
}, },
}, },

View File

@ -105,7 +105,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.onimport._figure(event, can, can.point = can.point.concat(point)) can.onimport._figure(event, can, can.point = can.point.concat(point))
}, },
onmousemove: function(event, can) { var point = can.onimport._point(event, can) onmousemove: function(event, can) { var point = can.onimport._point(event, can)
can.page.Prepos(event, event.target) can.onmotion.Prepos(event, event.target)
if (can.Action("go") == "run") { return can.page.Modify(can, event.target, {style: {cursor: ""}}) } if (can.Action("go") == "run") { return can.page.Modify(can, event.target, {style: {cursor: ""}}) }
if (can.Action("go") == "auto") { can.onaction._auto(can, event.target) } if (can.Action("go") == "auto") { can.onaction._auto(can, event.target) }
can.onimport._figure(event, can, can.point.concat(point)) can.onimport._figure(event, can, can.point.concat(point))
@ -213,8 +213,8 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
}, },
grid: function(event, can, point) { var target = event.target grid: function(event, can, point) { var target = event.target
if (target == can.svg) { return } if (target == can.svg) { return }
var p = point[point.length-1], pos = can.page.Prepos(event, target) var p = point[point.length-1], pos = can.onmotion.Prepos(event, target)
target.Val && can.page.Anchor(event, target, pos, p) target.Val && can.onmotion.Anchor(event, target, pos, p)
return p.target = target, p.anchor = pos, point return p.target = target, p.anchor = pos, point
}, },
draw: function(event, can, point) { if (point.length < 2) { return } draw: function(event, can, point) { if (point.length < 2) { return }
@ -327,7 +327,7 @@ Volcanos("onaction", {help: "组件菜单", list: [
can.user.toast(can, "保存成功") can.user.toast(can, "保存成功")
}, true) }, true)
}, },
"项目": function(event, can) { can.page.Toggle(can, can.ui.project) }, "项目": function(event, can) { can.onmotion.Toggle(can, can.ui.project) },
"显示": function(event, can) { can.onmotion.show(can, {value: 100, length: 10}, null, can.group) }, "显示": function(event, can) { can.onmotion.show(can, {value: 100, length: 10}, null, can.group) },
"隐藏": function(event, can) { can.onmotion.hide(can, {value: 100, length: 10}, null, can.group) }, "隐藏": function(event, can) { can.onmotion.hide(can, {value: 100, length: 10}, null, can.group) },
"添加": function(event, can) { "添加": function(event, can) {
@ -359,7 +359,7 @@ Volcanos("onaction", {help: "组件菜单", list: [
_auto: function(can, target) { _auto: function(can, target) {
if (can.point.length > 0) { return } if (can.point.length > 0) { return }
var pos = can.page.Prepos(event, event.target) var pos = can.onmotion.Prepos(event, event.target)
if (target.tagName == "text") { if (target.tagName == "text") {
} else if (target == can.svg) { } else if (target == can.svg) {
@ -406,7 +406,7 @@ Volcanos("onaction", {help: "组件菜单", list: [
return ship.pid && (ship.target = can.page.Select(can, can.svg, "."+ship.pid)[0]) && ship return ship.pid && (ship.target = can.page.Select(can, can.svg, "."+ship.pid)[0]) && ship
}) })
} }
}), pos: can.page.Prepos(event, target)} }), pos: can.onmotion.Prepos(event, target)}
} }
return return
} }
@ -415,12 +415,12 @@ Volcanos("onaction", {help: "组件菜单", list: [
} }
can.core.List(can.current.begin, function(item) { var figure = can.onfigure._get(can, item.target) can.core.List(can.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
can.page.Resizes(event, item.target, item, point[0], point[1], can.current.pos) can.onmotion.Resizes(event, item.target, item, point[0], point[1], can.current.pos)
can.page.Select(can, can.svg, "."+item.target.Value("text"), function(text) { can.page.Select(can, can.svg, "."+item.target.Value("text"), function(text) {
text.Value(figure.text(can, {}, item.target)) text.Value(figure.text(can, {}, item.target))
}) })
can.core.List(item.ship, function(ship) { can.core.List(item.ship, function(ship) {
var p = can.page.Anchor(event, item.target, ship.anchor, {}) var p = can.onmotion.Anchor(event, item.target, ship.anchor, {})
if (ship.which == 0) { if (ship.which == 0) {
ship.target.Val("x1", p.x) ship.target.Val("x1", p.x)
ship.target.Val("y1", p.y) ship.target.Val("y1", p.y)

View File

@ -5,28 +5,6 @@ fieldset.word>form.option>div.item.text input {
fieldset.word a { fieldset.word a {
word-break:break-word; word-break:break-word;
} }
fieldset.word h1.story {
clear:both;
}
fieldset.word h2.story {
clear:both;
}
fieldset.word h3.story {
clear:both;
}
fieldset.word h1:hover {
background:green;
cursor:pointer;
}
fieldset.word h2:hover {
background:green;
cursor:pointer;
}
fieldset.word h3:hover {
background:green;
cursor:pointer;
}
fieldset.word ul.story[data-type=premenu] { fieldset.word ul.story[data-type=premenu] {
cursor:pointer; cursor:pointer;
} }

View File

@ -133,12 +133,12 @@ Volcanos("onaction", {help: "控件交互", list: [],
"快闪": function(event, sub) { sub.sup.onaction.flash(sub) }, "快闪": function(event, sub) { sub.sup.onaction.flash(sub) },
"网格": function(event, sub) { sub.sup.onaction.grid(sub) }, "网格": function(event, sub) { sub.sup.onaction.grid(sub) },
"大纲": function(event, sub) { sub.page.Toggle(sub, sub.ui.project) }, "大纲": function(event, sub) { sub.onmotion.Toggle(sub, sub.ui.project) },
"首页": function(event, sub) { sub.sup.onaction.show(sub, 0) }, "首页": function(event, sub) { sub.sup.onaction.show(sub, 0) },
"上一页": function(event, sub) { sub.sup.onaction.prev(sub, sub.ui.content) }, "上一页": function(event, sub) { sub.sup.onaction.prev(sub, sub.ui.content) },
"菜单": function(event, sub) { sub.sup.onaction.show(sub, event.target.selectedIndex) }, "菜单": function(event, sub) { sub.sup.onaction.show(sub, event.target.selectedIndex) },
"下一页": function(event, sub) { sub.sup.onaction.next(sub, sub.ui.content) }, "下一页": function(event, sub) { sub.sup.onaction.next(sub, sub.ui.content) },
"隐藏": function(event, sub) { sub.page.Toggle(sub, sub._output) }, "隐藏": function(event, sub) { sub.onmotion.Toggle(sub, sub._output) },
"结束": function(event, sub) { sub.page.Remove(sub, sub._target) "结束": function(event, sub) { sub.page.Remove(sub, sub._target)
sub.onengine.signal(sub, "keymap.focus", sub.request(event, {cb: null})) sub.onengine.signal(sub, "keymap.focus", sub.request(event, {cb: null}))
}, },

View File

@ -98,8 +98,8 @@ Volcanos("onaction", {help: "交互操作", list: ["保存参数", "清空参数
res.push(can.core.Item(line, function(key, value) { return value }).join(",")) res.push(can.core.Item(line, function(key, value) { return value }).join(","))
}) })
res.length > 1 && can.user.download(can, URL.createObjectURL(new Blob([res.join("\n")])), meta.name+".csv") res.length > 1 && can.user.downloads(can, res.join("\n"), meta.name+".csv")
msg.result && can.user.download(can, URL.createObjectURL(new Blob([msg.Result()])), meta.name+".txt") msg.result && can.user.downloads(can, msg.Result(), meta.name+".txt")
}, },
"清空数据": function(event, can) { "清空数据": function(event, can) {
can.onmotion.clear(can, can._output) can.onmotion.clear(can, can._output)
@ -135,10 +135,10 @@ Volcanos("onaction", {help: "交互操作", list: ["保存参数", "清空参数
can.run(event, can.base.Simple("action", cmd, can.base.parseJSON(text)), function(msg) { can.run(event, can.base.Simple("action", cmd, can.base.parseJSON(text)), function(msg) {
can.user.toast(can, text, "添加成功"), can.run() can.user.toast(can, text, "添加成功"), can.run()
}, true) }, true)
}).catch((err) => { can.base.Log(err) }) }).catch((err) => { can.misc.Log(err) })
return return
} else { } else {
can.user.input(event, can, [{_input: "textarea"}], function(ev, button, data, list, args) { can.user.input(event, can, [{type: "textarea"}], function(ev, button, data, list, args) {
can.run(event, can.base.Simple("action", cmd, can.base.parseJSON(list[0])), function(msg) { can.run(event, can.base.Simple("action", cmd, can.base.parseJSON(list[0])), function(msg) {
can.user.toast(can, list[0], "添加成功"), can.run() can.user.toast(can, list[0], "添加成功"), can.run()
}, true) }, true)
@ -157,7 +157,7 @@ Volcanos("onaction", {help: "交互操作", list: ["保存参数", "清空参数
}, },
openLocation: function(event, can) { can.user.agent.openLocation(can.request(event)) }, openLocation: function(event, can) { can.user.agent.openLocation(can.request(event)) },
"参数": function(event, can) { can.page.Toggle(can, can._action) }, "参数": function(event, can) { can.onmotion.Toggle(can, can._action) },
"关闭": function(event, can) { can.page.Remove(can, can._target) }, "关闭": function(event, can) { can.page.Remove(can, can._target) },
"清空": function(event, can, name) { can.onmotion.clear(can, can._output) }, "清空": function(event, can, name) { can.onmotion.clear(can, can._output) },
}) })

View File

@ -11,7 +11,7 @@ function shy(help, meta, list, cb) {
cb.list = next("object") || [] cb.list = next("object") || []
return cb return cb
}; var _can_name = "" }; var _can_name = ""
var Volcanos = shy("火山架", {args: {}, data: {}, pack: {}, libs: [], cache: {}}, [], function(name, can, libs, cb) { var Volcanos = shy("火山架", {args: {}, pack: {}, libs: [], cache: {}, float: {}}, [], function(name, can, libs, cb) {
var meta = arguments.callee.meta, list = arguments.callee.list var meta = arguments.callee.meta, list = arguments.callee.list
if (typeof name == "object") { var Config = name; _can_name = "" if (typeof name == "object") { var Config = name; _can_name = ""
meta.libs = Config.libs, meta.volcano = Config.volcano meta.libs = Config.libs, meta.volcano = Config.volcano
@ -24,7 +24,7 @@ var Volcanos = shy("火山架", {args: {}, data: {}, pack: {}, libs: [], cache:
// 根模块 // 根模块
name = Config.name, can = {_follow: Config.name, _target: document.body} name = Config.name, can = {_follow: Config.name, _target: document.body}
libs = Preload.concat(Config.main.list, Config.libs), cb = function(can) { libs = Preload.concat(Config.main.list, Config.libs), cb = function(can) {
can.onengine._init(can, can.Conf(Config), Config.panels, function(msg) { can.base.Log(can.user.title(), "run", can) can.onengine._init(can, can.Conf(Config), Config.panels, function(msg) { can.misc.Log(can.user.title(), "run", can)
document.body.onresize = function() { can.onlayout._init(can, can._target) } document.body.onresize = function() { can.onlayout._init(can, can._target) }
}, can._target) }, can._target)
} }
@ -82,7 +82,7 @@ var Volcanos = shy("火山架", {args: {}, data: {}, pack: {}, libs: [], cache:
cmd: function(target, field) { cmd: function(target, field) {
return can.search({}, [target+".onaction."+field]) return can.search({}, [target+".onaction."+field])
}, },
search: function(event, cmds, cb) { can.run(event, ["search"].concat(cmds), cb, true) }, search: function(event, cmds, cb) { can.run && can.run(event, ["search"].concat(cmds), cb, true) },
Conf: function(key, value) { return can.core.Value(can._conf, key, value) }, _conf: {}, Conf: function(key, value) { return can.core.Value(can._conf, key, value) }, _conf: {},
// }; can = can || {}; for (var k in proto) { can.hasOwnProperty(k) || (can[k] = proto[k]) } // }; can = can || {}; for (var k in proto) { can.hasOwnProperty(k) || (can[k] = proto[k]) }
}; can = can || {}; can.__proto__ = proto }; can = can || {}; can.__proto__ = proto