diff --git a/frame.js b/frame.js index 6e560ba4..e1dc3ebd 100644 --- a/frame.js +++ b/frame.js @@ -6,7 +6,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.require([can.volcano], null, function(can, key, sub) { can[key] = sub }) can.run = function(event, cmds, cb) { var msg = can.request(event); cmds = cmds||[] return (can.onengine[cmds[0]]||can.onengine._remote)(event, can, msg, can, cmds, cb) - }, Volcanos.meta.args = can.user.args(can) + } can.user.title(can.misc.Search(can, chat.TITLE)||can.misc.Search(can, ice.POD)||location.host) can.core.Next(list, function(item, next) { item.type = chat.PANEL @@ -21,9 +21,9 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.onengine.listen(can, key, function(msg) { can.core.CallFunc(cb, {can: panel, msg: msg}) }) }), can.core.CallFunc([panel.onaction, chat._INIT], {can: panel, cb: next, target: panel._target}) }, target) - }, function() { can.misc.Log(can.user.title(), ice.RUN, can) + }, function() { can.misc.Info(can.user.title(), ice.RUN, can) can.onmotion._init(can, target), can.onkeymap._init(can) - can.onengine.listen(can, chat.ONSEARCH, function(msg, word) { word[0] == ctx.COMMAND && can.run(msg._event, ["can.command"]) }) + can.onengine.listen(can, chat.ONSEARCH, function(msg, word) { word[0] == ctx.COMMAND && can.run(msg, ["can.command"]) }) can.onengine.signal(can, chat.ONMAIN, can.request()), can.base.isFunc(cb) && cb() }) }, @@ -48,9 +48,9 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { return can.base.isFunc(cb) && cb(msg) } - var toast, _toast = msg.Option(chat._TOAST); if (_toast) { can.onmotion.delay(can, function() { toast = toast||can.user.toastProcess(can, _toast, msg._can._name) }) } + var toast, _toast = msg.Option(chat._TOAST); if (_toast) { can.onmotion.delay(can, function() { toast = toast||can.user.toastProcess(msg._can, _toast) }) } msg.option = can.core.List(msg.option, function(item) { return {_toast: true, _handle: true}[item] && delete(msg[item])? undefined: item }) - can.onengine.signal(can, chat.ONREMOTE, can.request({}, {_follow: panel._follow, _msg: msg, _cmds: cmds})) + can.onengine.signal(panel, chat.ONREMOTE, can.request({}, {_follow: panel._follow, _msg: msg, _cmds: cmds})) can.getHeader("topic", function(topic) { can.request(event, {topic: topic}) }) var names = msg.Option(chat._NAMES)||panel._names||((can.Conf("iceberg")||Volcanos.meta.iceberg)+panel._name) @@ -82,7 +82,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { }), listen: shy("监听事件", function(can, name, cb) { arguments.callee.meta[name] = (arguments.callee.meta[name]||[]).concat(cb) }), signal: shy("触发事件", function(can, name, msg) { msg = msg||can.request(); var _msg = name == chat.ONREMOTE? msg.Option("_msg"): msg - _msg.Option("log.disable") != ice.TRUE && can.misc.Log(gdb.SIGNAL, name, (msg._cmds||[]), _msg) + _msg.Option("log.disable") != ice.TRUE && can.misc.Log(gdb.SIGNAL, name, can._name, (msg._cmds||[]).join(ice.SP), _msg) return can.core.List(can.onengine.listen.meta[name], function(cb) { can.core.CallFunc(cb, {event: msg._event, msg: msg}) }).length }), }) @@ -345,13 +345,15 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { meta.name = meta.name||value.name meta.help = meta.help||value.help meta.args = can.base.getValid(can.base.Obj(meta.args), can.base.Obj(meta.arg), can.base.Obj(value.args), can.base.Obj(value.arg))||[] + if (can.misc.Debug(can, "plugin", meta.index, meta.args, meta)) { debugger } can.onappend._init(can, meta, [chat.PLUGIN_STATE_JS], function(sub, skip) { sub._index = value.index||meta.index sub.run = function(event, cmds, cb) { can.runActionCommand(event, sub._index, cmds, cb) } can.base.isFunc(cb) && cb(sub, meta, skip) }, target||can._output, field) }, plugin: function(can, meta, cb, target, field) { meta = meta||{}, meta.index = meta.index||can.core.Keys(meta.ctx, meta.cmd) - var p = can.onengine.plugin(can, meta.index), res = {}; function cbs(sub, meta, skip) { res.__proto__ = sub, cb(sub, meta, skip) } + if (can.misc.Debug(can, "plugin", meta.index, meta.args, meta)) { debugger } + var p = can.onengine.plugin(can, meta.index), res = {}; function cbs(sub, meta, skip) { kit.proto(res, sub), cb(sub, meta, skip) } (meta.inputs && meta.inputs.length > 0 || meta.meta)? /* 局部命令 */ can.onappend._plugin(can, {meta: meta.meta, list: meta.list}, meta, cbs, target, field): p? /* 前端命令 */ can.onappend._plugin(can, {name: meta.index, help: p.help, meta: p.meta, list: p.list}, meta, function(sub, meta, skip) { sub.run = function(event, cmds, cb) { var _cb = p, n = 0 @@ -378,7 +380,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { can.onlayout.figure({target: target}, can, sub._target), can.page.style(sub, sub._target, meta.style) target._can = sub, sub.close = function() { can.page.Remove(can, sub._target), delete(target._can) } can.base.isFunc(cb) && cb(sub, _cbs), can.base.isFunc(meta._init) && meta._init(sub, sub._target) - }, can._root._target) + }, document.body) }, target, last) } }), can.onfigure[input]._init && can.onfigure[input]._init(can, target) }) }, diff --git a/lib/base.js b/lib/base.js index 144f3f15..c55e74ba 100644 --- a/lib/base.js +++ b/lib/base.js @@ -1,11 +1,12 @@ -Volcanos("base", {help: "数据类型", Int: function(val, def) { return parseInt(val)||def||0 }, +Volcanos("base", { + Int: function(val, def) { return parseInt(val)||def||0 }, Min: function(val, min) { return val > min? val: min }, Max: function(val, max) { return val < max? val: max }, Obj: function(val, def) { try { if (typeof val == lang.STRING) { if (val == "") { return def } val = JSON.parse(val) } if (val.length > 0) { return val } for (var k in val) { return val } return def - } catch (e) { return val && val.split && val.split(ice.FS) || def } + } catch (e) { return val&&val.split&&val.split(ice.FS) || def } }, Copy: function(to, from, skip) { if (!from) { return to } if (arguments.length == 2 || typeof skip == "boolean") { @@ -13,113 +14,68 @@ Volcanos("base", {help: "数据类型", Int: function(val, def) { return parseIn if (skip && to[k] != undefined) { continue } if (from[k] === "") { delete(to[k]); continue } to[k] = from[k] - } - return to - } - for (var i = 2; i < arguments.length; i++) { - var k = arguments[i]; to[k] = from[k] - } - return to + } return to + } for (var i = 2; i < arguments.length; i++) { var k = arguments[i]; to[k] = from[k] } return to }, Eq: function(to, from) { var call = arguments.callee if (typeof to != typeof from) { return false } - if (typeof to == lang.OBJECT) { - if (to.length != from.length) { return false } - for (var i = 0; i < to.length; i++) { - if (!call(to[i], from[i])) { return false } - } - for (var k in to) { - if (!call(to[k], from[k])) { return false } - } + if (typeof to == lang.OBJECT) { if (to.length != from.length) { return false } + for (var i = 0; i < to.length; i++) { if (!call(to[i], from[i])) { return false } } + for (var k in to) { if (!call(to[k], from[k])) { return false } } return true - } - return to === from + } return to === from }, Ext: function(path) { return (path.split(ice.PS).pop().split(ice.PT).pop()).toLowerCase() }, Path: function(path) { var res = "" for (var i = 0; i < arguments.length; i++) { if (!arguments[i]) { continue } res += (arguments[i][0]==ice.PS || res=="" || res[res.length-1]==ice.PS? "": ice.PS) + arguments[i].trim() - } - return res + } return res }, Args: function() { var res = [] for (var i = 0; i < arguments.length; i += 2) { if (typeof arguments[i] == lang.OBJECT) { - for (var k in arguments[i]) { res.push(encodeURIComponent(k)+"="+encodeURIComponent(arguments[i][k])) } - i--; continue + for (var k in arguments[i]) { res.push(encodeURIComponent(k)+"="+encodeURIComponent(arguments[i][k])) } i--; continue } else if (arguments[i]) { res.push(encodeURIComponent(arguments[i])+"="+encodeURIComponent(arguments[i+1])) } - } - return res.join("&") + } return res.join("&") }, - MergeURL: function(url) { - var args = {}; (url.split("?")[1]||"").split("&").forEach(function(item) { if (!item) { return } - var ls = item.split("="); args[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) - }) - for (var i = 1; i < arguments.length; i++) { - switch (typeof arguments[i]) { - case lang.STRING: args[arguments[i]] = arguments[i+1], i++; break - case lang.OBJECT: - if (arguments[i].length > 0) { - for (var j = 0; j < arguments[i].length; j += 2) { args[arguments[i][j]] = arguments[i][j] } - } else { - for (var k in arguments[i]) { args[k] = arguments[i][k] } - } - break - } - } + MergeURL: function(url) { var args = this._parse(url); delete(args["_origin"]) + for (var i = 1; i < arguments.length; i++) { switch (typeof arguments[i]) { + case lang.STRING: args[arguments[i]] = arguments[i+1], i++; break + case lang.OBJECT: + if (arguments[i].length > 0) { + for (var j = 0; j < arguments[i].length; j += 2) { args[arguments[i][j]] = arguments[i][j] } + } else { + for (var k in arguments[i]) { args[k] = arguments[i][k] } + } + } } var list = []; for (var k in args) { k &&args[k] && list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k])) } return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "") }, - ParseURL: function(url) { var res = {link: url} - var list = url.split("?"); res["origin"] = list[0] + _parse: function(url, res) { var list = url.split("?"); res = res||{}, res["_origin"] = list[0] list[1] && list[1].split("&").forEach(function(item) { var ls = item.split("="); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) - }) - return res + }); return res }, - ParseJSON: function(str) { var res - if (typeof str == lang.OBJECT) { return str } - if (str.indexOf("http") == 0) { var ls = str.split("?") - res = {type: mdb.LINK, name: "", text: str} - res.name = ls[0].split("://").pop().split(ice.PS)[0] - ls[1] && ls[1].split("&").forEach(function(item) { var ls = item.split("=") - res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) - }) - return res - } - try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON - } catch (e) { res = {type: mdb.TEXT, text: str} } - return res + ParseURL: function(url) { var res = this._parse(url); res.link = url, res.origin = res._origin; return res }, + ParseJSON: function(str) { var res; if (typeof str == lang.OBJECT) { return str } + if (str.indexOf(ice.HTTP) == 0) { var res = this._parse(str, {type: mdb.LINK, name: "", text: str}); return res.name = res._origin.split("://").pop().split(ice.PS)[0], res } + try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON } catch (e) { res = {type: mdb.TEXT, text: str} } 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 - } + 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) }, Size: function(size) { size = parseInt(size) - if (size > 1000000000) { - return parseInt(size/1000000000) + ice.PT + parseInt(size/10000000%100) + "G" - } - if (size > 1000000) { - return parseInt(size/1000000) + ice.PT + parseInt(size/10000%100) + "M" - } - if (size > 1000) { - return parseInt(size/1000) + ice.PT + parseInt(size/10%100) + "K" - } + if (size > 1000000000) { return parseInt(size/1000000000) + ice.PT + parseInt(size/10000000%100) + "G" } + if (size > 1000000) { return parseInt(size/1000000) + ice.PT + parseInt(size/10000%100) + "M" } + if (size > 1000) { return parseInt(size/1000) + ice.PT + parseInt(size/10%100) + "K" } return size + "B" }, Number: function(d, n) { var result = [] @@ -131,43 +87,28 @@ Volcanos("base", {help: "数据类型", Int: function(val, def) { return parseIn Simple: function() { var res = [] for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; switch (typeof arguments[i]) { - case lang.NUMBER: res.push(arg); break - case lang.STRING: res.push(arg); break case lang.OBJECT: if (arg.length > 0) { res = res.concat(arg); break } for (var k in arg) { k && arg[k] && res.push(k, arg[k]) } break - default: res.push(arg); + default: res.push(arg) } - } - return res + } return res }, AddUniq: function(list, value) { list = list||[]; return list.indexOf(value) == -1 && list.push(value), list }, Date: function(time) { var now = new Date() if (typeof time == lang.STRING && time != "") { var ls = time.split(ice.SP) - var vs = ls[0].split("-") - now.setFullYear(parseInt(vs[0])) - now.setMonth(parseInt(vs[1])-1) - now.setDate(parseInt(vs[2])) - - var vs = ls[1].split(":") - now.setHours(parseInt(vs[0])) - now.setMinutes(parseInt(vs[1])) - now.setSeconds(parseInt(vs[2])) - } else if (time) { - now = time - } - return now + var vs = ls[0].split("-"); now.setFullYear(parseInt(vs[0])), now.setMonth(parseInt(vs[1])-1), now.setDate(parseInt(vs[2])) + var vs = ls[1].split(":"); now.setHours(parseInt(vs[0])), now.setMinutes(parseInt(vs[1])), now.setSeconds(parseInt(vs[2])) + } else if (time) { now = time } return now }, Time: function(time, fmt) { var now = this.Date(time) - var list = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] - // fmt = fmt||"%H:%M:%S" - fmt = fmt||"%y-%m-%d %H:%M:%S" + fmt = fmt||"%y-%m-%d %H:%M:%S" // fmt = fmt||"%H:%M:%S" fmt = fmt.replace("%y", now.getFullYear()) fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2)) fmt = fmt.replace("%d", this.Number(now.getDate(), 2)) - fmt = fmt.replace("%w", list[now.getDay()]) + fmt = fmt.replace("%w", ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][now.getDay()]) fmt = fmt.replace("%H", this.Number(now.getHours(), 2)) fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2)) fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2)) @@ -181,55 +122,26 @@ Volcanos("base", {help: "数据类型", Int: function(val, def) { return parseIn h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000 return res + (n > 0? ice.PT+parseInt(n/10): "") + "s" }, + isNight: function() { var now = new Date(); return now.getHours() < 7 || now.getHours() >= 17 }, - mod: function(index, total) { - return (index+total) % total - }, - getValid: function() { - for (var i = 0; i < arguments.length; i++) { var v = arguments[i] - if (typeof v == lang.OBJECT) { - if (v == null) { continue } - for (var k in v) { return v } - if (v.length > 0) { return v } - } else if (typeof v == lang.STRING && v) { - return v - } else if (v == undefined) { - continue - } else { - return v - } - } - }, isNumber: function(val) { return typeof val == lang.NUMBER }, isString: function(val) { return typeof val == lang.STRING }, isObject: function(val) { return typeof val == lang.OBJECT }, isArray: function(val) { return typeof val == lang.OBJECT && val.length != undefined }, isFunc: function(val) { return typeof val == lang.FUNCTION }, isFunction: function(val) { return typeof val == lang.FUNCTION }, - isCallback: function(key, value) { return key.indexOf("on") == 0 && typeof value == lang.FUNCTION }, isUndefined: function(val) { return val == undefined }, isNull: function(val) { return val == null }, - replaceAll: function(str) { - for (var i = 1; i < arguments.length; i += 2) { if (!arguments[i]) { continue } - if (str.replaceAll) { str = str.replaceAll(arguments[i], arguments[i+1]); continue } - if (arguments[i] && str.replace) { - while (str.indexOf(arguments[i]) > -1) { - str = str.replace(arguments[i], arguments[i+1]) - } - continue - } + getValid: function() { + for (var i = 0; i < arguments.length; i++) { var v = arguments[i] + if (typeof v == lang.OBJECT) { if (v == null) { continue } + if (v.length > 0) { return v } for (var k in v) { return v } + } else if (typeof v == lang.STRING && v) { return v + } else if (v == undefined) { continue + } else { return v } } - return str }, - count: function(str, s) { var n = 0 - for (var i = 0; i < str.length; i++) { - if (str[i] == s) { n++ } - } - return n - }, - random: function(max, min) { return min = min||0, parseInt(Math.random()*(max-min))+min }, - isNight: function() { var now = new Date(); return now.getHours() < 7 || now.getHours() >= 17 }, beginWith: function(str, begin) { return str.trim().indexOf(begin) == 0 }, endWith: function(str, end) { return str.lastIndexOf(end) + end.length == str.length }, trim: function(args) { if (this.isString(args)) { return args.trim() } @@ -237,21 +149,29 @@ Volcanos("base", {help: "数据类型", Int: function(val, def) { return parseIn return args }, trimPrefix: function(str, pre) { if (str.indexOf(pre) == -1) { return str } return str.slice(pre.length) }, - trimSuffix: function(str, end) { - var index = str.lastIndexOf(end) - if (index == -1 || index+end.length != str.length) { return str } return str.slice(0, index) - }, + trimSuffix: function(str, end) { var index = str.lastIndexOf(end); if (index == -1 || index+end.length != str.length) { return str } return str.slice(0, index) }, join: function(list, sp) { return (list||[]).join(sp||ice.SP) }, - joinKV: function(list, inner, outer) { var res = [] - for (var i = 0; i < list.length-1; i += 2) { - res.push(list[i]+(inner||": ")+list[i+1]) - } - return res.join(outer||" ") - }, joins: function(list, inner, outer) { for (var i = 0; i < list.length; i++) { list[i] = typeof list[i] == lang.STRING? list[i]: list[i].join(inner||ice.FS) - } - return list.join(outer||ice.SP) + } return list.join(outer||ice.SP) }, + joinKV: function(list, inner, outer) { var res = [] + for (var i = 0; i < list.length-1; i += 2) { + res.push(list[i]+(inner||": ")+list[i+1]) + } return res.join(outer||ice.SP) + }, + count: function(str, s) { var n = 0 + for (var i = 0; i < str.length; i++) { + if (str[i] == s) { n++ } + } return n + }, + replaceAll: function(str) { + for (var i = 1; i < arguments.length; i += 2) { if (!arguments[i]) { continue } + if (str.replaceAll) { str = str.replaceAll(arguments[i], arguments[i+1]); continue } + if (arguments[i] && str.replace) { while (str.indexOf(arguments[i]) > -1) { str = str.replace(arguments[i], arguments[i+1]) } } + } return str + }, + random: function(max, min) { return min = min||0, parseInt(Math.random()*(max-min))+min }, + mod: function(index, total) { return (index+total) % total }, }) diff --git a/lib/core.js b/lib/core.js index 891c4869..3ecadc4b 100644 --- a/lib/core.js +++ b/lib/core.js @@ -1,180 +1,52 @@ -Volcanos("core", {help: "数据结构", - Keys: shy("连接器", function() { var list = [] - for (var i = 0; i < arguments.length; i++) { var v = arguments[i] - switch (typeof v) { - case lang.OBJECT: for (var j = 0; j < v.length; j++) { list.push(v[j]) } break - case lang.NUMBER: list.push(v+""); break - case lang.FUNCTION: v = v() - default: v && list.push(v+"") - } - } - return list.join(ice.PT) - }), - Value: shy("存储器", function(data, key, value) { +Volcanos("core", { + Keys: function() { var list = [] + for (var i = 0; i < arguments.length; i++) { var v = arguments[i]; switch (typeof v) { + case lang.OBJECT: for (var j = 0; j < v.length; j++) { list.push(v[j]) } break + case lang.NUMBER: list.push(v+""); break + case lang.FUNCTION: v = v() + default: v && list.push(v+"") + } } return list.join(ice.PT) + }, + Value: function(data, key, value) { if (data == undefined) { return } if (key == undefined) { return data } - if (typeof key == lang.OBJECT && key.length > 0) { key = key.join(ice.PT) } if (typeof key == lang.OBJECT) { for (var k in key) { arguments.callee.call(this, data, k, key[k]) } return data } - - if (value != undefined) { - var _data = data - - var ls = key.split(ice.PT) - for (var i = 0; i < ls.length; i++) { - var _sub = _data[ls[i]]||{} - _data[ls[i]] = _sub - if (i == ls.length - 1) { - _data[ls[i]] = value - } else { - _data = _sub - } + if (value != undefined) { var _node = data, keys = key.split(ice.PT) + for (var i = 0; i < keys.length; i++) { var _next = _node[keys[i]]||{}; _node[keys[i]] = _next + if (i < keys.length - 1) { _node = _next } else { _node[keys[i]] = value } } - // data[key] = value } if (data[key] != undefined) { return data[key] } - - var p = data, ls = key.split(ice.PT); while (p && ls.length > 0) { - if (ls[0] == "-1") { ls[0] = p.length-1 } - p = p[ls[0]], ls = ls.slice(1) - } return p - }), - Split: shy("分词器", function(str) { if (!str || !str.length) { return [] } + var node = data, keys = key.split(ice.PT); while (node && keys.length > 0) { + if (keys[0] == "-1") { keys[0] = node.length-1 } node = node[keys[0]], keys = keys.slice(1) + } return node + }, + Split: function(str) { if (!str || !str.length) { return [] } var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { typeof arguments[i] == lang.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 space = _list(arg[0]||"\t ,;\n") // 空白符 var block = _list(arg[1]||"{[()]}") // 分隔符 var quote = _list(arg[2]||"'\"`") // 引用符 var trans = _list(arg[3]||"\\") // 转义符 - - var res = [], begin = 0; function push(obj) { - obj && res.push(typeof obj == lang.STRING || opt.detail? obj: obj.text), begin = -1 - } - - // 开始分词 + var res = [], begin = 0; function push(obj) { obj && res.push(typeof obj == lang.STRING || opt.detail? obj: obj.text), begin = -1 } for (var s = "", i = 0; i < str.length; i++) { - if (space[str[i]]) { // 空白符 - if (s) { continue } - begin > -1 && push(str.slice(begin, i)) - opt.detail && push({type: html.SPACE, text: str.slice(i, i+1)}) - - } else if (block[str[i]]) { // 分隔符 - if (s) { continue } - begin > -1 && push(str.slice(begin, i)) - push(str.slice(i, i+1)) - - } else if (quote[str[i]]) { // 引用符 + if (space[str[i]]) { if (s) { continue } + begin > -1 && push(str.slice(begin, i)), opt.detail && push({type: html.SPACE, text: str.slice(i, i+1)}) + } else if (block[str[i]]) { if (s) { continue } + begin > -1 && push(str.slice(begin, i)), push(str.slice(i, i+1)) + } else if (quote[str[i]]) { if (s == "") { - begin > -1 && push(str.slice(begin, i)) - s = str[i], begin = i+1 + begin > -1 && push(str.slice(begin, i)), s = str[i], begin = i+1 } else if (s == str[i]) { - push({type: lang.STRING, text: str.slice(begin, i), left: s, right: str[i]}) - s = "", begin = -1 + push({type: lang.STRING, text: str.slice(begin, i), left: s, right: str[i]}), s = "", begin = -1 } - - } else if (trans[str[i]]) { // 转义符 - begin == -1 && (begin = i++) - - } else { // 普通符 - begin == -1 && (begin = i) - } - } - - // 剩余字符 - begin >= 0 && (s? push({type: lang.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))) - return res - }), - CallFunc: shy("调用器", function(func, args, mod) { args = args||{} - var event = args["event"]||{}, can = args["can"]||args[0], msg = args["msg"]||args[1], cmds = args["cmds"]||[]; event = event._event||event - func = typeof func == lang.FUNCTION? func: typeof func == lang.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): typeof func == lang.STRING? this.Value(mod||can, func): null - if (typeof func != lang.FUNCTION) { if (typeof args["cb"] == lang.FUNCTION) { args["cb"]() } return } - - var list = [], echo = false, cb = args["cb"]; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(ice.FS), function(item, index) { item = item.trim(); if (item == "") { return } - list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || event&&!(event instanceof Event)&&event[item] || null); if (item == "cb") { echo = true } - }) - var res = func.apply(mod||can, list); if (!echo && typeof cb == lang.FUNCTION) { res && msg && msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res - }), - - List: shy("迭代器", function(list, cb, interval, cbs) { - if (typeof list == lang.STRING) { // 默认序列 - list = [list] - } else if (typeof list == lang.NUMBER) { // 等差序列 [end cb interval]|[begin end interval] - var begin = 0, end = list, step = typeof interval == lang.NUMBER? interval: 1 - if (typeof cb == lang.NUMBER) { begin = list, end = cb, cb = null } - list = []; for (var i = begin; i < end; i += step) { list.push(i) } - } - - list = list||[] - if (interval > 0) { // 时间序列 - function loop(i) { if (i >= list.length) { return typeof cbs == lang.FUNCTION && cbs(list) } - cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) - } - typeof cb == lang.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) - } else { // 选择序列 - var slice = [], res - for (var i = 0; i < list.length; i++) { - typeof cb == lang.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) { - switch (typeof list) { - case lang.OBJECT: if (list == null) { list = []; break } - if (list.length == undefined) { var ls = []; for (var k in list) { ls.push(k) } list = ls } break - default: if (list == undefined) { list = []; break } - list = [list] - } - - function next(i) { i < list.length? typeof cb == lang.FUNCTION && cb(list[i], function() { next(i+1) }, i, list): - typeof cbs == lang.FUNCTION && cbs(list) } - return next(0), list - }), - 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 == lang.FUNCTION && cb(v, i, k, obj) - })) - } - return list - }), - ItemSort: shy("迭代器", function(obj, key, cb) { var list = [] - var order = [], keys = {}, vals = {}, i = 0 - for (var k in obj) { o = obj[k][key]||i++ - order.push(o), keys[o] = k, vals[o] = obj[k] - }; order.sort() - - for (var i in order) { var k = order[i] - var res = typeof cb == lang.FUNCTION? cb(keys[k], vals[k]): k - res != undefined && list.push(res) - } - return list - }), - Item: shy("迭代器", function(obj, cb) { var list = [] - for (var k in obj) { - var res = typeof cb == lang.FUNCTION? cb(k, obj[k]): k - res != undefined && list.push(res) - } - return list - }), - ItemCB: shy("迭代器", function(meta, cb, can, item) { var list = [] - for (var k in meta) { (function(k) { - if (k.indexOf("on") == 0 && typeof meta[k] == lang.FUNCTION) { - if (typeof cb == lang.FUNCTION) { - cb(k, meta[k]) - } else { - cb[k] = function(event) { meta[k](event, can, item) } - } - list.push(k) - } - })(k) } - return list - }), - + } else if (trans[str[i]]) { begin == -1 && (begin = i++) + } else { begin == -1 && (begin = i) } + } return begin >= 0 && (s? push({type: lang.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))), res + }, SplitInput: function(item, type) { if (typeof item == lang.OBJECT) { return item } type = type||html.TEXT; switch (item) { case mdb.LIST: return {type: type = html.BUTTON, name: item, action: ice.AUTO} @@ -185,36 +57,80 @@ Volcanos("core", {help: "数据结构", switch (ls[i]) { case ":": res[mdb.TYPE] = ls[i+1]; break case "=": - if (res[mdb.TYPE] == html.SELECT) { - res.values = this.Split(ls[i+1]) - for (var j = 1; j < res.values.length; j++) { - if (res.values[0] == "" || res.values[0] == res.values[j]) { - res.value = res.values[0], res.values = res.values.slice(1) - break - } - } - } else { - res.value = ls[i+1] - } - break + if (res[mdb.TYPE] == html.SELECT) { res.values = this.Split(ls[i+1]) + for (var j = 1; j < res.values.length; j++) { if (res.values[0] == "" || res.values[0] == res.values[j]) { + res.value = res.values[0], res.values = res.values.slice(1); break + } } + } else { res.value = ls[i+1] } break case "@": res[ctx.ACTION] = ls[i+1]; break } } return res } }, - Timer300ms: function(cb) { this.Timer(300, cb) }, - Timer300: function(cb) { this.Timer(300, cb) }, - Timer3s: function(cb) { this.Timer(3000, cb) }, + CallFunc: function(func, args, mod) { args = args||{}; var can = args["can"]||args[0], msg = args["msg"]||args[1] + func = typeof func == lang.FUNCTION? func: typeof func == lang.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): typeof func == lang.STRING? this.Value(mod||can, func): null + if (typeof func != lang.FUNCTION) { if (typeof args["cb"] == lang.FUNCTION) { args["cb"]() } return } + var list = [], echo = false, cb = args["cb"]; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(ice.FS), function(item, index) { item = item.trim(); if (item == "") { return } + list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || null); if (item == "cb") { echo = true } + }); var res = func.apply(mod||can, list); if (!echo && typeof cb == lang.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res + }, + List: function(list, cb, interval, cbs) { + if (typeof list == lang.STRING) { list = [list] } else if (typeof list == lang.NUMBER) { // [end cb interval]|[begin end interval] + var begin = 0, end = list, step = typeof interval == lang.NUMBER? interval: 1 + if (typeof cb == lang.NUMBER) { begin = list, end = cb, cb = null } + list = []; for (var i = begin; i < end; i += step) { list.push(i) } + } list = list||[] + if (interval > 0) { + function loop(i) { if (i >= list.length) { return typeof cbs == lang.FUNCTION && cbs(list) } + cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) + } typeof cb == lang.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) + } else { var slice = [], res + for (var i = 0; i < list.length; i++) { + typeof cb == lang.FUNCTION? (res = cb(list[i], i, list)) != undefined && slice.push(res): slice.push(list[i]) + } list = slice + } return list + }, + Next: function(list, cb, cbs) { + switch (typeof list) { + case lang.OBJECT: if (list == null) { list = []; break } if (list.length == undefined) { var ls = []; for (var k in list) { ls.push(k) } list = ls } break + default: if (list == undefined) { list = []; break } list = [list] + } + function next(i) { i < list.length? typeof cb == lang.FUNCTION && cb(list[i], function() { next(i+1) }, i, list): typeof cbs == lang.FUNCTION && cbs(list) } + return next(0), list + }, + Item: function(obj, cb) { var list = [] + for (var k in obj) { + var res = typeof cb == lang.FUNCTION? cb(k, obj[k]): k + res != undefined && list.push(res) + } return list + }, + Items: function(obj, cb) { var list = [] + for (var k in obj) { + list = list.concat(this.List(obj[k], function(v, i) { + return typeof cb == lang.FUNCTION && cb(v, i, k, obj) + })) + } return list + }, + ItemSort: function(obj, key, cb) { var list = [] + var order = [], keys = {}, vals = {}, i = 0 + for (var k in obj) { o = obj[k][key]||i++ + order.push(o), keys[o] = k, vals[o] = obj[k] + } order.sort() + for (var i in order) { var k = order[i] + var res = typeof cb == lang.FUNCTION? cb(keys[k], vals[k]): k + res != undefined && list.push(res) + } return list + }, + ItemCB: function(meta, cb, can, item) { var list = [] + for (var k in meta) { if (k.indexOf("on") == 0 && typeof meta[k] == lang.FUNCTION) { (function(k) { list.push(k) + if (typeof cb == lang.FUNCTION) { cb(k, meta[k]) } else { cb[k] = function(event) { meta[k](event, can, item) } } + })(k) } } return 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 == lang.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1]) - } - - interval = typeof interval == lang.OBJECT? interval: [interval] - if (interval.interval == 0) { cb(); return timer } - - typeof cb == lang.FUNCTION && setTimeout(function() { loop(0) }, interval.interval||interval[0]) - return timer + } interval = typeof interval == lang.OBJECT? interval: [interval]; if (interval.interval == 0) { return cb(), timer } + return typeof cb == lang.FUNCTION && setTimeout(function() { loop(0) }, interval.interval||interval[0]), timer }), }) diff --git a/lib/misc.js b/lib/misc.js index c1fd5296..f92d9588 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -1,9 +1,9 @@ -Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg = {} +Volcanos("misc", {Message: function(event, can) { var msg = {} var proto = {_event: event, _can: can, RunAction: function(event, sub, cmds, meta) { var msg = can.request(event); meta = meta || sub&&sub.onaction || {} if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } - if (cmds && cmds[0] == ctx.ACTION && can.base.isFunc(meta[cmds[1]])) { event = event._event||event - return msg.Option(ice.MSG_HANDLE, ice.TRUE), can.core.CallFunc(meta[cmds[1]], {event: event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true + if (cmds && cmds[0] == ctx.ACTION && can.base.isFunc(meta[cmds[1]])) { msg.Option(ice.MSG_HANDLE, ice.TRUE) + return can.core.CallFunc(meta[cmds[1]], {event: event._event||event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true } return false }, @@ -12,6 +12,9 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg OptionStatus: function() { return msg.Option(ice.MSG_STATUS) }, OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) }, SearchOrOption: function(key) { return can.misc.Search(can, key)||msg.Option(key) }, + StatusTimeCount: function(obj) { msg.append && msg.Status(can.base.Copy({"time": can.base.Time(), "count": msg.Length()+"x"+msg.append.length}, obj)) }, + Status: function(obj) { msg.Option(ice.MSG_STATUS, JSON.stringify(can.core.Item(obj, function(key, value) { return {name: key, value: value} }))) }, + Option: function(key, val) { if (key == undefined) { return msg && msg.option || [] } if (can.base.isObject(key)) { can.core.Item(key, msg.Option) } @@ -25,25 +28,14 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val }, Result: function() { - if (msg.result && msg.result[0] == ice.ErrWarn) { - var res = msg.result[0] + if (msg.result && msg.result[0] == ice.ErrWarn) { var res = msg.result[0] for (var i = 1; i < msg.result.length; i+=2) { - res += msg.result[i]+(msg.result[i+1]||"")+" " - } - return res - } - return msg.result && msg.result.join("") || "" - }, - - 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 + res += msg.result[i]+(msg.result[i+1]||"")+ice.SP + } return res + } return msg.result && msg.result.join("") || "" }, TableDetail: function() { var item = {hash: can.Option(mdb.HASH)} - msg.Table(function(value) { can.core.Value(item, value.key, value.value) }) - return item + return msg.Table(function(value) { can.core.Value(item, value.key, value.value) }), item }, Table: function(cb) { return can.core.List(msg.Length(), function(value, index, array) { var one = {}, res @@ -51,6 +43,11 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg return can.base.isFunc(cb) && (res = cb(one, index, array)) && res != undefined && res || one }) }, + 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 + }, Clear: function(key) { switch (key||ice.MSG_APPEND) { case ice.MSG_APPEND: case ice.MSG_OPTION: @@ -58,37 +55,26 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg default: msg[key] = [] } }, Copy: function(res) { if (!res) { return msg } - res.result && (msg.result = (msg.result||[]).concat(res.result)) res.append && (msg.append = res.append) && res.append.forEach(function(item) { - var i = msg.option && msg.option.indexOf(item); if (i > -1) { - msg.option[i] = "", delete(msg[item]) - } + var i = msg.option && msg.option.indexOf(item); if (i > -1) { msg.option[i] = "", delete(msg[item]) } res[item] && (msg[item] = (msg[item]||[]).concat(res[item])) - }) - res.option && (msg.option = res.option) && res.option.forEach(function(item) { - res[item] && (msg[item] = res[item]) - }) - res._option && (msg._option = res._option) && res._option.forEach(function(item) { - res[item] && (msg[item] = res[item]) - }) + }), res.result && (msg.result = (msg.result||[]).concat(res.result)) + res.option && (msg.option = res.option) && res.option.forEach(function(item) { res[item] && (msg[item] = res[item]) }) + res._option && (msg._option = res._option) && res._option.forEach(function(item) { res[item] && (msg[item] = res[item]) }) return msg }, Push: function(key, value, detail) { if (can.base.isObject(key)) { can.core.List(value||can.base.Obj(msg.Option(ice.MSG_FIELDS))||can.core.Item(key), function(item) { detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): msg.Push(item, key[item]||"") - }) - return msg + }); return msg } + msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key]||[] var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", msg[key] = [] } - - msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key] || [] msg[key].push(can.base.isString(value)||can.base.isFunction(value)? value: JSON.stringify(value)) return msg }, - Status: function(obj) { msg.Option(ice.MSG_STATUS, JSON.stringify(can.core.Item(obj, function(key, value) { return {name: key, value: value} }))) }, - StatusTimeCount: function(obj) { msg.append && msg.Status(can.base.Copy({"time": can.base.Time(), "count": msg.Length()+"x"+msg.append.length}, obj)) }, - Echo: function(res) { msg.result = msg.result || [] + Echo: function(res) { msg.result = msg.result||[] for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) } return msg._hand = true, msg }, @@ -96,166 +82,9 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg can.onmotion.clear(can) can.onappend.table(can, msg) can.onappend.board(can, msg) + can.onmotion.story.auto(can) }, - } - return can.misc.proto(msg, proto) - }, - GET: function(can, url, cb) { var xhr = new XMLHttpRequest() - xhr.open("GET", url), xhr.onreadystatechange = function() { - if (xhr.status == 200) { - return can.base.isFunc(cb) && cb(xhr.responseText) - } - } - try { xhr.send() } catch(e) { can.misc.Log(e) } - }, - POST: function(can, msg, url, form, cb) { // _method _accept _upload _progress - var xhr = new XMLHttpRequest(); msg._xhr = xhr - var begin = new Date() - xhr.open(msg._method||"POST", url), xhr.onreadystatechange = function() { - if (xhr.readyState != 4) { return } - - try { // 解析响应 - var res = JSON.parse(xhr.responseText) - } catch (e) { - var res = {result: [xhr.responseText]} - } - msg.Option("_cost", new Date() - begin) - if (xhr.status == 200) { - return can.base.isFunc(cb) && cb(msg.Copy(res)) - } - can.user.toast(can, res, xhr.status) - } - - if (msg._upload) { // 上传文件 - var data = new FormData(); can.core.Items(form, function(value, index, key) { - data.append(key, value) - }), data.append(html.UPLOAD, msg._upload), data.append(ice.MSG_UPLOAD, mdb.UPLOAD) - - xhr.upload.onprogress = function(event) { - can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) - } - } else { // 请求数据 - var data = can.core.Items(form, function(value, index, key) { return key+"="+encodeURIComponent(value) }).join("&") - xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") - } - - // 发送请求 - xhr.setRequestHeader("Accept", msg._accept||"application/json") - try { xhr.send(data) } catch(e) { can.misc.Log(e) } - }, - Run: function(event, can, dataset, cmds, cb) { - var msg = can.request(event||{}), skip = {_handle: true} - var form = {cmds: cmds||msg.cmd}; msg.option && msg.option.forEach(function(item) { - if (typeof msg.Option(item) == lang.OBJECT) { return } - if (typeof msg.Option(item) == lang.FUNCTION) { return } - if (item == "_daemon") { return } - !skip[item] && msg[item] && (form[item] = msg[item]) - }) - - can.misc.POST(can, msg, can.base.MergeURL(dataset.names.toLowerCase(), - "_name", (msg._can.sup||msg._can)._name, "_index", (msg._can.sup||msg._can)._index, - ice.MSG_DAEMON, msg.__daemon||dataset.daemon||"" - ), form, cb) - }, - WSS: function(can, args, cb, onopen, onclose, onerror) { if (can.user.isIE) { return } - var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/" - if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" } - - var socket = new WebSocket(can.base.MergeURL(url, args)) - socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args) - can.base.isFunc(onclose)? onclose(socket): can.core.Timer(can.base.random(3000, 1000), function() { - args.name = args.name||can._wss_name - can.misc.WSS(can, args, cb, onopen, onerror, onclose) - }) - }, socket.onerror = function() { can.misc.Log(html.WSS, cli.ERROR, args) - can.base.isFunc(onerror)? onerror(socket): socket.close() - - }, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args) - can.base.isFunc(onopen) && onopen(socket) - } - - socket.onmessage = function(event) { // 解析命令 - try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} } - - var msg = can.request(event); msg.Reply = function() { // 回复命令 - var res = can.request({}); res._source = (msg[ice.MSG_TARGET]||[]).reverse().slice(1)||[] - res.Option({_handle: ice.TRUE, _target: (msg[ice.MSG_SOURCE]||[]).reverse().join(ice.PT)}) - res.append = msg.append, can.core.List(msg.append, function(key) { res[key] = msg[key] }) - res.result = (msg.result||[]).concat(can.core.List(arguments)) - res.Option("log.disable", msg.Option("log.disable")) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result||[], msg) - socket.send(JSON.stringify(res)) - }, msg.detail = data.detail, msg.Copy(data) - - try { // 执行命令 - msg.Option("log.disable") != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg) - can.base.isFunc(cb) && cb(event, msg, msg.detail[0], msg.detail.slice(1)) - } catch (e) { can.misc.Log(e), msg.Reply() } - } - }, - - CookieSessid: shy("会话变量", function(can, value, path) { - return can.misc.Cookie(can, ice.MSG_SESSID+"_"+can.base.replaceAll(location.host, ice.PT, "_", ice.DF, "_"), value, path) - }), - Cookie: shy("会话变量", function(can, key, value, path) { - function set(k, v) { document.cookie = k+"="+v+";path="+(path||ice.PS) } - if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined } - - if (key == undefined) { var cs = {} - document.cookie.split("; ").forEach(function(item) { var ls = item.split("="); cs[ls[0]] = ls[1] }) - return cs - } - - value != undefined && set(key, value) - var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie) - return val && val.length > 0? val[1]: "" - }), - SearchOrConf: function(can, key, def) { return can.base.getValid(can.misc.Search(can, key), can.Conf(key), def) }, - SearchHash: function(can) { - if (can.isCmdMode() && can._index == can.misc.Search(can, "cmd")) { - return location.hash.slice(1) - } - }, - Search: shy("请求参数", function(can, key, value) { var args = {} - if (value == undefined && can.base.isString(key)) { - var ls = location.pathname.split(ice.PS); if (ls[1] == chat.SHARE) { args[chat.SHARE] = ls[2] } - for (var i = 2; i < ls.length; i += 2) { if ({"pod": true, "cmd": true}[ls[i]]) { args[ls[i]] = ls[i+1] } } - } - location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("=") - x[1] != "" && (args[x[0]] = decodeURIComponent(x[1])) - }) - - if (can.base.isObject(key)) { - can.core.Item(key, function(key, value) { - if (value != undefined) { args[key] = value } args[key] == "" && delete(args[key]) - }) - } else { - if (key == undefined) { return args } - if (value == undefined) { return args[key] } - args[key] = value, args[key] == "" && delete(args[key]) - } - - var search = can.core.Item(args, function(key, value) { return key+"="+encodeURIComponent(value) }).join("&") - return search? location.search = search: location.href = location.pathname - }), - MergeCache: shy("地址链接", function(can, hash) { - return can.misc.MergeURL(can, {_path: "/share/cache/"+hash}, true) - }), - MergePodCmd: shy("地址链接", function(can, objs) { - objs.pod = can.core.Keys(can.misc.Search(can, "pod"), objs.pod) - objs.topic = can.misc.Search(can, "topic") - return can.misc.MergeURL(can, objs, true) - }), - MergeURL: shy("地址链接", function(can, objs, clear) { - var path = location.pathname; objs._path && (path = objs._path), delete(objs._path) - objs.pod && (path = "/chat/pod/"+objs.pod), delete(objs.pod) - objs.cmd && (path = (path.indexOf("/chat/pod/") == 0? path: "/chat")+"/cmd/"+objs.cmd), delete(objs.cmd) - objs.website && (path = (path.indexOf("/chat/pod/") == 0? path: "/chat")+"/website/"+objs.website), delete(objs.website) - return can.base.MergeURL(location.origin+path+(clear?"":location.search), objs) - }), - - runAction: function(can, msg, cmds, cb, list) { - if (cmds[0] == ctx.ACTION && list[cmds[1]]) { return list[cmds[1]](cmds.slice(2)), true } - if (list[cmds[0]]) { return list[cmds[0]](cmds.slice(1)), true } + }; return kit.proto(msg, proto) }, concat: function(can, to, from) { to = to||[], from = from||[] if (from[0] == ctx.ACTION && from[1] == ice.RUN && can.onengine.plugin(can, from[2])) { return from } @@ -263,52 +92,187 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg if (from[0] == "_search") { return from } return to.concat(from) }, - proto: function(sub, sup) { return sub.__proto__ = sup, sub }, + runAction: function(can, msg, cmds, cb, meta) { + if (cmds[0] == ctx.ACTION && meta[cmds[1]]) { return meta[cmds[1]](cmds.slice(2)), true } + if (meta[cmds[0]]) { return meta[cmds[0]](cmds.slice(1)), true } + }, + Run: function(event, can, dataset, cmds, cb) { var msg = can.request(event) + var form = {cmds: cmds||msg.cmd}; msg.option && msg.option.forEach(function(item) { + if ([ice.MSG_HANDLE, ice.MSG_DAEMON].indexOf(item) > -1) { return } + if (can.base.isObject(msg.Option(item))) { return } + if (can.base.isFunc(msg.Option(item))) { return } + msg[item] && (form[item] = msg[item]) + }) + can.misc.POST(can, msg, can.base.MergeURL(dataset.names.toLowerCase(), + "_name", (msg._can.sup||msg._can)._name, "_index", (msg._can.sup||msg._can)._index, ice.MSG_DAEMON, msg.__daemon||dataset.daemon||"" + ), form, cb) + }, + POST: function(can, msg, url, form, cb) { var xhr = new XMLHttpRequest(), begin = new Date(); msg._xhr = xhr + xhr.open(msg._method||web.POST, url), xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return } + try { var res = JSON.parse(xhr.responseText) } catch (e) { var res = {result: [xhr.responseText]} } msg.Option("_cost", new Date() - begin) + if (xhr.status == 200) { if (can.misc.Debug(msg._can, msg, web.POST, res)) { debugger } + return can.base.isFunc(cb) && cb(msg.Copy(res)) + } can.misc.Warn(xhr.status, res, url, form) + }, xhr.setRequestHeader(web.Accept, msg._accept||web.ContentJSON) + + if (msg._upload) { + var data = new FormData(); can.core.Items(form, function(value, index, key) { data.append(key, value) }) + data.append(ice.MSG_UPLOAD, mdb.UPLOAD), data.append(html.UPLOAD, msg._upload) + xhr.upload.onprogress = function(event) { can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) } + } else { + var data = can.core.Items(form, function(value, index, key) { return key+ice.EQ+encodeURIComponent(value) }).join("&") + xhr.setRequestHeader(web.ContentType, web.ContentFORM) + } + if (can.misc.Debug(msg._can, msg, web.POST, data)) { debugger } + try { xhr.send(data) } catch(e) { can.misc.Warn(e) } + }, + GET: function(can, url, cb) { var xhr = new XMLHttpRequest() + xhr.open(msg._method||web.GET, url), xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return } + if (xhr.status == 200) { return can.base.isFunc(cb) && cb(xhr.responseText) } can.misc.Warn(xhr.status, res, url, form) + }; try { xhr.send() } catch(e) { can.misc.Warn(e) } + }, + WSS: function(can, args, cb, onopen, onclose, onerror) { if (can.user.isIE) { return } + var url = location.protocol.replace(ice.HTTP, "ws")+"//"+location.host+"/space/" + if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" } + + var socket = new WebSocket(can.base.MergeURL(url, args)) + socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args) + can.base.isFunc(onclose)? onclose(socket): can.core.Timer(can.base.random(3000, 1000), function() { + args.name = args.name||can._wss_name, can.misc.WSS(can, args, cb, onopen, onerror, onclose) + }) + }, socket.onerror = function() { can.misc.Log(html.WSS, cli.ERROR, args) + can.base.isFunc(onerror)? onerror(socket): socket.close() + }, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args) + can.base.isFunc(onopen) && onopen(socket) + }, socket.onmessage = function(event) { + try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} } + + var msg = can.request(event); msg.Reply = function() { + var res = can.request({}); res._source = (msg[ice.MSG_TARGET]||[]).reverse().slice(1)||[] + res.Option({_handle: ice.TRUE, _target: (msg[ice.MSG_SOURCE]||[]).reverse().join(ice.PT)}) + res.append = msg.append, can.core.List(msg.append, function(key) { res[key] = msg[key] }), res.result = (msg.result||[]).concat(can.core.List(arguments)) + res.Option("log.disable", msg.Option("log.disable")) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result||[], msg) + socket.send(JSON.stringify(res)) + }, msg.detail = data.detail, msg.Copy(data) + + try { + msg.Option("log.disable") != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg) + can.base.isFunc(cb) && cb(event, msg, msg.detail[0], msg.detail.slice(1)) + } catch (e) { can.misc.Warn(e), msg.Reply() } + } + }, + + MergeCache: function(can, hash) { + return can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true) + }, + MergePodCmd: function(can, objs) { + objs.pod = can.core.Keys(can.misc.Search(can, ice.POD), objs.pod) + objs.topic = can.misc.Search(can, chat.TOPIC) + return can.misc.MergeURL(can, objs, true) + }, + MergeURL: function(can, objs, clear) { + var path = location.pathname; objs._path && (path = objs._path), delete(objs._path) + objs.pod && (path = can.base.Path("/chat/pod/", objs.pod)), delete(objs.pod) + objs.cmd && (path = can.base.Path(path.indexOf("/chat/") == 0? path: "/chat", ice.CMD, objs.cmd)), delete(objs.cmd) + objs.website && (path = can.base.Path(path.indexOf("/chat/") == 0? path: "/chat", web.WEBSITE, objs.website)), delete(objs.website) + return can.base.MergeURL(location.origin+path+(clear?"":location.search), objs) + }, + SearchOrConf: function(can, key, def) { return can.base.getValid(can.misc.Search(can, key), can.Conf(key), def) }, + SearchHash: function(can) { if (can.isCmdMode() && can._index == can.misc.Search(can, ice.CMD)) { return location.hash.slice(1) } }, + Search: function(can, key, value) { var args = {} + if (value == undefined && can.base.isString(key)) { var ls = location.pathname.split(ice.PS); if (ls[1] == chat.SHARE) { args[chat.SHARE] = ls[2] } + for (var i = 2; i < ls.length; i += 2) { if (kit.Dict(ice.POD, true, ice.CMD, true, web.WEBSITE, true)[ls[i]]) { args[ls[i]] = ls[i+1] } } + } location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("="); x[1] != "" && (args[x[0]] = decodeURIComponent(x[1])) }) + + if (can.base.isUndefined(key)) { return args } else if (can.base.isObject(key)) { + can.core.Item(key, function(key, value) { can.base.isUndefined(value) || (args[key] = value), args[key] == "" && delete(args[key]) }) + } else if (can.base.isUndefined(value)) { return args[key] } else { + args[key] = value, args[key] == "" && delete(args[key]) + } + var search = can.core.Item(args, function(key, value) { return key+"="+encodeURIComponent(value) }).join("&") + return search? location.search = search: location.href = location.pathname + }, + CookieSessid: function(can, value, path) { + return can.misc.Cookie(can, ice.MSG_SESSID+"_"+can.base.replaceAll(location.host, ice.PT, "_", ice.DF, "_"), value, path) + }, + Cookie: function(can, key, value, path) { + function set(k, v) { document.cookie = k+"="+v+";path="+(path||ice.PS) } + if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined } + if (can.base.isUndefined(key)) { var cs = {} + return document.cookie.split("; ").forEach(function(item) { var ls = item.split("="); cs[ls[0]] = ls[1] }), cs + } + can.base.isUndefined(value) || set(key, value) + var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie) + return val && val.length > 1? val[1]: "" + }, + localStorage: function(can, key, value) { + if (value != undefined) { localStorage.setItem(key, value) } + return localStorage.getItem(key) + }, Log: function() { var args = [this._time(), this.FileLine(2, 3)] - for (var i in arguments) { args.push(arguments[i]) } + for (var i in arguments) { arguments[i] != undefined && args.push(arguments[i]) } console.log.apply(console, args) }, Info: function() { - var args = [this._time(), this.FileLine(2, 3)] - for (var i in arguments) { args.push(arguments[i]) } - console.log.apply(console, args) + var args = [this._time(), this.FileLine(2, 3), log.INFO] + for (var i in arguments) { arguments[i] != undefined && args.push(arguments[i]) } + console.info.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(ice.NL, this._fileLine().split(ice.NL).slice(2).join(ice.NL)) - console.log.apply(console, args) + var args = [this._time(), this.fileLine(2, 3).link, log.WARN] + for (var i in arguments) { arguments[i] != undefined && args.push(arguments[i]) } + console.warn.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) - var args = [this._time(), this.FileLine(2, 3), "debug"] - for (var i in arguments) { args.push(JSON.stringify(arguments[i])) } - navigator.userAgent.indexOf("Mobile") > -1 && alert(JSON.stringify(args.join(ice.SP))) + Error: function() { + var args = [this._time(), this.fileLine(2, 3).link, log.ERROR] + for (var i in arguments) { arguments[i] != undefined && args.push(arguments[i]) } + args.push(ice.NL, this._stack().slice(1).join(ice.NL)) + console.error.apply(console, args) }, - FileLine: function(depth, length) { - return this.fileLine(depth+1).split(ice.PS).slice(3).slice(-length).join(ice.PS).split(")")[0] + Debug: function(msg) { var filter = "", output = false + var args = [this._time(), this.fileLine(2, 3).link, log.DEBUG] + for (var i in arguments) { var item = arguments[i]; if (item == undefined) { continue } + if (item.misc && item.misc.Search) { + filter += item.misc.Search(item, log.DEBUG)||"" + item._name && args.push(item._name) + } else if (item.Option) { + filter += item.Option(log.DEBUG)||"" + } else if (arguments[i].indexOf && arguments[i].indexOf(filter||"trace") > -1) { + output = true + } args.push(arguments[i]) + } if (output) { return console.debug.apply(console, args), true } }, - fileLine: function(depth) { - return (this._fileLine().split(ice.NL)[1+depth]||"").trim() + FileLine: function(depth, length) { length = length||9 + var file = this.fileLine(depth+1, length); return file.file+ice.DF+file.line }, - _fileLine: function() { var obj = {} - Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee) - return obj.stack || "" + fileLine: function(depth, length) { var list = this._stack() + function split(i) { if (!list[i]) { return {} } + var ls = list[i].trim().split(ice.SP).slice(-2), link = ls.slice(-1)[0]; link.indexOf("(") == 0 && (link = link.slice(1, -1)), link.indexOf("@") > -1 && (ls = link.split("@"), link = ls[1]) + var path = link, file = "", line = "", cols = ""; path = link.indexOf(ice.HTTP) == 0 && (path = link.split(ice.PS).slice(3).join(ice.PS)) + for (var i = path.length; i > 0; i--) { if (path[i] != ice.DF) { continue } + if (cols == "") { + cols = path.slice(i+1), path = path.slice(0, i) + } else if (line == "") { + line = path.slice(i+1), path = path.slice(0, i) + file = path.split(ice.PS).slice(-length).join(ice.PS), path = path.slice(0, -file.length) + break + } + } return {name: ls[0], link: link, path: path, file: file, line: line, cols: cols} + } + if (depth < 0) { var current = split(-depth) + for (var i = -depth+1; i < list.length; i++) { var pos = split(i) + if (pos.file != current.file) { return pos } + } + } return split(depth)||{} }, + _stack: function() { return ((new Error()).stack||"").split(ice.NL).slice(2) }, _time: function() { var now = new Date() - var hour = now.getHours() - if (hour < 10) { hour = "0"+hour } - var minute = now.getMinutes() - if (minute < 10) { minute = "0"+minute } - var second = now.getSeconds() - if (second < 10) { second = "0"+second } - var mill = now.getMilliseconds() - if (mill < 10) { mill = "00"+mill } else if (mill < 100) { mill = "0"+mill } - return hour+":"+minute+":"+second+"."+mill + var hour = now.getHours(); hour < 10 && (hour = "0"+hour) + var minute = now.getMinutes(); minute < 10 && (minute = "0"+minute) + var second = now.getSeconds(); second < 10 && (second = "0"+second) + var mill = now.getMilliseconds(); mill < 10 && (mill = "00"+mill) || mill < 100 && (mill = "0"+mill) + return [hour, minute, second].join(ice.DF)+ice.PT+mill }, }) diff --git a/lib/page.js b/lib/page.js index 8b3af3e6..65502ddc 100644 --- a/lib/page.js +++ b/lib/page.js @@ -1,331 +1,198 @@ -Volcanos("page", {help: "用户界面", ClassList: { - has: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] - return list.indexOf(key) > -1 - }, - add: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] - var value = can.base.AddUniq(list, key).join(ice.SP).trim() +Volcanos("page", {ClassList: { + has: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): []; return list.indexOf(key) > -1 }, + add: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [], value = can.base.AddUniq(list, key).join(ice.SP).trim() return value != obj.className && (obj.className = value), value }, del: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] return obj.className = can.core.List(list, function(value) { return value == key? undefined: value }).join(ice.SP).trim() }, - set: function(can, obj, key, condition) { - return (condition? this.add(can, obj, key): this.del(can, obj, key)).indexOf(key) > -1 - }, - neg: function(can, obj, key) { - return (this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)).indexOf(key) > -1 - }, + set: function(can, obj, key, condition) { return (condition? this.add(can, obj, key): this.del(can, obj, key)).indexOf(key) > -1 }, + neg: function(can, obj, key) { return (this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)).indexOf(key) > -1 }, }, - SelectChild: function(can, target, key, cb) { var i = 0 - return can.page.Select(can, target, key, function(node) { - if (node.parentNode == target) { return cb(node, i++) } - }) + SelectAll: function(can, target, key, cb, interval, cbs) { + can.page.Select(can, target, html.IFRAME, function(item) { can.page.SelectAll(can, item.contentWindow.document.body, key, cb, interval, cbs) }) + return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs) }, SelectArgs: function(can, option, key, cb) { - if (can.base.isUndefined(key)) { var value = {} - can.page.SelectArgs(can, option, "", function(item) { - item.name && item.value && (value[item.name] = item.value) - }); return [value] - } - if (can.base.isObject(key)) { - return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, option, key, value) }), [key] - } - if (!can.base.isFunc(cb)) { var value = cb; cb = function(item) { if (item.type == html.BUTTON) { return } - return item.name && (can.base.isUndefined(value)? item.value: (item.value = value))||"" - } } + if (can.base.isUndefined(key)) { var value = {}; can.page.SelectArgs(can, option, "", function(item) { item.name && item.value && (value[item.name] = item.value) }); return [value] } + if (can.base.isObject(key)) { return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, option, key, value) }), [key] } + if (!can.base.isFunc(cb)) { var value = cb; cb = function(item) { if (item.type == html.BUTTON) { return } return item.name && (can.base.isUndefined(value)? item.value: (item.value = value))||"" } } if (key.indexOf(ice.PT) > -1) { return [""]} return can.page.Select(can, option, key? "textarea[name="+key+"],"+"input[name="+key+"],"+"select[name="+key+"]": ".args", cb) }, - SelectAll: shy("选择节点", function(can, target, key, cb, interval, cbs) { - can.page.Select(can, target, html.IFRAME, function(item) { - can.page.SelectAll(can, item.contentWindow.document.body, key, cb, interval, cbs) - }) - return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs) - }), - Select: shy("选择节点", function(can, target, key, cb, interval, cbs) { if (key == ice.PT) { cb(target); return [] } + SelectChild: function(can, target, key, cb) { var i = 0; return can.page.Select(can, target, key, function(node) { if (node.parentNode == target) { return cb(node, i++) } }) }, + Select: function(can, target, key, cb, interval, cbs) { if (key == ice.PT) { cb(target); return [] } return can.core.List(target && target.querySelectorAll(can.page.Keys(key)), cb, interval, cbs) - }), - Modify: shy("修改节点", function(can, target, value) { target = target||{} - target = can.base.isObject(target)? target: document.querySelector(target); if (!target) { return } + }, + Modify: function(can, target, value) { target = can.base.isString(target)? document.querySelector(target): target; if (!target) { return } can.base.isString(value)? (target.innerHTML = value): can.core.Item(value, function(key, val) { key == "className" && can.base.isArray(val) && (val = val.join(ice.SP)) !can.base.isObject(val)? (target[key] = val): can.core.Item(val, function(k, v) { - var size = { - "height": true, "max-height": true, "min-height": true, - "width": true, "max-width": true, "min-width": true, - } - if (size[k] && parseInt(v) < 0) { return target[key] && (target[key][k] = "") } - - var size = { - "margin-top": true, "margin-left": true, "font-size": true, - "left": true, "right": true, "top": true, "bottom": true, - "height": true, "max-height": true, "min-height": true, - "width": true, "max-width": true, "min-width": true, - "padding": true, - } - - if (size[k] && v && (can.base.isNumber(v) || v.indexOf && v.indexOf("px") == -1)) { v += "px" } + if (["height", "max-height", "min-height", "width", "max-width", "min-width"].indexOf(k) > -1 && parseInt(v) < 0) { return target[key] && (target[key][k] = "") } + if (["height", "max-height", "min-height", "width", "max-width", "min-width", + "left", "right", "top", "bottom", "margin-left", "margin-top", "padding", "font-size", + ].indexOf(k) > -1 && v && (v&&v.indexOf&&v.indexOf("px") == -1 || can.base.isNumber(v))) { v += "px" } target[key] && (target[key][k] = v) }) - }) - return target - }), - Remove: shy("删除节点", function(can, target) { - return target && target.parentNode && target.parentNode.removeChild(target), target - }), - Create: shy("创建节点", function(can, key, value) { - return can.page.Modify(can, document.createElement(key), value) - }), - Append: shy("添加节点", function(can, target, key, value) { value = value||{} + }); return target + }, + Create: function(can, key, value) { return can.page.Modify(can, document.createElement(key), value) }, + Remove: function(can, target) { return target && target.parentNode && target.parentNode.removeChild(target), target }, + Append: function(can, target, key, value) { value = value||{} if (can.base.isString(key)) { var res = can.page.Create(can, key, value); return target.appendChild(res), res } - can.core.List(key, function(item, index) { if (!item) { return } - if (can.base.isString(item)) { item = {view: [item]} } if (item.nodeName) { target.appendChild(item); return } + if (can.base.isString(item)) { item = {view: [item]} } - // 基本结构: type name data list - var type = item.type||html.DIV, data = item.data||{} - var name = item.name||data.name||"" + var type = item.type||html.DIV, data = item.data||{}, name = item.name||data.name||"" + can.core.Item(item, function(key, value) { switch (key) { + case mdb.TYPE: break + case mdb.NAME: break + case mdb.DATA: break + case mdb.LIST: break + case html.CLICK: data.onclick = item.click; break + case html.INNER: data.innerHTML = item.inner; break + default: can.base.isUndefined(item[key]) || (data[key] = item[key]) + } }) - // 数据调整 - can.core.Item(item, function(key, value) { - switch (key) { - case mdb.TYPE: break - case mdb.NAME: break - case mdb.DATA: break - case mdb.LIST: break - case html.INNER: data.innerHTML = item.inner; break - case html.CLICK: data.onclick = item.click; break - default: - if (item[key] == undefined) { break } - data[key] = item[key] - } - }) - - // 基本类型: view text button select input username password - // 基本类型: img row th td - if (item.view) { var list = can.core.List(item.view) - if (can.base.isArray(list[0])) { list[0] = list[0].join(ice.SP) } - list[0] && can.page.ClassList.add(can, data, list[0]) - type = list[1]||html.DIV - data.innerHTML = list[2]||data.innerHTML||"" - name = name||list[3]||"" - - } else if (item.text) { var list = can.core.List(item.text) - data.innerHTML = list[0]||data.innerHTML||"" - type = list[1]||html.SPAN - list[2] && can.page.ClassList.add(can, data, list[2]) - - } else if (item.button) { var list = can.core.List(item.button) - type = html.BUTTON, name = name||list[0] + if (item.view) { var list = can.core.List(item.view); if (can.base.isArray(list[0])) { list[0] = list[0].join(ice.SP) } + list[0] && can.page.ClassList.add(can, data, list[0]), type = list[1]||html.DIV, data.innerHTML = list[2]||data.innerHTML||"", name = name||list[3]||"" + } else if (item.text) { var list = can.core.List(item.text); if (can.base.isArray(list[2])) { list[2] = list[2].join(ice.SP) } + data.innerHTML = list[0]||data.innerHTML||"", type = list[1]||html.SPAN, list[2] && can.page.ClassList.add(can, data, list[2]) + } else if (item.button) { var list = can.core.List(item.button); type = html.BUTTON, name = name||list[0] data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) { - can.base.isFunction(list[1]) && list[1](event, name) - can.onkeymap.prevent(event) - return true + can.base.isFunction(list[1]) && list[1](event, name), can.onkeymap.prevent(event); return true } + } else if (item.select) { var list = item.select; type = html.SELECT + data.name = name = name||list[0][0], data.title = can.user.trans(can, data.title||name), data.className = data.className||list[0][0]||"" + item.list = list[0].slice(1).map(function(value) { return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} }) + data.onchange = function(event) { can.base.isFunction(list[1]) && list[1](event, event.target.value, name) } + } else if (item.input) { var list = can.core.List(item.input); type = html.INPUT, name = name||list[0]||"" + data.type = data.type||"text", data.name = data.name||name, data.autocomplete = "off", data.className = data.className||data.name + data.onfocus = data.onfocus||function(event) { event.target.setSelectionRange(0, -1) } + data.onkeydown = function(event) { can.base.isFunction(list[1]) && list[1](event) } + data.onkeyup = function(event) { can.base.isFunction(list[2]) && list[2](event) } + } else if (item.username) { var list = can.core.List(item.username); type = html.INPUT, name = name||list[0]||html.USERNAME + data.name = data.name||name, data.autocomplete = data.autocomplete||html.USERNAME, data.className = list[1]||data.className||data.name + } else if (item.password) { var list = can.core.List(item.password); type = html.INPUT, name = name||list[0]||html.PASSWORD + data.type = html.PASSWORD, data.name = data.name||name, data.autocomplete = data.autocomplete||"current-password", data.className = list[1]||data.className||data.name + } else if (item.img) { var list = can.core.List(item.img); type = html.IMG, data.src = list[0] + } else if (item.row) { type = html.TR, item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} }) + } else if (item.th) { type = html.TR, item.list = item.th.map(function(text) { return {text: [text, html.TH]} }) + } else if (item.td) { type = html.TR, item.list = item.td.map(function(text) { return {text: [text, html.TD]} }) } - } else if (item.select) { var list = item.select - type = html.SELECT, data.name = name = name||list[0][0] - data.title = can.user.trans(can, data.title||name) - data.className = data.className||list[0][0]||"" - - item.list = list[0].slice(1).map(function(value) { - return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} - }) - data.onchange = function(event) { - can.base.isFunction(list[1]) && list[1](event, event.target.value, name) - } - - } else if (item.input) { var list = can.core.List(item.input) - type = html.INPUT, name = name||list[0]||"", data.name = data.name||name - data.type = data.type||"text" - data.className = data.className||data.name - data.autocomplete = "off" - - data.onfocus = data.onfocus||function(event) { - event.target.setSelectionRange(0, -1) - } - data.onkeydown = function(event) { - can.base.isFunction(list[1]) && list[1](event) - } - data.onkeyup = function(event) { - can.base.isFunction(list[2]) && list[2](event) - } - } else if (item.username) { var list = can.core.List(item.username) - type = html.INPUT, name = name||list[0]||html.USERNAME, data.name = data.name||name - data.className = list[1]||data.className||data.name - data.autocomplete = data.autocomplete||html.USERNAME - - } else if (item.password) { var list = can.core.List(item.password) - type = html.INPUT, name = name||list[0]||html.PASSWORD, data.name = data.name||name - data.className = list[1]||data.className||data.name - data.autocomplete = data.autocomplete||"current-password" - data.type = html.PASSWORD - - } else if (item.img) { var list = can.core.List(item.img) - type = html.IMG, data.src = list[0] - - } else if (item.row) { type = html.TR - item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} }) - } else if (item.th) { type = html.TR - item.list = item.th.map(function(text) { return {text: [text, html.TH]} }) - } else if (item.td) { type = html.TR - item.list = item.td.map(function(text) { return {text: [text, html.TD]} }) - } - - // 语言转换 - if (type == html.SELECT) { - data.title = can.user.trans(can, data.title||data.name) - } + if (type == html.SELECT) { data.title = can.user.trans(can, data.title||data.name) } if (type == html.INPUT) { data.type == html.BUTTON && (data.value = can.user.trans(can, data.value)) if (data.type == html.TEXT||data.type == html.PASSWORD||!data.type) { data.autocomplete = data.autocomplete||"off" - // data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) - data.placeholder = (data.placeholder||data.name||"").split(ice.PT).pop() - data.title = can.user.trans(can, data.title||data.placeholder) + data.placeholder = (data.placeholder||data.name||"").split(ice.PT).pop(), data.title = can.user.trans(can, data.title||data.placeholder) } - } - if (type == html.TEXTAREA) { - data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) - } + } else if (type == html.TEXTAREA) { data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) } - // 创建节点 - !data.name && item.name && (data.name = item.name) - var node = can.page.Create(can, type, data) - - // 创建索引 - 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) - target && target.appendChild && target.appendChild(node) - can.base.isFunc(item._init) && item._init(node, value) - }) - return value - }), - Appends: shy("添加节点", function(can, target, key, value) { - return target.innerHTML = "", can.page.Append(can, target, key, value) - }), - - AppendTable: shy("添加表格", function(can, msg, target, list, cb) { - if (!msg.append||msg.append.length == 0) {return} - - var table = can.page.Append(can, target, html.TABLE) - var thead = can.page.Append(can, table, "thead") - var tbody = can.page.Append(can, table, "tbody") - can.page.Append(can, thead, [{type: html.TR, data: {dataset: {index: -1}}, list: - can.core.List(list, function(key) { - return key[0] == "_"? undefined: {text: [key.trim(), html.TH]} - }) - }]) - can.page.Append(can, tbody, can.core.List(msg.Table(), function(line, index, array) { - var _list = can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return } - return cb(can.page.Color(line[key]).trim(), key, index, line, array) - }) - return _list.length > 0? {type: html.TR, dataset: {index: index}, list: _list}: undefined - })) + !data.name && item.name && (data.name = item.name); var node = can.page.Create(can, type, data) + value[name||""] = value[data.className||""] = value[type] = node, value._target = value._target||node, value.first = value.first||node, value.last = node + item.list && can.page.Append(can, node, item.list, value), target && target.appendChild && target.appendChild(node), can.base.isFunc(item._init) && item._init(node, value) + }); return value + }, + Appends: function(can, target, key, value) { return target.innerHTML = "", can.page.Append(can, target, key, value) }, + AppendTable: function(can, msg, target, list, cb) { if (!msg.append||msg.append.length == 0) {return} + var table = can.page.Append(can, target, html.TABLE), thead = can.page.Append(can, table, html.THEAD), tbody = can.page.Append(can, table, html.TBODY) + can.page.Append(can, thead, [{type: html.TR, data: {dataset: {index: -1}}, list: can.core.List(list, function(key) { return key[0] != "_" && {text: [key.trim(), html.TH]} }) }]) + can.page.Append(can, tbody, can.core.List(msg.Table(), function(line, index, array) { return {type: html.TR, dataset: {index: index}, list: can.core.List(list, function(key) { return key[0] != "_" && cb(can.page.Color(line[key]).trim(), key, index, line, array) }) } })) return can.page.OrderTable(can, table) - }), + }, OrderTable: function(can, table) { - can.page.Select(can, table, html.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 + can.page.Select(can, table, html.TH, function(th, index) { th.onclick = function(event) { var dataset = event.target.dataset + can.page.RangeTable(can, table, index, (dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1) == "1") + } }); return table }, RangeTable: function(can, table, index, sort_asc) { + index = can.core.List(index, function(item) { if (item > -1) { return item } }); if (index.length == 0) { return } var list = can.page.Select(can, table, html.TR, function(tr) { return tr.style.display == html.NONE||can.page.ClassList.has(can, tr, "hide")? null: tr }).slice(1) - - index = can.base.isObject(index)? index: [index] - index = can.core.List(index, function(item) { if (item > -1) { return item} }) - if (index.length == 0) { return } - - var is_time = true, is_number = true - can.core.List(list, function(tr) { - var text = tr.childNodes[index[0]].innerText - is_time = is_time && Date.parse(text) > 0 - is_number = is_number && !isNaN(parseInt(text)) + var is_time = true, is_number = true; can.core.List(list, function(tr) { + var text = tr.childNodes[index[0]].innerText; is_time = is_time && Date.parse(text) > 0, is_number = is_number && !isNaN(parseInt(text)) }) - - var num_list = can.core.List(list, function(tr) { - var text = tr.childNodes[index[0]].innerText - return is_time? Date.parse(text): - is_number? can.base.ParseSize(text): text + var num_list = can.core.List(list, function(tr) { var text = tr.childNodes[index[0]].innerText + return is_time? Date.parse(text): is_number? can.base.ParseSize(text): text }) function isless(a, b, index) { if (a.childNodes[index[0]] && b.childNodes[index[0]]) { if (a.childNodes[index[0]].innerText < b.childNodes[index[0]].innerText) { return true } if (a.childNodes[index[0]].innerText > b.childNodes[index[0]].innerText) { return false } - } - return index.length > 1 && isless(a, b, index.slice(1)) + } return index.length > 1 && isless(a, b, index.slice(1)) } - - // 选择排序 for (var i = 0; i < num_list.length; i++) { var min = i for (var j = i+1; j < num_list.length; j++) { if (num_list[min] == num_list[j] && index.length > 1 && list[index[1]]) { - if (sort_asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) { - min = j - } - } else if (sort_asc? num_list[min] < num_list[j]: num_list[j] < num_list[min]) { - min = j - } + if (sort_asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) { min = j } + } else if (sort_asc? num_list[min] < num_list[j]: num_list[j] < num_list[min]) { min = j } } - if (min != i) { var temp = num_list[i]; num_list[i] = num_list[min]; num_list[min] = temp var temp = list[i]; list[i] = list[min]; list[min] = temp } - - var tbody = list[i].parentElement - list[i].parentElement && tbody.removeChild(list[i]) - tbody.appendChild(list[i]) + var tbody = list[i].parentElement; list[i].parentElement && tbody.removeChild(list[i]), tbody.appendChild(list[i]) } }, - Cache: function(name, output, data) { if (!name) { return } - var cache = output._cache||{}; output._cache = cache - if (data) { if (output.children.length == 0) { return } - var temp = document.createDocumentFragment() - while (output.childNodes.length > 0) { // 写缓存 - var item = output.childNodes[0] - item.parentNode.removeChild(item), - temp.appendChild(item) - } - return cache[name] = {node: temp, data: data}, name - } - output.innerHTML = "" - - var list = cache[name]; if (!list) { return } - while (list.node.childNodes.length > 0) { // 读缓存 - var item = list.node.childNodes[0] - item.parentNode.removeChild(item) - output.appendChild(item) - } - return delete(cache[name]), list.data - }, - Format: function(type) { var args = arguments - switch (type) { - case html.A: return ""+(args[2]||args[1])+"" - case html.IMG: return args[2]? "": "" - case html.SPAN: return args[2]? ""+args[1]+"": args[1] - } - }, - replace: function(can, text, key, value) { - return can.base.replaceAll(text, "<", "<", ">", ">", key, value) - }, - Color: function(text) { if (typeof text != lang.STRING) { return "" } - if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) { - var ls = text.split(ice.SP); - text = ""+ls[0]+""+ls.slice(1).join(ice.SP) - }; text = text.replace(/\\n/g, "
") + inputs: function(can, list) { + var _list = []; for (var i = 0; i < list.length; i++) { switch (list[i]) { + case "": _list.push(""); break + case ice.AUTO: + _list.push({type: html.BUTTON, name: "list"}) + _list.push({type: html.BUTTON, name: "back"}) + break + case mdb.PAGE: + _list.push({type: html.TEXT, name: mdb.LIMIT, value: can._msg.Option(mdb.LIMIT)}) + _list.push({type: html.TEXT, name: mdb.OFFEND, value: can._msg.Option(mdb.OFFEND)}) + _list.push(mdb.PREV, mdb.NEXT) + break + default: + (function() { var item = can.core.SplitInput(list[i], html.BUTTON); + if (item.type == html.SELECT) { item._init = function(target) { target.value = item.value||item.values[0], target.onchange = function(event) { can.run(event) } } } + item.action && (function() { item._init = function(target) { can.onappend.figure(can, item, target) } })() + item.type == html.BUTTON? _list.push(list[i]): _list.push(item) + })() + } } return _list + }, + input: function(can, item, value) { + var input = {type: html.INPUT, name: item.name, data: item, dataset: {}, _init: item._init, style: item.style||{}} + item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO) + switch (item.type = item.type||html.TEXT) { + case html.TEXTAREA: input.type = html.TEXTAREA + input.style.height = input.style.height||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.HEIGHT].join(ice.PT))||can.Conf([ctx.FEATURE, html.TEXTAREA, html.HEIGHT].join(ice.PT)) + input.style.width = input.style.width||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.WIDTH].join(ice.PT))||can.Conf([ctx.FEATURE, html.TEXTAREA, html.WIDTH].join(ice.PT)) + // no break + case html.USERNAME: // no break + case html.PASSWORD: // no break + case html.TEXT: + item.autocomplete = "off" + item.name = item.name||item.type + item.value = value||item.value||"" + item.placeholder = item.placeholder||item.name||item.type + item.title = item.title||item.placeholder||item.name||item.type + item.className || can.page.ClassList.add(can, item, ctx.ARGS); break + case html.SELECT: input.type = html.SELECT + item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values + if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] } + if (item.values.slice(1).indexOf(item.values[0]) > -1) { item.value = item.value||item.values[0], item.values = item.values.slice(1) } + item.value = value||item.value, input.list = item.values.map(function(value) { return {type: html.OPTION, value: value, inner: value} }) + item.className || can.page.ClassList.add(can, item, ctx.ARGS); break + case html.BUTTON: item.value = item.value||item.name||mdb.LIST; break + case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break + case "upfile": item.type = html.FILE; break + } return input + }, + replace: function(can, text, key, value) { return can.base.replaceAll(text, "<", "<", ">", ">", key, value) }, + Format: function(type) { var args = arguments; switch (type) { + case html.A: return ""+(args[2]||args[1])+"" + case html.IMG: return args[2]? "": "" + case html.SPAN: return args[2]? ""+args[1]+"": args[1] + } }, + Color: function(text) { if (typeof text != lang.STRING) { return "" } text = text.replace(/\\n/g, "
") + if (text.indexOf(ice.HTTP) == 0) { var ls = text.split(ice.SP); text = ""+ls[0]+""+ls.slice(1).join(ice.SP) } if (text.indexOf("\033\[") == -1) { return text } text = text.replace(/\033\[31m/g, "") text = text.replace(/\033\[32m/g, "") @@ -339,145 +206,47 @@ Volcanos("page", {help: "用户界面", ClassList: { text = text.replace(/\033\[m/g, "") return text }, - input: function(can, item, value) { - var input = {type: html.INPUT, name: item.name, data: item, dataset: {}, _init: item._init, style: item.style||{}} - item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO) - - switch (item.type = item.type||html.TEXT) { - case html.TEXTAREA: input.type = html.TEXTAREA - input.style.height = input.style.height||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.HEIGHT].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.HEIGHT].join(ice.PT)) - input.style.width = input.style.width||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.WIDTH].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.WIDTH].join(ice.PT)) - // no break - case html.USERNAME: - case html.PASSWORD: - // no break - case html.TEXT: - item.autocomplete = "off" - item.name = item.name||item.type - item.value = value||item.value||"" - item.placeholder = item.placeholder||item.name||item.type - item.title = item.title||item.placeholder||item.name||item.type - item.className || can.page.ClassList.add(can, item, ctx.ARGS) - break - case html.SELECT: input.type = html.SELECT - item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values - if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] } - - if (item.values.slice(1).indexOf(item.values[0]) > -1) { - item.value = item.value||item.values[0], item.values = item.values.slice(1) - } - item.value = value||item.value, input.list = item.values.map(function(value) { - return {type: html.OPTION, value: value, inner: value} - }), item.className || can.page.ClassList.add(can, item, ctx.ARGS) - break - case html.BUTTON: item.value = item.value||item.name||mdb.LIST; break - case "upfile": item.type = html.FILE; break - case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break - default: - } - return input - }, - inputs: function(can, list) { - var _list = []; for (var i = 0; i < list.length; i++) { - switch (list[i]) { case "": _list.push(""); break - case ice.AUTO: - _list.push({type: html.BUTTON, name: "list"}) - _list.push({type: html.BUTTON, name: "back"}) - break - case mdb.PAGE: - _list.push({type: html.TEXT, name: mdb.LIMIT, value: can._msg.Option(mdb.LIMIT)}) - _list.push({type: html.TEXT, name: mdb.OFFEND, value: can._msg.Option(mdb.OFFEND)}) - _list.push(mdb.PREV, mdb.NEXT) - break - default: - (function() { var item = can.core.SplitInput(list[i], html.BUTTON); - if (item.type == html.SELECT) { - item._init = function(target) { target.value = item.value||item.values[0], target.onchange = function(event) { can.run(event) } } - } - item.action && (function() { item._init = function(target) { can.onappend.figure(can, item, target) } })() - item.type == html.BUTTON? _list.push(list[i]): _list.push(item) - })() - } - } - return _list - }, - - styleDisplay: function(can, target, value) { - return can.page.style(can, target, html.DISPLAY, value), target.style.display - }, - styleHeight: function(can, target, value) { - return can.page.style(can, target, html.HEIGHT, value), target.offsetHeight - }, - styleWidth: function(can, target, value) { - return can.page.style(can, target, html.WIDTH, value), target.offsetWidth - }, - styleClass: function(can, target, value) { - can.page.Modify(can, target, {className: value}) - }, - style: function(can, target, style) { var value = {} - for (var i = 2; i < arguments.length; i += 2) { - if (typeof arguments[i] == lang.OBJECT) { - can.page.Modify(can, target, {style: arguments[i--]}) - } else if (typeof arguments[i] == lang.UNDEFINED) { - continue - } else { - value[arguments[i]] = arguments[i+1] - } - } - return can.page.Modify(can, target, {style: value}), value - }, Keys: function() { var list = [] // FS SP GT PT for (var i = 0; i < arguments.length; i++) { var v = arguments[i] if (typeof v == lang.OBJECT) { - for (var j = 0; j < v.length; j++) { - if (typeof v[j] == lang.OBJECT) { - for (var k = 0; k < v[j].length; k++) { - if (typeof v[j][k] == lang.OBJECT) { v[j][k] = v[j][k].join(ice.PT) } - } - v[j] = v[j].join(ice.GT) - } - } - list.push(v.join(ice.SP)) - } else { - list.push(v+"") - } - } - return list.join(ice.FS) + for (var j = 0; j < v.length; j++) { if (typeof v[j] == lang.OBJECT) { + for (var k = 0; k < v[j].length; k++) { if (typeof v[j][k] == lang.OBJECT) { v[j][k] = v[j][k].join(ice.PT) } } + v[j] = v[j].join(ice.GT) + } } list.push(v.join(ice.SP)) + } else { list.push(v+"") } + } return list.join(ice.FS) }, - css: function(text) { - var styleSheet = document.createElement("style") - styleSheet.type = "text/css", styleSheet.innerText = text - document.head.appendChild(styleSheet) + Cache: function(name, output, data) { if (!name) { return } + var cache = output._cache||{}; output._cache = cache + if (data) { if (output.children.length == 0) { return } + var temp = document.createDocumentFragment() + while (output.childNodes.length > 0) { var item = output.childNodes[0]; item.parentNode.removeChild(item), temp.appendChild(item) } + return cache[name] = {node: temp, data: data}, name + } output.innerHTML = "" + var list = cache[name]; if (!list) { return } + while (list.node.childNodes.length > 0) { var item = list.node.childNodes[0]; item.parentNode.removeChild(item), output.appendChild(item) } + return delete(cache[name]), list.data }, - tagis: function(target) { - var type = target.tagName.toLowerCase() - for (var i = 1; i < arguments.length; i++) { - if (type == arguments[i]) { return true } - } - }, - offsetTop: function(item) { var res = 0 - while (item) { res += item.offsetTop||0, item = item.parentNode } - return res - }, - offsetLeft: function(item) { var res = 0 - // if (item.offsetLeft) { return item.offsetLeft } - while (item) { res += item.offsetLeft||0, item = item.parentNode } - return res - }, - editable: function(can, item, ok) { item.setAttribute("contenteditable", ok) }, - draggable: function(can, item, ok) { item.setAttribute("draggable", ok) }, - AppendVue: function(can, meta, list, target) { - can.require(["https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"], function() { - can.require(["https://unpkg.com/element-ui/lib/index.js", "https://unpkg.com/element-ui/lib/theme-chalk/index.css"], function() { - new Vue(can.base.Copy({el: can.page.Append(can, target||can._output, [{type: "div", inner: list}]).first}, meta)) - }) - }) - }, insertBefore: function(can, list, before, parent) { parent = parent||before.parentNode var item = can.base.isArray(list)? can.page.Append(can, parent, list).first: list return before && parent.insertBefore(item, before), item }, + styleDisplay: function(can, target, value) { return can.page.style(can, target, html.DISPLAY, value), target.style.display }, + styleHeight: function(can, target, value) { return can.page.style(can, target, html.HEIGHT, value), target.offsetHeight }, + styleWidth: function(can, target, value) { return can.page.style(can, target, html.WIDTH, value), target.offsetWidth }, + styleClass: function(can, target, value) { can.page.Modify(can, target, {className: value}) }, + style: function(can, target, style) { var value = {} + for (var i = 2; i < arguments.length; i += 2) { + if (typeof arguments[i] == lang.OBJECT) { + can.page.Modify(can, target, {style: arguments[i--]}) + } else if (can.base.isUndefined(arguments[i])) { continue + } else { value[arguments[i]] = arguments[i+1] } + } return can.page.Modify(can, target, {style: value}), value + }, + tagis: function(target) { var type = target.tagName.toLowerCase(); for (var i = 1; i < arguments.length; i++) { if (type == arguments[i]) { return true } } }, + editable: function(can, item, ok) { item.setAttribute("contenteditable", ok) }, + draggable: function(can, item, ok) { item.setAttribute("draggable", ok) }, height: function() { return window.innerHeight }, width: function() { return window.innerWidth }, }) diff --git a/lib/user.js b/lib/user.js index 2f50ad72..1fe2e516 100644 --- a/lib/user.js +++ b/lib/user.js @@ -1,44 +1,33 @@ -Volcanos("user", {help: "用户操作", info: {}, agent: { +Volcanos("user", {info: {}, agent: { + chooseImage: function(can, cb) { can.base.isFunc(cb) && cb([]) }, scanQRCode: function(can, cb) { - can.user.input(event, can, [{type: html.TEXTAREA, name: "text", text: ""}], function(list) { - cb(can.base.ParseJSON(list[0])) - }) + can.user.input(event, can, [{type: html.TEXTAREA, name: "text", text: ""}], function(list) { cb(can.base.ParseJSON(list[0])) }) }, - getLocation: function(can, cb) { var call = arguments.callee - if (call._res) { return cb(call._res) } - + getLocation: function(can, cb) { var call = arguments.callee; if (call._res) { return cb(call._res) } navigator.geolocation.getCurrentPosition(function(res) { cb(call._res = {latitude: parseInt(res.coords.latitude*100000), longitude: parseInt(res.coords.longitude*100000)}) - }, function(some) { - typeof cb == lang.FUNCTION && cb({type: "unknown", name: "unknown", latitude: 3998412, longitude: 11630748}) - } ); + }, function(some) { can.base.isFunc(cb) && cb({type: "unknown", name: "unknown", latitude: 3998412, longitude: 11630748}) } ) }, openLocation: function(can, msg) { window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT)) +"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT))) }, - chooseImage: function(can, cb) { - typeof cb == lang.FUNCTION && cb([]) - }, }, isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1, isIPhone: navigator.userAgent.indexOf("iPhone") > -1, isMobile: navigator.userAgent.indexOf("Mobile") > -1, isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1, isWindows: navigator.userAgent.indexOf("Windows") > -1, - isWebview: window.webview != undefined, isIE: navigator.userAgent.indexOf("MSIE") > -1, + isWebview: window.webview != undefined, isExtension: location && location.protocol && location.protocol == "chrome-extension:", isLocalFile: location && location.protocol && location.protocol == "file:", isLandscape: function() { return window.innerWidth > window.innerHeight }, - isPortrait: function() { return window.innerWidth < window.innerHeight }, mod: { isPod: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 || location.pathname.indexOf("/x/") == 0), + isCmd: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/cmd/") > 0 || location.pathname.indexOf("/chat/cmd/") == 0 || location.pathname.indexOf("/help/") == 0), + isWeb: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/website/") > 0 || location.pathname.indexOf("/chat/website/") == 0), isDiv: location && location.pathname && (location.pathname.indexOf("/chat/div/") == 0), - isCmd: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/cmd/") > 0 || - location.pathname.indexOf("/chat/cmd/") == 0 || location.pathname.indexOf("/help/") == 0), - isWeb: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/website/") > 0 || - location.pathname.indexOf("/chat/website/") == 0), }, alert: function(text) { alert(JSON.stringify(text)) }, @@ -48,217 +37,112 @@ Volcanos("user", {help: "用户操作", info: {}, agent: { jumps: function(url) { location.href = url }, open: function(url) { window.open(url) }, close: function(url) { window.close() }, - time: function(can, time, fmt) { var now = can.base.Date(time) - var list = can.user.language(can) == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] - return can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()])) - }, - args: function(can) { - if (can.user.isExtension) { - return can.base.Obj(localStorage.getItem(ctx.ARGS), {}) - } - return {} - }, title: function(text) { if (window.webview) { return title(text) } - return text && (document.title = Volcanos.meta.args.name||text), document.title + return text && (document.title = text), document.title }, topic: function(can, name) { can.base.isString(name) && (name = [name]) || name || [] can.user.isMobile && name.push("mobile") && can.user.isLandscape() && name.push("landscape") can.user.language(can) && name.push(can.user.language(can)) can.Conf("display") && name.push(can.Conf("display")) + can.user.isWebview && name.push("webview") can.user.mod.isCmd && name.push("simple") - window.webview && name.push("webview") - can.page.styleClass(can, can._root._target, name.join(ice.SP)) + can.page.styleClass(can, document.body, name.join(ice.SP)) }, language: function(can) { return can.misc.Search(can, "language") }, - trans: function(can, text, list) { if (can.base.isObject(text)) { - return can.core.Item(text, function(k, v) { can.core.Value(can._trans, k, v) }) - } - + trans: function(can, text, list) { if (can.base.isFunc(text)) { text = text.name||"" } + if (can.base.isObject(text)) { return can.core.Item(text, function(k, v) { can.core.Value(can._trans, k, v) }) } if (can.user.language(can) == "en") { return text } - if (can.base.isFunction(text)) { text = text.name||"" } - return list&&list[text] || can.Conf("trans."+text) || can.Conf("feature._trans."+text) || can._trans&&can._trans[text] || { - "create": "创建", "remove": "删除", "insert": "添加", "delete": "删除", "modify": "编辑", - "inputs": "补全", "prunes": "清理", "export": "导出", "import": "导入", - "list": "查看", "back": "返回", "run": "执行", "done": "完成", "share": "共享", - "edit": "编辑", "save": "保存", "copy": "复制", "show": "显示", "hide": "隐藏", - "project": "项目", "profile": "详情", "actions": "参数", - "download": "下载", "toimage": "截图", - "plugin": "插件", - "prev": "上一页", "next": "下一页", - "width": "宽度", - "height": "高度", - "link": "链接", - "Close": "关闭", - "Close others": "关闭其它", - "Close all": "关闭所有", - "source": "源码", - "module": "模块", - "recent": "最近", + return list&&list[text] || can._trans&&can._trans[text] || can.Conf("trans."+text) || can.Conf("feature._trans."+text) || { + "plugin": "插件", "label": "标签", "height": "高度", "width": "宽度", "show": "显示", "hide": "隐藏", "project": "项目", "profile": "详情", "actions": "参数", + "create": "创建", "remove": "删除", "insert": "添加", "delete": "删除", "modify": "修改", "prunes": "清理", "export": "导出", "import": "导入", + "link": "链接", "copy": "复制", "edit": "编辑", "save": "保存", "trash": "删除", "share": "共享", "toimage": "截图", "download": "下载", + "run": "执行", "list": "查看", "back": "返回", "prev": "上一页", "next": "下一页", + "source": "源码", "module": "模块", "recent": "最近", - "trash": "删除", "open": "打开", "close": "关闭", "start": "启动", "stop": "停止", "begin": "开始", "end": "结束", + "exec": "执行", "done": "完成", "clear": "清空", "refresh": "刷新", "submit": "提交", "cancel": "取消", - "label": "标签", "exec": "执行", + + "Close": "关闭", + "Close others": "关闭其它", + "Close all": "关闭所有", }[text]||text }, - toastScript: function(can, content, title) { - var ui = can.user.toast(can, {title: title, duration: -1, width: -300, content: content, action: [cli.CLOSE]}) - can.onmotion.story.auto(can, ui._target) + time: function(can, time, fmt) { var now = can.base.Date(time) + var list = can.user.language(can) == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] + if (fmt == "%W") { return list } + return can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()])) }, - toastConfirm: function(can, content, title, action) { - return can.user.toast(can, {title: title, content: content, action: action||[cli.CLOSE], duration: -1, width: -300}) - }, - toastProcess: function(can, title, content) { return can.user.toast(can, content||ice.PROCESS, title, -1) }, - toastSuccess: function(can, title, content) { return can.user.toast(can, content||ice.SUCCESS, title) }, + + toastConfirm: function(can, content, title, action) { return can.user.toast(can, {content: content, title: title, action: action||[cli.CLOSE], duration: -1, width: -300}) }, + toastProcess: function(can, content, title) { return can.user.toast(can, content||ice.PROCESS, title||can._name.split(ice.PS).slice(-2).join(ice.PS), -1) }, + toastSuccess: function(can, content, title) { return can.user.toast(can, content||ice.SUCCESS, title||can._name.split(ice.PS).slice(-2).join(ice.PS)) }, toast: function(can, content, title, duration, progress) { var meta = can.base.isObject(content)? 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: chat.TOAST, style: { - left: (window.innerWidth-width)/2, width: width, bottom: 100, + var width = meta.width||400; if (width < 0) { width = window.innerWidth + width } + var ui = can.page.Append(can, document.body, [{view: [[chat.TOAST, chat.FLOAT]], style: { + width: width, left: (window.innerWidth-width)/2, bottom: 100, }, list: [ {text: [meta.title||"", html.DIV, html.TITLE], title: "点击复制", onclick: function(event) { can.user.copy(event, can, meta.title) - }}, - {view: "duration", title: "点击关闭", onclick: function() { action.close() }}, - can.base.isObject(meta.content)? meta.content: {text: [meta.content||"执行成功", html.DIV, "content"]}, - - {view: html.ACTION}, meta.progress != undefined && {view: "progress", style: {width: width}, list: [ + }}, {view: "duration", title: "点击关闭", onclick: function() { action.close() }}, + can.base.isObject(meta.content)? meta.content: {text: [meta.content||"", html.DIV, nfs.CONTENT]}, + html.ACTION, meta.progress != undefined && {view: "progress", style: {width: width}, list: [ {view: "current", style: {width: (meta.progress||0)/100*width}}, ]}, - ] }]) - - can.page.ClassList.add(can, ui._target, chat.FLOAT) + ] }]); can.onengine.signal(can, chat.ONTOAST, can.request({}, {time: can.misc._time(), title: meta.title, content: meta.content, fileline: can.misc.FileLine(-3)})) var action = can.onappend._action(can, meta.action && meta.action.list? meta.action.list: meta.action||[""], ui.action, { - _engine: function(event, button) { - var cb = meta.action[button]||meta.action; can.base.isFunc(cb) && cb(event, button) - }, + _engine: function(event, button) { can.core.CallFunc(meta.action[button]||meta.action, [event, button]) }, open: function(event) { - if (meta.content.indexOf("http") == 0) { can.user.open(meta.content) } - if (meta.title.indexOf("http") == 0) { can.user.open(meta.title) } + if (meta.content.indexOf(ice.HTTP) == 0) { can.user.open(meta.content) } + if (meta.title.indexOf(ice.HTTP) == 0) { can.user.open(meta.title) } }, 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)+ice.PT+(index%10)+"s..." } }, function() { action.close() }), _target: ui._target, ui: ui, - }); can.onmotion.story.auto(can, ui._target) - - can.onengine.signal(can, chat.ONTOAST, can.request({}, {time: can.misc._time(), title: meta.title, content: meta.content, fileline: can.misc.FileLine(2, 2)})) - return action + }); can.onmotion.story.auto(can, ui._target); return action }, share: function(can, msg, cmd) { can.run(msg, cmd||[ctx.ACTION, chat.SHARE], function(msg) { - can.user.toast(can, { - title: msg.Append(mdb.NAME), duration: -1, + can.user.toast(can, {title: msg.Append(mdb.NAME), duration: -1, content: msg.Append(mdb.TEXT), action: [cli.CLOSE, cli.OPEN], }), can.user.copy(msg._event, can, msg.Append(mdb.NAME)) }) }, - login: function(can, cb, method, auto) { method = can.base.Obj(method, ["登录", "扫码"]) - var list = { - "登录": function(event, button, data) { - can.run({}, [aaa.LOGIN, data[html.USERNAME], data[html.PASSWORD]], function(msg) { - if (msg.Option(ice.MSG_USERNAME)) { - can.page.Remove(can, ui._target), can.base.isFunc(cb) && cb() - } else { - can.user.toast(can, "用户名或密码错误") - } - }) - return true - }, - "扫码": function() { - can.misc.WSS(can, {type: html.CHROME, cmd: "pwd"}, 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 == ice.MSG_SESSID) { - return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) - } - can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) - }) - }, - "授权": function() { - can.misc.WSS(can, {type: html.CHROME, cmd: "sso", "back": location.href}, function(event, msg, cmd, arg) { if (!msg) { return } - if (cmd == "pwd") { - return location.href = arg[1] - } - if (cmd == ice.MSG_SESSID) { - return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) - } - can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) - }) - }, - }; if (auto) { return list["授权"]() } else if (method.length == 1) { list[method[0]](); return } - - var ui = can.user.input({}, can, [{type: html.USERNAME}, {type: html.PASSWORD}], function(event, button, data) { return list[button](event, button, data) }, method) - 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.runAction({}, aaa.LOGOUT, [], function(msg) { - can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true) - }) - } }, - - toPNG: function(can, name, text, height, width) { - if (text.indexOf("" - } - var img = document.createElement(html.IMG) - img.onload = function() { - var canvas = document.createElement("canvas") - canvas.height = height, canvas.width = width - canvas.getContext("2d").drawImage(img, 0, 0) - - var a = document.createElement("a") - a.href = canvas.toDataURL("image/png") - a.download = name, a.click() - }, img.src = "data:image/svg+xml,"+encodeURIComponent(text) - }, copy: function(event, can, text) { if (!text) { return } - if (navigator.clipboard) { var ok = false - navigator.clipboard.writeText(text).then(function() { ok = true }); if (ok) { - can.user.toastSuccess(can, text, "copy success"), can.misc.Log("copy", text) - return text - } + if (navigator.clipboard) { var ok = false; navigator.clipboard.writeText(text).then(function() { ok = true }) + if (ok) { return can.user.toastSuccess(can, text, "copy success"), can.misc.Log("copy", text), text } } - var input = can.page.Append(can, event.target.parentNode, [{type: html.TEXTAREA, value: text}]).first can.onmotion.focus(can, input), document.execCommand("Copy"), can.page.Remove(can, input) - can.user.toastSuccess(can, text, "copy success"), can.misc.Log("copy", text) - return text + return can.user.toastSuccess(can, text, "copy success"), can.misc.Log("copy", text), text }, - carte: function(event, can, meta, list, cb, parent) { // event item meta - meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||can.core.Item(meta)||[]; if (list.length == 0) { return } - cb = cb||function(event, button, meta) { var cb = meta[button]||meta["_engine"]; can.base.isFunc(cb) && cb(event, can, button) } - var ui = can.page.Append(can, document.body, [{view: chat.CARTE, style: {left: 0, top: 0}, onmouseleave: function(event) { + carte: function(event, can, meta, list, cb, parent) { + meta = meta||can.ondetail||can.onaction||{}, list = can.base.getValid(list, meta.list, can.core.Item(meta))||[]; if (list.length == 0) { return } + cb = cb||function(event, button, meta) { var cb = meta[button]||meta["_engine"]; can.base.isFunc(cb) && cb(event, can, button) } + parent || can.page.Select(can, document.body, can.page.Keys("div.carte.float"), function(target) { can.page.Remove(can, target) }) + var ui = can.page.Append(can, document.body, [{view: [[chat.CARTE, chat.FLOAT]], onmouseleave: function(event) { // can.page.Remove(can, ui._target) }, list: can.core.List(list, function(item, index) { - return can.base.isString(item)? item ==""? /* space */ {view: "space"}: /* string */ {view: html.ITEM, list: [{text: can.user.trans(can, item), onclick: function(event) { - can.user.isMobile && can.page.Remove(can, ui._target) - can.base.isFunc(cb) && cb(event, item, meta, index) - can.onkeymap.prevent(event) + return can.base.isString(item)? item ==""? /* space */ {view: html.SPACE}: /* string */ {view: html.ITEM, list: [{text: can.user.trans(can, item), onclick: function(event) { + can.base.isFunc(cb) && cb(event, item, meta, index), can.onkeymap.prevent(event), can.user.isMobile && can.page.Remove(can, ui._target) }, onmouseenter: function(event) { carte._float && can.page.Remove(can, carte._float._target) } }] }: can.base.isArray(item)? /* array */ {view: html.ITEM, list: [{text: can.user.trans(can, item[0])+" -> "}], onmouseenter: function(event) { - var sub = can.user.carte(event, can, meta, item.slice(1), cb, carte) + var sub = can.user.carte(event, can, meta, item.slice(1), cb, carte); can.onlayout.figure(event, can, sub._target, true) carte._float && can.page.Remove(can, carte._float._target), carte._float = sub - can.onlayout.figure(event, can, sub._target, true) } }: /* object */ {view: html.ITEM, list: [{text: can.user.trans(can, item.name), onclick: function(event) { - can.user.isMobile && can.page.Remove(can, ui._target) - can.base.isFunc(cb) && cb(event, item.name, meta, index) + can.base.isFunc(cb) && cb(event, item.name, meta, index), can.user.isMobile && can.page.Remove(can, ui._target) }, onmouseenter: function(event) { carte._float && can.page.Remove(can, carte._float._target) } }] } - }) }] ) - - parent || can.page.Select(can, document.body, can.page.Keys("div.carte.float"), function(target) { can.page.Remove(can, target) }) - can.page.ClassList.add(can, ui._target, chat.FLOAT) - ui._target.onmouseover = function(event) { can.onkeymap.prevent(event) } + }), onmouseover: function(event) { can.onkeymap.prevent(event) } }] ) var carte = {_target: ui._target, _parent: parent, layout: can.onlayout.figure(event, can, ui._target)} return can.onkeymap.prevent(event), carte }, @@ -266,120 +150,67 @@ Volcanos("user", {help: "用户操作", info: {}, agent: { var carte = can.user.carte(event, can, meta, list, cb, parent) return can.page.style(can, carte._target, can.onlayout.figure(event, can, carte._target, true)), carte }, - carteClient: function(event, can, meta, list, cb, parent) { - var ui = can.user.carte(event, can, meta, list, cb, parent) - can.page.style(can, ui._target, {left: event.clientX, top: event.clientY}) - }, input: function(event, can, form, cb, button) { if (!form || form.length == 0) { return cb() } var msg = can.request(event); event = event._event||event; var need = {} - var ui = can.page.Append(can, document.body, [{view: [html.INPUT], style: {left: 0, top: 0}, list: [ - {view: "content", list: [{view: [html.OPTION, html.TABLE], list: can.core.List(form, function(item) { + var ui = can.page.Append(can, document.body, [{view: [[html.INPUT, chat.FLOAT]], list: [ + {view: nfs.CONTENT, list: [{view: [html.OPTION, html.TABLE], list: can.core.List(form, function(item) { item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item - item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT) - need[item.name] = item.need - - item._init = function(target) { - item._enter = function(event) { action.submit(event, can, "submit") } + item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT), need[item.name] = item.need + item._init = function(target) { if (item.type == html.PASSWORD || item.type == html.USERNAME) { return } + if (item.name && item.name != ctx.ACTION) { target.value = msg.Option(item.name)||can.Option(item.name)||target.value||"" } item.run = item.run||function(event, cmds, cb) { var _msg = can.request(event, {_handle: ice.TRUE, action: msg.Option(html.ACTION)}, msg, can.Option()) - can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { - item.name && item.value && _msg.Option(item.name, item.value) - }) + can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { item.name && item.value && _msg.Option(item.name, item.value) }) can.run(event, cmds, cb, true) - } - - if (item.name != "action" && item.name) { - target.value = msg.Option(item.name)||can.Option(item.name)||target.value||"" - } - item.mode = "simple" - if (item.type == html.USERNAME) { return } - if (item.type == html.PASSWORD) { return } - can.onappend.figure(can, item, target) - } - - // return {type: html.TR, list: [{type: html.TD, list: [{text: item._trans||can.user.trans(can, item.name)||""}]}, {type: html.TD, list: [can.page.input(can, item)]} ]} - return {type: html.TR, list: [{type: html.TD, list: [{text: item.name||""}, {text: item.need == "must"? "*": "", style: {color: "red"}}]}, - {type: html.TD, list: [can.page.input(can, item)]} ]} - })}]}, {view: html.ACTION}, - ]}]) - + }, item._enter = function(event) { action.submit(event, can, html.SUBMIT) } + item.mode = "simple", can.onappend.figure(can, item, target) + }; return {type: html.TR, list: [{type: html.TD, list: [{text: item.name||""}, {text: item.need == "must"? "*": "", style: {color: cli.RED}}]}, {type: html.TD, list: [can.page.input(can, item)]}]} + })}]}, html.ACTION, + ]}]); can.onlayout.figure(event, can, ui._target), can.onmotion.delay(can, function() { action.focus() }) var action = can.onappend._action(can, button||[html.SUBMIT, html.CANCEL], ui.action, { focus: function(event) { can.page.Select(can, ui.first, html.INPUT_ARGS)[0].focus() }, 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 = [], err = false - list = can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { - if (item.value == "" && need[item.name] == "must") { - err = true, item.focus(), can.user.toast(can, item.name+" 是必选字段, 请重新输入") - } + submit: function(event, can, button) { var args = [], data = {}, err = false + var list = can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { + if (item.value == "" && need[item.name] == "must") { err = true, item.focus(), can.user.toast(can, item.name+" 是必选字段, 请重新输入") } return item.name && args.push(item.name, item.value||""), data[item.name] = item.value||"" - // return item.name && item.value && args.push(item.name, item.value), data[item.name] = item.value - }); if (err) { return } - - var msg = can.request(event, {_handle: ice.TRUE}) - !can.core.CallFunc(cb, {event: event, button: button, data: data, list: list, args: args}) && action.cancel() - // can.base.isFunc(cb) && !cb(event, button, data, list, args) && action.cancel() - can.onkeymap.prevent(event) - return err - }, _target: ui._target, - }) - if (button === true) { return action.submit(event, can, "submit"), action } - - can.page.ClassList.add(can, ui._target, chat.FLOAT); var layout = can.onlayout.figure(event, can, ui._target) - can.page.Select(can, ui._target, html.INPUT_ARGS, function(item, index) { - index == 0 && can.onmotion.delay(can, function() { can.onmotion.focus(can, item) }) - }) - return action + }); if (err) { return } can.onkeymap.prevent(event) + can.core.CallFunc(cb, {event: can.request(event, {_handle: ice.TRUE})._event, button: button, data: data, list: list, args: args}) || action.cancel() + }, _target: ui._target, _engine: function(event, can, button) { action.submit(event, can, button) }, + }); return button === true && action.submit(event, can, html.SUBMIT), action }, select: function(event, can, type, fields, cb, cbs) { - var msg = can.request(event, {fields: fields||"type,name,text"}) - can.search(msg, ["Search.onimport.select", type, "", ""], function(list) { - can.core.Next(list, cb, cbs||function() { - can.user.toastSuccess(can) - }) + can.search(can.request(event, {fields: fields||"type,name,text"}), ["Search.onimport.select", type, "", ""], function(list) { + can.core.Next(list, cb, cbs||function() { can.user.toastSuccess(can) }) }) }, upload: function(event, can, cb) { var begin = new Date() - var ui = can.page.Append(can, document.body, [{view: html.UPLOAD, style: {left: 0, top: 0}, list: [ - {view: html.ACTION}, {view: html.OUTPUT, list: [{view: "progress"}]}, - {view: html.STATUS, list: [{view: html.SHOW}, {view: "cost"}, {view: "size"}]}, + var ui = can.page.Append(can, document.body, [{view: [[html.UPLOAD, chat.FLOAT]], list: [ + html.ACTION, {view: html.OUTPUT, list: ["progress"]}, {view: html.STATUS, list: [html.SHOW, cli.COST, nfs.SIZE]}, ]}]); can.onlayout.figure(event, can, ui._target) - can.page.ClassList.add(can, ui._target, chat.FLOAT) - - var action = can.onappend._action(can, [ - {type: html.UPLOAD, onchange: function(event) { - action.show(event, 0, event.target.files[0].size, 0) - }}, cli.CLOSE, - ], ui.action, { + var action = can.onappend._action(can, [{type: html.UPLOAD, onchange: function(event) { action.show(event, 0, event.target.files[0].size, 0) }}, cli.CLOSE], ui.action, { close: function(event) { can.page.Remove(can, ui._target) }, begin: function(event) { begin = new Date() - var upload = can.page.Select(can, ui.action, "input[type=file]") - if (upload[0].files.length == 0) { return upload[0].focus() } - - var msg = can.request(event, can.Option(), {_handle: "true"}) - msg._upload = upload[0].files[0], msg._progress = action.show - + var upload = can.page.Select(can, ui.action, html.INPUT_FILE)[0] + if (upload.files.length == 0) { return upload.focus() } + var msg = can.request(event, can.Option(), {_handle: ice.TRUE}) + msg._upload = upload.files[0], msg._progress = action.show can.runAction(event, html.UPLOAD, [], cb||function(msg) { can.user.toastSuccess(can), can.Update(), action.close() }) }, - show: function (event, value, total, loaded) { now = new Date() - value == 0 && action.begin(event) - - ui.show.innerHTML = value+"%" - ui.cost.innerHTML = can.base.Duration(now - begin) + show: function (event, value, total, loaded) { + ui.cost.innerHTML = can.base.Duration(new Date() - begin) + ui.show.innerHTML = value+"%", value == 0 && action.begin(event) ui.size.innerHTML = can.base.Size(loaded)+ice.PS+can.base.Size(total) - can.page.style(can, ui.progress, {width: value*(ui.output.offsetWidth-2)/100}) + can.page.styleWidth(can, ui.progress, value*(ui.output.offsetWidth-2)/100) }, - }); can.page.Select(can, ui.action, "input[type=file]")[0].click() - - return action + }); can.page.Select(can, ui.action, html.INPUT_FILE)[0].click(); return action }, download: function(can, path, name, ext) { var a = can.page.Append(can, document.body, [{type: html.A, href: path, download: can.core.Keys(name, ext)||path.split(ice.PS).pop()}]).first - a.click(), can.page.Remove(can, a) - return path + return a.click(), can.page.Remove(can, a), path }, downloads: function(can, text, name, ext) { if (!text) { return } return can.user.download(can, URL.createObjectURL(new Blob([text])), name, ext) @@ -387,27 +218,54 @@ Volcanos("user", {help: "用户操作", info: {}, agent: { toimage: function(event, can, name, target, silent) { can.require(["https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.5/dist/html2canvas.min.js"], function() { html2canvas(target||can._target).then(function (canvas) { var url = canvas.toDataURL("image/png") - if (silent) { return can.user.download(can, url, name, "png") } - var toast = can.user.toast(can, {content: {img: url, style: {"max-height": 240, display: html.BLOCK}}, duration: -1, - action: shy({}, [cli.CLOSE, "download"], function(event, button) { - can.user.input(event, can, [{name: mdb.NAME, value: name}], function(list) { toast.close() - can.user.download(can, url, list[0], "png") - }) + if (silent) { return can.user.download(can, url, name, nfs.PNG) } + var toast = can.user.toast(can, {content: {img: url, style: {"max-height": window.innerHeight/2, display: html.BLOCK}}, title: can._name, duration: -1, + action: shy({}, [cli.CLOSE, web.DOWNLOAD], function(event, button) { + can.user.input(event, can, [{name: mdb.NAME, value: name}], function(list) { toast.close(), can.user.download(can, url, list[0], nfs.PNG) }) }), }) + can.onmotion.delay(can, function() { can.page.Select(can, toast._target, "img", function(target) { + can.page.style(can, toast._target, html.WIDTH, target.offsetWidth, html.LEFT, (window.innerWidth-target.offsetWidth)/2) + }) }) }) }) }, + toPNG: function(can, name, text, height, width) { + if (text.indexOf("" } + can.page.Create(html.IMG, {src: "data:image/svg+xml,"+encodeURIComponent(text), onload: function() { + var canvas = can.page.Create(can, html.CANVAS, {height: height, width: width}); canvas.getContext("2d").drawImage(img, 0, 0) + can.user.download(can, canvas.toDataURL("image/png"), name, nfs.PNG) + }}) + }, - camera: function(can, msg, cb) { - navigator.getUserMedia({video: true}, cb, function(error) { - can.misc.Log(error) - }) - }, - localStorage: function(can, key, value) { - if (value != undefined) { localStorage.setItem(key, value) } - return localStorage.getItem(key) - if (value != undefined) { localStorage.setItem(key, JSON.stringify(value)) } - return can.base.Obj(localStorage.getItem(key), {}) + login: function(can, cb, method, auto) { method = can.base.Obj(method, ["登录", "扫码"]) + var meta = { + "登录": function(event, button, data) { + can.run({}, [aaa.LOGIN, data[html.USERNAME], data[html.PASSWORD]], function(msg) { + if (!msg.Option(ice.MSG_USERNAME)) { return can.user.toast(can, "用户名或密码错误") } + can.page.Remove(can, ui._target), can.base.isFunc(cb) && cb() + }); return true + }, + "扫码": function() { + can.misc.WSS(can, {type: html.CHROME, cmd: "pwd"}, 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 == ice.MSG_SESSID) { return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) } + can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) + }) + }, + "授权": function() { + can.misc.WSS(can, {type: html.CHROME, cmd: "sso", "back": location.href}, function(event, msg, cmd, arg) { if (!msg) { return } + if (cmd == "pwd") { return location.href = arg[1] } + if (cmd == ice.MSG_SESSID) { return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) } + can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) + }) + }, + }; if (auto) { return meta["授权"]() } else if (method.length == 1) { meta[method[0]](); return } + + var ui = can.user.input({}, can, [{type: html.USERNAME}, {type: html.PASSWORD}], function(event, button, data) { return meta[button](event, button, data) }, method) + 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.runAction({}, aaa.LOGOUT, [], function(msg) { + can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true) + }) } }, }) diff --git a/page/index.css b/page/index.css index 7209348a..c55103bf 100644 --- a/page/index.css +++ b/page/index.css @@ -85,6 +85,7 @@ fieldset.input.date div.output td.next { color:gray; } fieldset.input.date div.output td { padding:2px 10px; } fieldset.input.date table { text-align:center; width:280px; } +body>div.toast div.action>div.item.space { height:unset; } body>div.float { background-color:#0e3369b3; color:white; padding:5px; } body>div.toast div.title { color:yellow; float:left; } body>div.toast div.duration { color:gray; float:right; } diff --git a/panel/action.js b/panel/action.js index 83b345a2..c4c28b2c 100644 --- a/panel/action.js +++ b/panel/action.js @@ -1,6 +1,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM); can.core.Next(msg.Table(), function(item, next) { item.inputs = can.base.Obj(item.inputs||item.list), item.feature = can.base.Obj(item.feature||item.meta) + if (can.misc.Debug(can, "plugin", item.index, item.args, item)) { debugger } can.onappend.plugin(can, item, function(sub, meta, skip) { can.onimport._run(can, sub, function(event, cmds, cb) { return can.run(event, can.misc.concat(can, [river, storm, meta.id||meta.index], cmds), cb) }), can.onimport._tabs(can, sub, meta), skip || next() }) @@ -12,6 +13,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can) can.Conf(chat.RIVER, web.SHARE, chat.STORM, share), can.onimport._init(can, msg) }) }, _cmd: function(can, item, next) { can.base.Copy(item, {mode: chat.CMD, opts: can.misc.Search(can)}), can.onengine.signal(can, chat.ONACTION_CMD) + if (can.misc.Debug(can, "plugin", item.index, item.args, item)) { debugger } can.onappend.plugin(can, item, function(sub, meta, skip) { can.onimport._run(can, sub, function(event, cmds, cb) { return can.runActionCommand(event, sub._index, cmds, cb) }), can.user.title(meta.name), skip || next() }) @@ -200,12 +202,12 @@ Volcanos(chat.ONEXPORT, { }) }, plugin: function(can, msg, word) { var fields = can.core.Split(msg.Option(ice.MSG_FIELDS)) - can.core.List(can._plugins, function(sub) { + can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (meta.index.indexOf(word[1]) == -1) { return } var data = {ctx: "can", cmd: "Action", type: mdb.PLUGIN, name: sub._legend.innerHTML, text: shy("跳转", function(event) { sub.Focus() }), argument: JSON.stringify(can.page.SelectArgs(can, sub._option, "", function(target) { return target.value })), } - var meta = sub._target._meta; if (meta.index) { + if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd diff --git a/panel/footer.js b/panel/footer.js index ea53320f..6af37614 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -64,12 +64,11 @@ Volcanos(chat.ONACTION, {help: "交互数据", _init: function(can, cb) { Volcanos(chat.ONEXPORT, {help: "导出数据", height: function(can) { return can._target.offsetHeight }, float: function(can, msg, name, cb) { if (can[name]) { return can[name].close() } - var ui = can.onappend.field(can, "story toast float", {}, can._root._target); can[name] = ui + var ui = can.onappend.field(can, "story toast float", {}, document.body); can[name] = ui ui.close = function() { can.page.Remove(can, ui.first), delete(can[name]) } ui.refresh = function() { ui.close(), can.toast.click() } can.getActionSize(function(left, top, height, width) { - // can.page.style(can, ui.first, html.LEFT, left, html.TOP, top) can.page.style(can, ui.first, html.RIGHT, 0, html.BOTTOM, can.onexport.height(can)) can.page.style(can, ui.output, html.MAX_HEIGHT, height-html.ACTION_HEIGHT, html.MAX_WIDTH, width) }) @@ -85,7 +84,14 @@ Volcanos(chat.ONEXPORT, {help: "导出数据", }, ui.output), can.onappend.board(can, msg.Result(), ui.output) return ui }, - ntip: function(can) { can.onexport.float(can, can._tips, "ntip") }, + ntip: function(can) { can.onexport.float(can, can._tips, "ntip", function(value, key, index, line) { + can.onappend.plugin(can, {type: chat.SRORY, mode: chat.FLOAT, index: "web.code.inner", args: ["usr/volcanos/"].concat(line.fileline.split(":"))}, function(sub) { + can.getActionSize(function(left, top, width, height) { left = left||0, top = top||0 + sub.onimport.size(sub, sub.ConfHeight(height/2), sub.ConfWidth(width)) + can.onmotion.move(can, sub._target, {left: left, top: top+height/4}) + }), sub.onaction.close = function() { can.page.Remove(can, sub._target) } + }, document.body) + }) }, ncmd: function(can) { can.onexport.float(can, can._cmds, "ncmd", function(value, key, index, line) { var cmds = can.base.Obj(line.cmds); switch (line.follow) { @@ -101,7 +107,7 @@ Volcanos(chat.ONEXPORT, {help: "导出数据", sub.run = function(event, cmd, cb) { can.runActionCommand(event, cmds[0], cmd, cb) } sub.onimport.size(sub, height-120-2*html.ACTION_HEIGHT-can.onexport.height(can), width, true) sub.onmotion.move(sub, sub._target, {left: left, top: top+120}) - }, can._root._target) + }, document.body) }) }) }, diff --git a/panel/header.js b/panel/header.js index e4b8013f..68ac2272 100644 --- a/panel/header.js +++ b/panel/header.js @@ -228,7 +228,7 @@ Volcanos(chat.ONACTION, {help: "交互数据", }) Volcanos(chat.ONEXPORT, {help: "导出数据", height: function(can) { return can._target.offsetHeight }, - topic: function(can) { return can._topic || can.misc.Search(can, chat.TOPIC) || Volcanos.meta.args.topic || (can.base.isNight()? chat.BLACK: chat.WHITE) }, + topic: function(can) { return can._topic || can.misc.Search(can, chat.TOPIC) || (can.base.isNight()? chat.BLACK: chat.WHITE) }, background: function(can) { return can.user.info.background == "void"? "": can.user.info.background }, avatar: function(can) { return can.user.info.avatar == "void"? "": can.user.info.avatar }, }) diff --git a/panel/river.js b/panel/river.js index 50cf87d5..0be75cf1 100644 --- a/panel/river.js +++ b/panel/river.js @@ -7,8 +7,8 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg) { })), select && select.click() }, _main: function(can, msg) { - can._main_river = can.misc.Search(can, chat.RIVER)||Volcanos.meta.args.river||msg.Option(ice.MSG_RIVER)||can._main_river||"project" - can._main_storm = can.misc.Search(can, chat.STORM)||Volcanos.meta.args.storm||msg.Option(ice.MSG_STORM)||can._main_storm||"studio" + can._main_river = can.misc.Search(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||can._main_river||"project" + can._main_storm = can.misc.Search(can, chat.STORM)||msg.Option(ice.MSG_STORM)||can._main_storm||"studio" }, _menu: function(can, msg) { if (can.user.mod.isPod||can.user.isMobile) { return } can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.ondetail._menus), function(event, button) { @@ -35,7 +35,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg) { }, }) Volcanos(chat.ONENGINE, {help: "解析引擎", _engine: function(event, can, msg, panel, cmds, cb) { - var list = can._root.river + var list = can.river cmds.length == 0 && can.core.ItemSort(list, "order", function(key, value) { if (can.core.Item(value.storm).length == 0) { return } msg.Push({hash: key, name: can.user.language(can) == "en"? key: value.name}) // 群组列表 diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 06735c7a..c70d6801 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -16,7 +16,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", function show(skip) { if (can.isCmdMode()) { can.onimport._title(can, path+file) } can._msg && can._msg.Option(nfs.LINE, can.Option(nfs.LINE)), can._msg = can.tabview[key] - can.Option(can.onimport.history(can, {path: path, file: file, line: line||can.user.localStorage(can, "web.code.vimer:selectLine:"+path+file)||can._msg.Option(nfs.LINE)|| 1})) + can.Option(can.onimport.history(can, {path: path, file: file, line: line||can.misc.localStorage(can, "web.code.vimer:selectLine:"+path+file)||can._msg.Option(nfs.LINE)|| 1})) can.onsyntax._init(can, can._msg, function(content) { var msg = can._msg can.onexport.hash(can), msg._tab && can.onmotion.select(can, msg._tab.parentNode, html.DIV_TABS, msg._tab) can.ui._path && (can.ui._path.innerHTML = isDream()? can.page.Format(html.A, can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)})): @@ -318,11 +318,11 @@ Volcanos(chat.ONACTION, {help: "控件交互", _trans: {link: "链接", width: " can.runAction(can.request(event, {_toast: "执行中..."}), mdb.ENGINE, [can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.display(can, msg) }) }, clear: function(event, can) { - if (can.page.Select(can, can._root._target, ".input.float", function(item) { return can.page.Remove(can, item) }).length > 0) { return } + if (can.page.Select(can, document.body, ".input.float", function(item) { return can.page.Remove(can, item) }).length > 0) { return } if (can.page.Select(can, can._status, "legend.select", function(item) { return item.click(), item }).length > 0) { return } if (can.ui.display.style.display == "") { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } if (can.ui.profile.style.display == "") { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } - if (can.page.Select(can, can._root._target, "div.vimer.find.float", function(item) { return can.page.Remove(can, item) }).length > 0) { return } + if (can.page.Select(can, document.body, "div.vimer.find.float", function(item) { return can.page.Remove(can, item) }).length > 0) { return } can.onmotion.toggle(can, can.ui.project), can.onimport.layout(can) }, }) @@ -375,7 +375,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar can.tabview = can.tabview||{}, can.history = can.history||[], can.toolkit = {}, can.extentions = {} can.profile_size = {}, can.display_size = {} - if (can.user.isWebview) { var last = can.user.localStorage(can, "web.code.inner:currentFile"); if (last) { var ls = can.core.Split(last, ice.DF) } } + if (can.user.isWebview) { var last = can.misc.localStorage(can, "web.code.inner:currentFile"); if (last) { var ls = can.core.Split(last, ice.DF) } } switch (can.Mode()) { case "simple": can.onmotion.hidden(can, can.ui.project); break @@ -463,7 +463,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar can.extentions[url.split("?")[0]] = sub, can.base.isFunc(cb)? cb(sub): sub.select() }) }) }, - sess: function(can, sess, cb) { sess = sess||can.base.Obj(can.user.localStorage(can, "web.code.inner.sess"), {}) + sess: function(can, sess, cb) { sess = sess||can.base.Obj(can.misc.localStorage(can, "web.code.inner.sess"), {}) can.core.Next(sess.plug, function(item, next) { can.onimport.toolkit(can, {index: item}, function(sub) { can.toolkit[item] = sub, next() }) }, function() { can.core.Next(sess.exts, function(item, next) { can.onimport.exts(can, item, next) }, function() { var path = can.Option(nfs.PATH), file = can.Option(nfs.FILE), line = can.Option(nfs.LINE) @@ -492,7 +492,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: [], }, }) Volcanos(chat.ONEXPORT, {help: "导出数据", - sess: function(can) { can.user.localStorage(can, "web.code.inner.sess", {"plug": can.onexport.plug(can), "exts": can.onexport.exts(can), "tabs": can.onexport.tabs(can)}) }, + sess: function(can) { can.misc.localStorage(can, "web.code.inner.sess", {"plug": can.onexport.plug(can), "exts": can.onexport.exts(can), "tabs": can.onexport.tabs(can)}) }, tabs: function(can) { return can.core.Item(can.tabview, function(key, msg) { return key+ice.DF+can.Option(nfs.LINE) }) }, plug: function(can) { return can.core.Item(can.toolkit) }, exts: function(can) { return can.core.Item(can.plugins) }, diff --git a/plugin/local/code/inner/syntax.js b/plugin/local/code/inner/syntax.js index 63449e6c..c07ef6cf 100644 --- a/plugin/local/code/inner/syntax.js +++ b/plugin/local/code/inner/syntax.js @@ -172,7 +172,6 @@ Volcanos(chat.ONSYNTAX, {help: "语法高亮", }, }, go: { - render: {}, split: { operator: "{([:.,*])}", }, diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js index 54c9739e..82ca39d5 100644 --- a/plugin/local/code/vimer.js +++ b/plugin/local/code/vimer.js @@ -460,8 +460,8 @@ Volcanos(chat.ONACTION, {help: "控件交互", target.focus(), can.onkeymap.cursorMove(can.ui.current, 0, 0) } can.ui.content.scrollLeft = scroll }) - can.user.localStorage(can, "web.code.inner:currentFile", can.Option(nfs.PATH)+ice.DF+can.Option(nfs.FILE)+ice.DF+can.onaction._getLineno(can, can.current.line)) - can.user.localStorage(can, "web.code.vimer:selectLine:"+can.Option(nfs.PATH)+can.Option(nfs.FILE), can.onaction._getLineno(can, can.current.line)) + can.misc.localStorage(can, "web.code.inner:currentFile", can.Option(nfs.PATH)+ice.DF+can.Option(nfs.FILE)+ice.DF+can.onaction._getLineno(can, can.current.line)) + can.misc.localStorage(can, "web.code.vimer:selectLine:"+can.Option(nfs.PATH)+can.Option(nfs.FILE), can.onaction._getLineno(can, can.current.line)) }, _getLine: function(can, line) { diff --git a/plugin/local/team/plan.js b/plugin/local/team/plan.js index 4c056104..86d12626 100644 --- a/plugin/local/team/plan.js +++ b/plugin/local/team/plan.js @@ -165,7 +165,7 @@ Volcanos(chat.ONACTION, {list: [mdb.PREV, mdb.NEXT, mdb.INSERT, mdb.EXPORT, mdb. Volcanos(chat.ONEXPORT, {list: [mdb.COUNT, "begin_time", mdb.ZONE, mdb.ID, mdb.TYPE, mdb.NAME, mdb.TEXT], span: function(can) { return {"day": 24*3600*1000, "week": 7*24*3600*1000, "month": 30*24*3600*1000, "year": 365*24*3600*1000, "long": 365*24*3600*1000}[can.Option("scale")]||0 }, hash: function(can, task) { if (!can.isCmdMode()) { return } location.hash = [task.zone, task.id].join(ice.FS) }, - head: function(can, scale) { if (["year", "long"].indexOf(scale) > -1) { return } return [scale].concat(can.user.info.language == "en"? ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]); }, + head: function(can, scale) { if (["year", "long"].indexOf(scale) > -1) { return } return [scale].concat(can.user.time(can, "", "%W")) }, name: function(can, task) { return task.name }, text: function(can, task) { return task.name+": "+(task.text||"") }, level: function(can, task) { return "l-"+(task.level||3)+": "+(task.name||"") }, diff --git a/plugin/local/wiki/feel.js b/plugin/local/wiki/feel.js index 532e8fa8..d161dfe9 100644 --- a/plugin/local/wiki/feel.js +++ b/plugin/local/wiki/feel.js @@ -143,7 +143,7 @@ Volcanos(chat.ONDETAIL, {help: "组件菜单", list: ["关闭", "下载", "删 sub.Status(cli.BEGIN, order+1+ice.PS+can.list.length), sub.Status(nfs.FILE, path) }, can.show(can.order) }) - }, can._root._target) + }, document.body) }, "关闭": function(event, can) { can.page.Remove(can, can.sub._target) }, "下载": function(event, can) { can.user.download(can, path = can.onimport._file(can, can.list[can.order].path)) }, diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js index b6c8e8ab..2ef0e33e 100644 --- a/plugin/local/wiki/word.js +++ b/plugin/local/wiki/word.js @@ -108,9 +108,9 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar can.runAction(can.request(event, data), "run", [data.index, "find", event.target.innerHTML]) } target.oncontextmenu = function(event) { - can.user.carteClient(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) { + var ui = can.user.carte(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) { can.user.toimage(event, can, "hi", target) - }), [mdb.EXPORT]) + }), [mdb.EXPORT]); can.page.style(can, ui._target, {left: event.clientX, top: event.clientY}) } }, table: function(can, data, target) { @@ -178,7 +178,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", can.keylist = can.onkeymap._parse(event, can, "normal", can.keylist) }})), can.onkeymap._build(can) - sub.page.style(sub, sub._target, html.BACKGROUND, can._root._target.style.background) + sub.page.style(sub, sub._target, html.BACKGROUND, document.body.style.background) sub.page.style(sub, sub._output, html.HEIGHT, can.page.height()-2*html.ACTION_HEIGHT) sub.page.style(sub, sub._output, html.WIDTH, can.page.width()) @@ -202,7 +202,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", var from = new Date(); can.core.Timer({interval: 100}, function() { var now = new Date() sub.Status(cli.COST, can.base.Duration(now-from)) }) - }, can._root._target) + }, document.body) }, view: function(event, can) { if (can._height) { diff --git a/plugin/story/video.js b/plugin/story/video.js index 8b51b91f..32d6fc19 100644 --- a/plugin/story/video.js +++ b/plugin/story/video.js @@ -8,7 +8,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar }) }, select: function(can, msg) { - msg.Clear(), can.page.Select(can, can._root._target, can.Option("tags"), function(a, index) { + msg.Clear(), can.page.Select(can, document.body, can.Option("tags"), function(a, index) { msg.Push(mdb.INDEX, index) msg.Push(mdb.NAME, a.innerText) msg.Push(mdb.LINK, a.href) @@ -33,7 +33,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", }) }, play: function(event, can) { - can.page.SelectAll(can, can._root._target, html.VIDEO, function(video) { + can.page.SelectAll(can, document.body, html.VIDEO, function(video) { video.playbackRate = parseFloat(can.Option("rate")) video.currentTime = parseInt(can.Option("skip")) video.ontimeupdate = function(event) { diff --git a/proto.js b/proto.js index 9fd36f69..91202dfb 100644 --- a/proto.js +++ b/proto.js @@ -7,7 +7,8 @@ var kit = { res[arguments[i]] = arguments[i+1] } } return res - } + }, + proto: function(sub, sup) { return sub.__proto__ = sup, sub }, } var ice = { TB: "\t", SP: " ", DF: ":", EQ: "=", AT: "@", PS: "/", PT: ".", FS: ",", NL: "\n", LT: "<", GT: ">", @@ -33,8 +34,8 @@ var ice = { MSG_SOURCE: "_source", MSG_TARGET: "_target", MSG_HANDLE: "_handle", - MSG_UPLOAD: "_upload", MSG_DAEMON: "_daemon", + MSG_UPLOAD: "_upload", MSG_ACTION: "_action", MSG_STATUS: "_status", MSG_PREFIX: "_prefix", @@ -79,6 +80,9 @@ var cli = { ERROR: "error", CLEAR: "clear", REFRESH: "refresh", SHOW: "show", FULL: "full", } +var log = { + INFO: "info", WARN: "warn", ERROR: "error", DEBUG: "debug", TRACE: "trace", +} var nfs = { PWD: "./", ZML: "zml", IML: "iml", TXT: "txt", @@ -88,6 +92,8 @@ var nfs = { DIR: "dir", CAT: "cat", DEFS: "defs", TRASH: "trash", DIR_ROOT: "dir_root", SCRIPT: "script", + CONTENT: "content", + PNG: "png", } var mdb = { DICT: "dict", META: "meta", HASH: "hash", LIST: "list", @@ -118,6 +124,13 @@ var aaa = { var web = { SPACE: "space", DREAM: "dream", SHARE: "share", REFRESH: "refresh", + WEBSITE: "website", + SHARE_CACHE: "/share/cache/", + DOWNLOAD: "download", + + GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE", + Accept: "Accept", ContentType: "Content-Type", + ContentJSON: "application/json", ContentFORM: "application/x-www-form-urlencoded", } var tcp = { HOST: "host", PORT: "port", @@ -249,14 +262,14 @@ var html = { FIELDSET_AUTO: "fieldset.auto", FIELDSET_FLOAT: "fieldset.float", OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", - INPUT_BUTTON: "input[type=button]", + INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]", // HTML UPLOAD: "upload", USERNAME: "username", PASSWORD: "password", INPUT: "input", TEXT: "text", TEXTAREA: "textarea", SELECT: "select", BUTTON: "button", FORM: "form", FILE: "file", SPACE: "space", CLICK: "click", SUBMIT: "submit", CANCEL: "cancel", DIV: "div", IMG: "img", CODE: "code", SPAN: "span", VIDEO: "video", - TABLE: "table", TBODY: "tbody", TR: "tr", TH: "th", TD: "td", BR: "br", UL: "ul", LI: "li", + TABLE: "table", THEAD: "thead", TBODY: "tbody", TR: "tr", TH: "th", TD: "td", BR: "br", UL: "ul", LI: "li", A: "a", LABEL: "label", INNER: "inner", TITLE: "title", H1: "h1", H2: "h2", H3: "h3", WSS: "wss", SVG: "svg", CANVAS: "canvas", IFRAME: "iframe", CHROME: "chrome", @@ -330,10 +343,9 @@ var Volcanos = shy("火山架", {iceberg: "/chat/", volcano: "/frame.js", pack: can.onengine._init(can, can.Conf(Config), panels, Config._init, can._target) }, can = {_follow: name, _target: Config.target||meta.target, _height: Config.height||meta._height, _width: Config.width||meta._width} for (var k in Config) { can[k] = Config[k] } - can._root = can } - var proto = {__proto__: meta, _path: _can_path, _name: name, _load: function(name, each) { + var proto = {_path: _can_path, _name: name, _load: function(name, each) { // 加载缓存 var cache = meta.cache[name]||[]; for (list.reverse(); list.length > 0; list) { var sub = list.pop(); sub != can && cache.push(sub) @@ -453,7 +465,7 @@ var Volcanos = shy("火山架", {iceberg: "/chat/", volcano: "/frame.js", pack: } return res }, _conf: {}, - }; can = can||{}, can.__proto__ = proto + }; can = can||{}, kit.proto(can, proto), kit.proto(proto, meta) if (_can_name) { // 加入缓存 meta.cache[_can_name] = meta.cache[_can_name]||[], meta.cache[_can_name].push(can) diff --git a/publish/chrome/contexts.js b/publish/chrome/contexts.js index d4164f39..1c580d9c 100644 --- a/publish/chrome/contexts.js +++ b/publish/chrome/contexts.js @@ -6,7 +6,7 @@ setTimeout(function() { Volcanos({Option: function() { return [] }, msg.Push(mdb.LINK, location.href) } - var has = {}; _target = _target||can._root._target + var has = {}; _target = _target||document.body can.page.Select(can, _target, html.IFRAME, function(item) { if (!item.src || has[item.src]) { return } has[item.src] = true @@ -41,7 +41,7 @@ setTimeout(function() { Volcanos({Option: function() { return [] }, }, change: function(can, msg, arg) { arg.length > 1 && can.page.Modify(can, arg[0], can.base.Obj(arg[1])) - arg.length > 0 && can.page.Select(can, can._root._target, arg[0], function(item) { + arg.length > 0 && can.page.Select(can, document.body, arg[0], function(item) { msg.Push(mdb.TEXT, item.outerHTML) }) }, @@ -87,11 +87,11 @@ setTimeout(function() { Volcanos({Option: function() { return [] }, can.run(event, [chat.FIELD, mdb.MODIFY, ctx.ARGS, JSON.stringify(sub.Input([], true))]) can.user.toastSuccess(can) } - }, can._root._target) + }, document.body) }, style: function(can, msg, arg) { can.core.List(arg[0].split(ice.FS), function(item) { - can.page.Select(can, can._root._target, item, function(target) { + can.page.Select(can, document.body, item, function(target) { can.page.Modify(can, target, can.base.Obj(arg[1])) }) }) @@ -104,7 +104,7 @@ setTimeout(function() { Volcanos({Option: function() { return [] }, }}) }) }, - _motion: function(can) { can.onmotion.float.auto(can, can._root._target) + _motion: function(can) { can.onmotion.float.auto(can, document.body) document.body.ondblclick = function(event) { can.onengine.signal(can, "onselection") } can.runAction({}, ctx.COMMAND, [], function(msg) {