diff --git a/demo/frame.js b/demo/frame.js index a472d71b..af5e464f 100644 --- a/demo/frame.js +++ b/demo/frame.js @@ -1,14 +1,183 @@ Volcanos("onappend", { - init: function(can, type, item, list, cb, target) { - var sub = Volcanos(item.name, { - _target: can.page.AppendField(can, target, type, item), - }, list, function(sub) { cb(sub) }) + _init: function(can, meta, list, cb, target) { + var field = can.onappend.field(can, target, meta.type, meta); + var option = can.page.Select(can, field, "form.option")[0]; + var action = can.page.Select(can, field, "div.action")[0]; + var output = can.page.Select(can, field, "div.output")[0]; + + // 添加插件 + var sub = Volcanos(meta.name, { _help: meta.name, _target: field, + _option: option, _action: action, _output: output, + _history: [], + }, list, function(sub) { sub.Conf(meta); + sub.onimport && sub.onimport._init && sub.onimport._init(sub, meta, [], function() { + }, output, action, option, field); + + // 添加控件 + can.core.Next(typeof meta.inputs == "string"? JSON.parse(meta.inputs||"[]"): meta.inputs || [], function(item, next) { + sub[item.name] = Volcanos(item.name, { + _target: can.onappend.input(sub, sub._option, "input", item), + _option: option, _action: action, _output: output, + }, Config.libs.concat(["plugin/input.js"]), function(input) { input.Conf(item); + // 事件回调 + input.run = function(event, cmds, cb, silent) { + + switch (item.name) { + case "返回": + // 历史命令 + sub._history.pop(); var his = sub._history.pop(); if (his) { + can.page.Select(can, option, "input.args", function(item, index) { + item.value = his[index] || "" + }) + } + } + + // 解析参数 + cmds = cmds && cmds.length > 0? cmds: can.page.Select(can, option, "input.args", function(item) { + return item.name && item.value || "" + }); for (var i = cmds.length-1; i >= 0; i--) { + if (!cmds[i]) { cmds.pop() } else { break } + } + + sub._history.push(cmds); sub.run(event, cmds, function(msg) { + if (silent) { typeof cb == "function" && cb(msg); return } + + // 添加组件 + var display = msg.Option("display")||meta.display||"table" + sub[display] = Volcanos(display, { _target: output, + _option: option, _action: action, _output: output, + }, Config.libs.concat(["plugin/"+display]), function(table) { + //事件响应 + table.onimport._init(table, msg, [], function() { + }, output, action, option) + }) + }, silent) + } + can.core.Item(input.onaction, function(key, value) { + key.indexOf("on") == 0 && (input._target[key] = function(event) { + // 事件触发 + value(event, input) + }) + }) + next() + }) + }) + }) + cb(sub) + }, + + item: function(can, target, type, item, cb, cbs) { + var ui = can.page.Append(can, target, [{view: ["item", "div", item.name], click: function(event) { + cb(event, ui.item) + }}]) + return ui.item.Meta = item, ui.item + }, + field: function(can, target, type, item) { + typeof item.help == "string" && item.help.startsWith("[") && (item.help = JSON.parse(item.help)) + + var dataset = {}; item && item.name && (dataset.names = item.name); + var field = can.page.Append(can, target, [{view: [(item.name||"")+" "+(type||"")+" "+(item.pos||""), "fieldset"], list: [ + item.pos? undefined: {text: [(item.nick||item.name||"")+"("+((typeof item.help == "string"? item.help: item.help.length > 0 && item.help[0])||"")+")", "legend"]}, + {view: ["option", "form"], dataset: dataset, list: []}, + {view: ["action"]}, {view: ["output"]}, {view: ["status"]}, + ]}]).first; + return field.Meta = item, field; + }, + input: function(can, option, type, item, cb) { + var input = {type: "input", name: item.name, data: item}; + item.action = item.action || item.value || ""; + item.figure = item.figure || item.value || ""; + item.cb = item.cb || item.value || ""; + item.name && item.name.indexOf("@") == 0 && (item.name = item.name.slice(1)) && (item.position = item.position || "opts") + + switch (item.type = item.type || item._type || item._input || "text") { + case "upfile": item.type = "file"; break + case "button": + item.value = item.name || item.value; + break + case "select": + item.values = typeof item.values == "string"? item.values.split(" "): item.values; + if (!item.values && item.value) { + item.values = item.value.split("|") + item.value = item.values[0] + } + input.type = "select", input.list = item.values.map(function(value) { + return {type: "option", value: value, inner: value}; + }) + item.className || can.page.ClassList.add(can, item, item.position||"args"); + break + case "textarea": + input.type = "textarea" + // no break + case "password": + // no break + case "text": + item.className || can.page.ClassList.add(can, item, item.position||"args"); + item.autocomplete = "off"; + break + } + + if (item.value == "auto") {item.value = ""} + item.figure && item.figure.indexOf("@") == 0 && (item.figure = item.figure.slice(1)) && can.require(["plugin/input/"+item.figure], function() { + target.type != "button" && (target.value = "") + }) + + var list = [], style = "" + switch (type) { + case "option": + list.push({text: item.name+": "}) + case "input": + style = " "+item.type + list.push(input) + break + } + var ui = can.page.Append(can, option, [{view: ["item"+style], list:list}]) + var target = ui[item.name] + if (!target) { return } + + item.type == "text" && !target.placeholder && (target.placeholder = item.name || ""); + item.type != "button" && !target.title && (target.title = item.placeholder || item.name || ""); + item.type == "textarea" && can.page.Append(can, option, [{type: "br"}]) + item.type == "select" && (target.value = item.value || item.values[item.index||0]) + item.type == "button" && item.action == "auto" && can.run && can.run({}); + return target; }, }, [], function(can) {}) -Volcanos("onremove", {}, [], function(can) {}) +Volcanos("onlayout", { + start: function(can, target, width, height) { + can.page.Select(can, target, "fieldset.head", function(field) { + height -= field.offsetHeight; + }) + can.page.Select(can, target, "fieldset.foot", function(field) { + height -= field.offsetHeight; + }) -Volcanos("onimport", {}, [], function(can) {}) -Volcanos("onexport", {}, [], function(can) {}) + can.page.Select(can, target, ["fieldset.left", "fieldset.middle", "fieldset.right"], function(field) { + var border = field.offsetHeight - field.clientHeight + can.page.Modify(can, field, {style: { + height: height-border*2+"px", + }}) + }) + can.page.Select(can, target, ["fieldset.left>div.output", "fieldset.middle>div.output", "fieldset.right>div.output"], function(field) { + var border = field.offsetHeight - field.clientHeight + can.page.Modify(can, field, {style: { + height: height-border*2-20+"px", + }}) + }) + }, +}) +Volcanos("onsearch", { + start: function(event, can, chain, cb) { + var sub, mod, fun = can, key; + can.core.List(chain.split("."), function(value, index, array) { + sub = mod, mod = fun, fun = mod[value], key = value + }) + if (!sub || !mod) { console.error("not found", chain); return } -Volcanos("onaction", {}, [], function(can) {}) -Volcanos("ondetail", {}, [], function(can) {}) + Volcanos.meta.debug["search"] && console.log("volcano", can._name, "search", chain, "match", sub._name+"."+mod._name) + typeof fun == "function" && fun(event, sub, key, function(value) { + Volcanos.meta.debug["search"] && console.log("volcano", can._name, "search", chain, "value", value) + cb(value) + }) + }, +}) diff --git a/demo/index.html b/demo/index.html index 657607a7..1477f81c 100644 --- a/demo/index.html +++ b/demo/index.html @@ -10,6 +10,7 @@ + diff --git a/demo/order.js b/demo/order.js index e20c2b9b..45ccb9df 100644 --- a/demo/order.js +++ b/demo/order.js @@ -1,17 +1,14 @@ -Volcanos("demo", { - _head: document.head, _body: document.body, _target: document.body, -}, ["lib/core.js", "lib/page.js", "frame.js"], function(can) { - can._body.style.background = "black" - can._body.style.color = "cyan" - console.log("", "demo", can); - - can.core.Next([ - {type: "item", name: "Header", help: "head", list: ["pane/Header.js", "pane/Header.css"]}, - {type: "item", name: "Footer", help: "foot", list: ["pane/Footer.js", "pane/Footer.css"]}, - ], function(item, next) { - can.onappend.init(can, item.type, item, item.list, function(sub) { - can[item.name] = sub, next() - }, can._target); - }) +var Config = { volcano: "frame.js", iceberg: "/chat/", intshell: "plug.sh", + libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"], panes: [ + {type: "pane", pos: "head", name: "Header", help: "标题栏", list: ["pane/Header.js", "pane/Header.css"], state: ["time"]}, + {type: "pane", pos: "left", name: "River", help: "群聊", list: ["frame.js", "pane/River.js", "pane/River.css"]}, + {type: "pane", pos: "right", name: "Storm", help: "应用", list: ["frame.js", "pane/Storm.js", "pane/Storm.css"]}, + {type: "pane", pos: "middle", name: "Action", help: "工作台", list: ["frame.js", "pane/Action.js", "pane/Action.css"]}, + {type: "pane", pos: "foot", name: "Footer", help: "状态栏", list: ["pane/Footer.js", "pane/Footer.css"]}, + ], +} +var Preload = []; Config.panes.forEach(function(pane) { + Preload = Preload.concat(pane.list); }) +Preload = Preload.concat(["plugin/input.js"]) diff --git a/demo/pane b/demo/pane deleted file mode 120000 index cabd17f1..00000000 --- a/demo/pane +++ /dev/null @@ -1 +0,0 @@ -../pane \ No newline at end of file diff --git a/demo/pane/Action.css b/demo/pane/Action.css new file mode 100644 index 00000000..24920f53 --- /dev/null +++ b/demo/pane/Action.css @@ -0,0 +1,10 @@ +fieldset.Action { + min-width:160px; + min-height:160px; + padding-left:10px; + padding-right:10px; +} +fieldset.Action>div.output>div.item:hover { + background-color:lightblue; +} + diff --git a/demo/pane/Action.js b/demo/pane/Action.js new file mode 100644 index 00000000..2e142ecd --- /dev/null +++ b/demo/pane/Action.js @@ -0,0 +1,27 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) { output.innerHTML = ""; + }, +}) +Volcanos("onexport", {help: "导出数据", list: [], + action: function(event, can, key, cb) { + can.run(event, ["search", "River.onexport.river"], function(river) { + can.run(event, ["search", "Storm.onexport.storm"], function(storm) { + can.Cache(can.Conf("river")+can.Conf("storm"), can._output, true) + if (can.Cache(can.Conf("river", river)+can.Conf("storm", storm), can._output)) { + // 缓存恢复 + return + } + + can.run(event, [river, storm], function(msg) { can._output.innerHTML = ""; msg.Table(function(value, index, array) { + can.onappend._init(can, value, Config.libs.concat([]), function(sub) { + sub.run = function(event, cmds, cb, silent) { + can.run(event, [river, storm, index].concat(cmds), cb, silent) + } + console.log("volcano", can._name, "plugin", sub._name) + }, can._output) + }) }) + }) + }) + }, +}) + diff --git a/demo/pane/Footer.css b/demo/pane/Footer.css new file mode 100644 index 00000000..307e3b3f --- /dev/null +++ b/demo/pane/Footer.css @@ -0,0 +1,19 @@ +fieldset.Footer { + height:32px; + clear:both; +} +fieldset.Footer>div { + margin:7px 0; +} +fieldset.Footer>div.output div.title { + margin-left:5px; + float:left; +} +fieldset.Footer>div.output div.state { + float:right; +} +fieldset.Footer>div.output div.state>div { + margin-right:5px; + float:right; +} + diff --git a/demo/pane/Footer.js b/demo/pane/Footer.js new file mode 100644 index 00000000..d728be10 --- /dev/null +++ b/demo/pane/Footer.js @@ -0,0 +1,26 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) {output.innerHTML = ""; + can.run({}, [], function(msg) { + console.log("volcano", "Footer", "display", msg.result) + can.core.List(msg.result, function(title) { + can.page.Append(can, output, [{view: ["title", "div", title]}]) + }) + + console.log("volcano", "Footer", "display", meta.state) + can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(meta.state, function(item) { + return {text: meta[item]||"", className: item, click: function(event) {can.Export(event, meta[item], item)}}; + })}]) + }) + }, + ntxt: function(event, can, value, cmd, field) {var state = can.Conf(cmd); + can.ui[cmd].innerHTML = cmd+":"+ can.Conf(cmd, can.base.Int(value)+can.base.Int(state)) + }, + ncmd: function(event, can, value, cmd, field) {var state = can.Conf(cmd); + can.ui && (can.ui[cmd].innerHTML = cmd+":"+ can.Conf(cmd, can.base.Int(value)+can.base.Int(state))) + }, +}) +Volcanos("onaction", {help: "组件交互", list: []}) +Volcanos("onchoice", {help: "组件菜单", list: []}) +Volcanos("ondetail", {help: "组件详情", list: []}) +Volcanos("onexport", {help: "导出数据", list: []}) + diff --git a/demo/pane/Header.css b/demo/pane/Header.css new file mode 100644 index 00000000..bb6b95ea --- /dev/null +++ b/demo/pane/Header.css @@ -0,0 +1,30 @@ +fieldset.Header { + height:32px; + clear:both; +} +fieldset.Header>div { + margin:7px 0; +} +fieldset.Header>div.output>div.title { + margin-left:5px; + cursor:pointer; + float:left; +} +fieldset.Header>div.output>div.title:hover { + background-color:red; + border:ridge 2px yellow; +} + +fieldset.Header>div.output>div.state { + margin-right:5px; + float:right; +} +fieldset.Header>div.output>div.state>div { + cursor:pointer; + margin-right:5px; + float:right; +} +fieldset.Header>div.output>div.state>div:hover { + background-color:red; +} + diff --git a/demo/pane/Header.js b/demo/pane/Header.js new file mode 100644 index 00000000..4c3723bc --- /dev/null +++ b/demo/pane/Header.js @@ -0,0 +1,25 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) { output.innerHTML = ""; + can.run({}, [], function(msg) { + console.log("volcano", "Header", "display", msg.result) + can.core.List(msg.result, function(title) { + can.page.Append(can, output, [{view: ["title", "div", title], + click: function(event) {can.Export(event, meta.title, "title")}, + }]) + }) + + console.log("volcano", "Header", "display", meta.state) + can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(meta.state, function(item) { + return {text: meta[item]||"", className: item, click: function(event) {can.Export(event, meta[item], item)}}; + })}]) + + can.timer = can.Timer({interval: 1000, length: -1}, function(event) { + can.onimport.time(event, can, can.base.Time().split(" ")[1], "time") + }) + }) + return + }, + time: function(event, can, value, cmd, field) { + can.ui[cmd].innerHTML = value + }, +}) diff --git a/demo/pane/River.css b/demo/pane/River.css new file mode 100644 index 00000000..49111b54 --- /dev/null +++ b/demo/pane/River.css @@ -0,0 +1,19 @@ +fieldset.River { + min-width:80px; + min-height:160px; + float:left; +} +fieldset.River>div.output { + padding:0; +} +fieldset.River>div.output>div.item { + padding-left:6px; +} +fieldset.River>div.output>div.item:hover { + background-color:red; + border:ridge 2px yellow; +} +fieldset.River>div.output>div.item.select { + background-color:red; + border:ridge 2px yellow; +} diff --git a/demo/pane/River.js b/demo/pane/River.js new file mode 100644 index 00000000..44d5eece --- /dev/null +++ b/demo/pane/River.js @@ -0,0 +1,31 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) { output.innerHTML = ""; + }, +}) +Volcanos("onexport", {help: "导出数据", list: [], + river: function(event, can, key, cb) { + if (can.Conf(key)) { cb(can.Conf(key)); return } + + can.run({}, [], function(msg) { msg.Table(function(value, index, array) { + // 添加列表 + var view = can.onappend.item(can, can._output, "item", value, function(event, item) { + // 左键点击 + can.page.Select(can, can._output, "div.item", function(item) { + can.page.ClassList.del(can, item, "select"); + }); can.page.ClassList.add(can, item, "select"); + + can.Conf(key, value.key); can.run({}, ["search", "Action.onexport.action"], function(action) { + // 切换群组 + }) + }, function(event) { + // 右键点击 + + }); + + if (index == 0 || [value.key, value.name].indexOf(can.user.Search(can, key)) > -1) { + view.click() + } + }); cb(can.Conf(key)); }) + }, +}) + diff --git a/demo/pane/Storm.css b/demo/pane/Storm.css new file mode 100644 index 00000000..df64ac18 --- /dev/null +++ b/demo/pane/Storm.css @@ -0,0 +1,21 @@ +fieldset.Storm { + min-width:80px; + min-height:160px; + float:right; +} +fieldset.Storm>div.output { + padding:0; +} +fieldset.Storm>div.output>div.item { + padding-left:6px; +} +fieldset.Storm>div.output>div.item:hover { + cursor:pointer; + background-color:red; + border:ridge 2px yellow; +} +fieldset.Storm>div.output>div.item.select { + background-color:red; + border:ridge 2px yellow; +} + diff --git a/demo/pane/Storm.js b/demo/pane/Storm.js new file mode 100644 index 00000000..524a348c --- /dev/null +++ b/demo/pane/Storm.js @@ -0,0 +1,42 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) { output.innerHTML = ""; + }, +}) +Volcanos("onexport", {help: "导出数据", list: [], + storm: function(event, can, key, cb) { + can.run({}, ["search", "River.onexport.river"], function(river) { + if (river == can.Conf("river")) { + cb(can.Conf(key)) + return //当前应用 + } + + can.Cache(can.Conf("river"), can._output, can.Conf(key)) + if (can.Conf(key, can.Cache(can.Conf("river", river), can._output))) { + cb(can.Conf(key)) + return // 缓存恢复 + } + + can.run({}, [river], function(msg) { msg.Table(function(value, index, array) { + // 添加列表 + var view = can.onappend.item(can, can._output, "item", value, function(event, item) { + // 左键点击 + can.page.Select(can, can._output, "div.item", function(item) { + can.page.ClassList.del(can, item, "select"); + }); can.page.ClassList.add(can, item, "select"); + + can.Conf(key, value.key); can.run({}, ["search", "Action.onexport.action"], function(action) { + // 切换应用 + }) + }, function(event) { + // 右键点击 + + }); + if (index == 0 || [value.key, value.name].indexOf(can.user.Search(can, key)) > -1) { + view.click() + } + }); cb(can.Conf(key)); }) + }) + }, +}) + + diff --git a/demo/plugin/input.js b/demo/plugin/input.js new file mode 100644 index 00000000..f2717c78 --- /dev/null +++ b/demo/plugin/input.js @@ -0,0 +1,29 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, meta, list, cb, output, action, option, field) { output.innerHTML = ""; + }, +}) +Volcanos("onaction", {help: "控件交互", list: [], + onclick: function(event, can) { + switch (can.Conf("type")) { + case "button": + can.run(event, [], function() {}) + break + } + }, + onkeydown: function(event, can) { + switch (event.key) { + case "Enter": + can.run(event, [], function() {}) + break + } + }, + onkeyup: function(event, can) { + switch (event.key) { + case "Enter": + can.run(event, [], function() {}) + break + } + }, +}) + + diff --git a/demo/plugin/state.js b/demo/plugin/state.js new file mode 100644 index 00000000..f909207a --- /dev/null +++ b/demo/plugin/state.js @@ -0,0 +1,41 @@ +Volcanos("onimport", {help: "导入数据", list: []}) +Volcanos("onaction", {help: "组件交互", list: []}) +Volcanos("onchoice", {help: "组件菜单", list: ["执行", "返回", "共享", "重命名", "选项", "加参", "减参", "克隆", "删除"], + "执行": function(event, can, msg, cmd, field) {can.Runs(event)}, + "返回": function(event, can, msg, cmd, field) {can.Last(event)}, + "共享": function(event, can, msg, cmd, field) { + can.user.input(event, can, ["name", "text"], function(event, cmd, meta, list) { + var msg = can.Event(event); + msg.Option("name", meta.name) + msg.Option("text", meta.text) + can.Conf("args", JSON.stringify(can.Option())) + can.core.List(["node", "group", "index", "args"], function(key) { + msg.Option(key, can.Conf(key)) + }) + can.Export(event, "action", "share") + return true + }) + }, + "重命名": function(event, can, msg, cmd, field) {var meta = field.Meta; + meta.help = can.user.prompt("", function(help) { + meta.help = help + }, meta.help) + }, + "选项": function(event, can, msg, cmd, field) { + can.user.input(event, can, ["name", "value"], function(event, cmd, meta, list) { + var data = {type: "text", value: meta.value||""} + can.page.ClassList.add(can, data, "opts"); + + var input = {type: "input", name: meta.name, data: data}; + var target = can.Dream(can.option, "option", input)[input.name]; + return true + }) + }, + "加参": function(event, can, msg, cmd, field) {can.Append()}, + "减参": function(event, can, msg, cmd, field) {can.Remove(event)}, + "克隆": function(event, can, msg, cmd, field) {can.Clone(event)}, + "删除": function(event, can, msg, cmd, field) {can.Delete(event)}, +}) +Volcanos("ondetail", {help: "组件详情", list: []}) +Volcanos("onexport", {help: "导出数据", list: []}) + diff --git a/demo/plugin/table.js b/demo/plugin/table.js new file mode 100644 index 00000000..05a9ecc6 --- /dev/null +++ b/demo/plugin/table.js @@ -0,0 +1,21 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, msg, list, cb, output, action, option, field) { output.innerHTML = ""; + var table = can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) { + can.page.Select(can, option, "input.args", function(input) { if (input.name == key) { + input.value = value + } }) + + }, function(event, value, key, index, tr, td) { + }); + + msg.result && can.page.AppendBoard(can, output, msg.result.join("")) + }, +}) +Volcanos("onaction", {help: "控件交互", list: [], + onclick: function(event, can) { + can.run(event, [], function() {}) + }, +}) + + + diff --git a/demo/proto.js b/demo/proto.js index b682d078..fcb682c1 100644 --- a/demo/proto.js +++ b/demo/proto.js @@ -2,8 +2,7 @@ // FMS: a fieldset manager system function shy(help, meta, list, cb) { - var index = -1, value = "", type = "string", args = arguments; - function next(check) { + var index = -1, value = "", type = "string", args = arguments; function next(check) { if (++index >= args.length) {return false} if (check && check != typeof args[index]) {index--; return false} return value = args[index], type = typeof value, value; @@ -12,69 +11,145 @@ function shy(help, meta, list, cb) { var cb = arguments[arguments.length-1] || function() {}; cb.help = next("string") || "还没有写"; cb.meta = next("object") || {}; - cb.list = next("object") || {}; - cb.runs = function() {}; + cb.list = next("object") || []; return cb; } -function Volcanos(name, can, libs, cb) { - // 全局缓存 - var list = arguments.callee.list || [], meta = arguments.callee.meta || {index: 1, cache: {}}; - arguments.callee.list = list, arguments.callee.meta = meta; +var Volcanos = shy("火山架", {cache: {}, index: 1, order: 1, debug: { + volcano: false, config: true, + require: true, cache: false, frame: false, + request: true, search: true, +}}, [], function(name, can, libs, cb) { + var meta = arguments.callee.meta, list = arguments.callee.list; - // 定义原型 - can = can || {}, list.push(can) && (can.__proto__ = {_name: name, _load: function(name) { - if (meta.cache[name]) {var cache = meta.cache[name]; + var conf = {}, conf_cb = {}, sync = {}, cache = {}; + meta.debug["volcano"] && console.debug("volcano", name, "create"); + can = can || {}, list.push(can) && (can.__proto__ = { _name: name, _create_time: new Date(), _load: function(name) { + for (var cache = meta.cache[name] || []; meta.index < list.length; meta.index++) { + if (list[meta.index] == can) {continue} + meta.debug["cache"] && console.debug("cache", name, "load", meta.index, list[meta.index]); + cache.push(list[meta.index]); + // 加载缓存 + } + + for (var i = 0; i < cache.length; i++) { + meta.debug["frame"] && console.debug("frame", can._name, "load", i, cache[i]); + can[cache[i]._name] = cache[i]; // 加载索引 - for (var i = 0; i < cache.length; i++) {var sub = cache[i]; - can[sub._name] = sub; - } - return can } - - // 加载缓存 - meta.cache[name] = [] - for (var i = meta.index; i < list.length; i++) {var sub = list[i]; - can[sub._name] = sub; - meta.cache[name].push(sub); - } - meta.index = i; - return can + meta.cache[name] = cache; }, - require: function(libs, cb) { - if (!libs || libs.length == 0) { - // 加载完成 + require: function(libs, cb) { if (!libs || libs.length == 0) { typeof cb == "function" && setTimeout(function() {cb(can)}, 10); + return // 加载完成 + } - } else if (can[libs[0]]) { - // 已经加载 - can.require(libs.slice(1), cb) + meta.debug["require"] && console.debug("volcano", can._name, "require", libs[0]); if (meta.cache[libs[0]]) { + can._load(libs[0]), can.require(libs.slice(1), cb); + return // 缓存加载 + } - } else if (meta.cache[libs[0]]) { - // 缓存加载 - can._load(libs[0]), can.require(libs.slice(1), cb) + var target = libs[0].endsWith(".css")? (can._head||document.head): (can._body||document.body); + var source = !libs[0].endsWith("/") && (libs[0].indexOf(".") == -1? libs[0]+".js": libs[0]) || libs[0]; - } else { - // 加载脚本 - var target = libs[0].endsWith(".css")? (can._head||document.head): (can._body||document.body); - var source = !libs[0].endsWith("/") && (libs[0].indexOf(".") == -1? libs[0]+".js": libs[0]) || libs[0] + if (source.endsWith(".js")) { var script = document.createElement("script"); + script.src = source, script.onload = function() { + // meta.debug["require"] && console.debug("volcano", can._name, "required", libs[0]); + can._load(libs[0]), can.require(libs.slice(1), cb); + } // 加载脚本 + target.appendChild(script); - if (source.endsWith(".js")) { var script = document.createElement("script"); - script.src = source, script.onload = function() { - can._load(libs[0]), can.require(libs.slice(1), cb); - } - target.appendChild(script); - - } else if (source.endsWith(".css")) { var style = document.createElement("link"); - style.rel = "stylesheet", style.type = "text/css"; - style.href = source; style.onload = function() { - can._load(libs[0]), can.require(libs.slice(1), cb); - }; - target.appendChild(style); - } + } else if (source.endsWith(".css")) { var style = document.createElement("link"); + style.rel = "stylesheet", style.type = "text/css"; + style.href = source; style.onload = function() { + // meta.debug["require"] && console.debug("volcano", can._name, "required", libs[0]); + can._load(libs[0]), can.require(libs.slice(1), cb); + } // 加载样式 + target.appendChild(style); } }, + request: function(event, msg, proto) { event = event || {}; + if (!msg && event.msg) { return event.msg } + + event.msg = msg = msg || {}, msg.event = event; + msg.__proto__ = proto || { _name: meta.order++, _create_time: new Date(), + Option: function(key, val) { + if (val == undefined) { return msg && msg[key] && msg[key][0] || "" } + msg.option = msg.option || [], can.core.List(msg.option, function(k) { + if (k == key) {return k} + }).length > 0 || msg.option.push(key) + msg[key] = can.core.List(arguments).slice(1) + }, + Copy: function(res) { if (!res) { return msg } + res.result && (msg.result = res.result) + res.append && (msg.append = res.append) && res.append.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 + }, + Table: shy("遍历数据", function(cb) { if (!msg.append || !msg.append.length || !msg[msg.append[0]]) { return } + var max = "", len = 0; can.core.List(msg.append, function(key, index) { + if (msg[key].length > len) { max = key, len = msg[key].length } + }); + + return can.core.List(msg[max], function(value, index, array) { var one = {}, res; + can.core.List(msg.append, function(key) { one[key] = msg[key][index]||"" }) + return typeof cb == "function" && (res = cb(one, index, array)) && res != undefined && res || one + }) + }), + } + return msg + }, + + Conf: function(key, value, cb) { if (key == undefined) { return conf } + if (typeof key == "object") { conf = key; return conf } + typeof cb == "function" && (conf_cb[key] = cb); + if (value != undefined) {var old = conf[key], res; meta.debug["config"] && console.debug("volcano", can._name, "config", key, value, old) + conf[key] = conf_cb[key] && (res = conf_cb[key](value, old, key)) != undefined && res || value + } + return conf[key] || "" + }, + Timer: shy("定时器, value, [1,2,3,4], {value, length}", function(interval, cb, cbs) { interval = typeof interval == "object"? interval || []: [interval]; + var timer = {stop: false}; + function loop(event, i) {if (timer.stop || i >= interval.length && interval.length >= 0) {return typeof cbs == "function" && cbs(event, interval)} + return typeof cb == "function" && cb(event, interval.value||interval[i], i, interval)? + typeof cbs == "function" && cbs(event, interval): + setTimeout(function() {loop(event, i+1)}, interval.value||interval[i+1]); + } + setTimeout(function(event) {loop(event, 0)}, interval.value||interval[0]); + return timer; + }), + Cache: shy("缓存器", function(name, output, data) { + 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); + } + + cache[name] = {node: temp, data: data} + console.log("volcano", can._name, "save", name, cache[name]); + return name + } + + var list = cache[name]; + if (!list) {return} + console.log("volcano", can._name, "load", name, cache[name]); + + // 读缓存 + while (list.node.childNodes.length>0) { + var item = list.node.childNodes[0]; + item.parentNode.removeChild(item); + output.appendChild(item); + } + delete(cache[name]); + return list.data; + }), }); return can.require(libs, cb), can -} - +}) diff --git a/demo/start.js b/demo/start.js new file mode 100644 index 00000000..85112dfa --- /dev/null +++ b/demo/start.js @@ -0,0 +1,29 @@ +Volcanos("demo", { _head: document.head, _body: document.body, _target: document.body, +}, [Config.volcano].concat(Config.libs).concat(Preload), function(can) { can.Conf(Config); can.core.Next(can.Conf("panes"), function(item, next) { + can.onappend._init(can, item, Config.libs.concat(item.list), function(sub) { + sub.run = function(event, cmds, cb, silent) { var msg = sub.request(event); + switch (cmds[0]) { + case "search": + can.onsearch.start(event, can, cmds[1], cb) + return + } + + // 发送请求 + Volcanos.meta.debug["request"] && console.log("volcano", sub._name, "request", msg._name, cmds, msg); + can.misc.Run(event, can, {names: item.name}, cmds, function(msg) { + // 接收响应 + Volcanos.meta.debug["request"] && console.log("volcano", sub._name, "response", msg._name, msg.result, msg); + cb(msg); + }) + } + can[item.name] = sub, next() + }, can._target); + }, function() { + // 启动入口 + can.onlayout.start(can, can._target, window.innerWidth, window.innerHeight); + console.log("volcano", "demo", "start", can); + can.Action.onexport.action({}, can.Action, function() { + }) + }) +}) + diff --git a/demo/style.css b/demo/style.css index a0534f7f..aceec56f 100644 --- a/demo/style.css +++ b/demo/style.css @@ -1,2 +1,156 @@ * { + background:black; } +body { + padding:0; + margin:0; +} +fieldset { + color:cyan; + padding:2px; + margin:0px; +} +legend { + margin-left:10px; +} + +fieldset>form.option { + padding:0 5px; +} +fieldset>form.option>br { + clear:both; +} +fieldset>form.option>div.item { + margin-right:3px; + float:left; +} +fieldset>form.option>div.item label { + margin-right:3px; +} +fieldset>form.option>div.item input.args.char { + width:20px; +} +fieldset>form.option>div.item input.args.tiny { + width:40px; +} +fieldset>form.option>div.item input.args { + width:80px; +} +fieldset>form.option>div.item input.args.cmd { + background-color:black; + color:white; + width:160px; +} +fieldset>form.option>div.item input.args.long { + width:240px; +} +fieldset>form.option>div.item input.args.full { + width:480px; +} +fieldset>form.option>div.item input.opts { + width:80px; +} +fieldset>form.option>div.item textarea.args { + width:300px; + height:50px; + background-color:cyan; +} + +fieldset>form.option>div.item.text>input { + background-color:cyan; +} +fieldset>form.option>div.item.button>input { + color:cyan; +} +fieldset>form.option>div.item.select>select { + color:cyan; +} +fieldset>form.option>div.item.textarea { + margin-top:4px; + clear:both; +} + +fieldset.Action>div.output { + overflow:auto; +} +fieldset>div.output { + margin-top:4px; + clear:both; + overflow:auto; +} + +fieldset table { + font-size:14px; + overflow: auto; +} +fieldset table caption { + font-size:18px; + font-style:italic; + border:solid 1px green; +} +fieldset table tbody { + overflow:auto; +} +fieldset table td sup.more { + color:red; +} + +fieldset table { + border:solid 1px green; + cursor:pointer; +} +fieldset table tr:hover { + background-color:#0fbd45; +} +fieldset table tr.over { + background:red; +} +fieldset table tr.select { + background-color:#0fbd45; +} +fieldset table th { + font-family:monospace; + background-color:#0fbd45; + cursor:pointer; + padding: 0 6px; +} +fieldset table td { + max-width:1200px; + font-family:monospace; + padding: 0 6px; + white-space: pre; +} +fieldset table td:hover { + background-color:red; +} +fieldset table td.select { + background-color:red; +} + +fieldset div.code { + color:white; + font-size:14px; + font-family:monospace; + background-color:#343a34f2; + white-space:pre; + padding:10px; + overflow:auto; + border:solid 3px green; + max-height:640px; +} +fieldset div.hidden { + display:none; +} + +fieldset div.code { + color:white; + font-size:14px; + font-family:monospace; + background-color:#343a34f2; + white-space:pre; + padding:10px; + overflow:auto; + border:solid 3px green; + max-height:640px; +} + diff --git a/frame_old.js b/frame_old.js index 46f1596e..a528f3de 100644 --- a/frame_old.js +++ b/frame_old.js @@ -129,7 +129,11 @@ var can = Volcanos("chat", { return msg }, }, Config.libs.concat(["pane/"+(meta.path||"")+name]), function(pane) {can.Dream(document.head, "pane/"+(meta.path||"")+name+".css") - pane.onimport._init && pane.onimport._init(pane, pane.Conf(meta), pane.output, pane.action, pane.option, field) + if (["Header", "Footer"].indexOf(meta.name) > -1) { + pane.onimport._init && pane.onimport._init(pane, pane.Conf(meta), [], function() {}, pane.output, pane.action, pane.option, field) + } else { + pane.onimport._init && pane.onimport._init(pane, pane.Conf(meta), pane.output, pane.action, pane.option, field) + } typeof cb == "function" && cb(pane) }, meta) return pane diff --git a/lib/misc.js b/lib/misc.js index 2510194f..257ff778 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -48,7 +48,7 @@ Volcanos("misc", {help: "工具模块", msg._xhr = xhr }), Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmd, cb) { - var msg = can.Event(event); + var msg = (can.request||can.Event)(event); // 解析参数 var option = {"cmds": cmd||msg.cmd} diff --git a/lib/page.js b/lib/page.js index 1a7aa2d0..12915030 100644 --- a/lib/page.js +++ b/lib/page.js @@ -23,6 +23,9 @@ Volcanos("page", {help: "网页模块", Select: shy("选择节点", function(can, obj, key, cb, interval, cbs) {if (key == ".") {return []} var item = obj && obj.querySelectorAll(key); + // can.core.List(key, function(key) { + // item = item.concat(obj.querySelectorAll(key)); + // }) return can.core.List(item, cb, interval, cbs); }), Modify: shy("修改节点", function(can, target, value) { diff --git a/pane/Footer.js b/pane/Footer.js index 4a6046c4..c60e58b1 100644 --- a/pane/Footer.js +++ b/pane/Footer.js @@ -1,13 +1,13 @@ Volcanos("onimport", {help: "导入数据", list: [], - _init: function(can, conf, output, action, option, field) {output.innerHTML = ""; + _init: function(can, meta, list, cb, output, action, option, field) {output.innerHTML = ""; can._init = function() { can.run({}, [], function(msg) { can.core.List(msg.result, function(title) { can.page.Append(can, output, [{view: "title", list: [{text: title, className: "title"}]}]) }) - can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(conf.state, function(item) { - return {text: conf[item]||"", className: item, click: function(event) {can.Export(event, conf[item], item)}}; + can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(meta.state, function(item) { + return {text: meta[item]||"", className: item, click: function(event) {can.Export(event, meta[item], item)}}; })}]) }) } diff --git a/pane/Header.js b/pane/Header.js index a193deeb..79a2d94b 100644 --- a/pane/Header.js +++ b/pane/Header.js @@ -1,15 +1,15 @@ Volcanos("onimport", {help: "导入数据", list: [], - _init: function(can, conf, output, action, option, field) {output.innerHTML = ""; + _init: function(can, meta, list, cb, output, action, option, field) {output.innerHTML = ""; can._init = function() { can.run({}, [], function(msg) { can.core.List(msg.result, function(title) { can.page.Append(can, output, [{view: "title", list: [{text: title, className: "title"}], - click: function(event) {can.Export(event, conf.title, "title")}, + click: function(event) {can.Export(event, meta.title, "title")}, }]) }) - can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(conf.state, function(item) { - return {text: conf[item]||"", className: item, click: function(event) {can.Export(event, conf[item], item)}}; + can.ui = can.page.Append(can, output, [{view: "state", list: can.core.List(meta.state, function(item) { + return {text: meta[item]||"", className: item, click: function(event) {can.Export(event, meta[item], item)}}; })}]) can.timer = can.Timer({interval: 1000, length: -1}, function(event) { diff --git a/pane/Storm.js b/pane/Storm.js index 44257535..f23ab8ea 100644 --- a/pane/Storm.js +++ b/pane/Storm.js @@ -84,5 +84,6 @@ Volcanos("ondetail", {help: "组件详情", list: ["共享", "重命名", "删 }) }, }) -Volcanos("onexport", {help: "导出数据", list: []}) +Volcanos("onexport", {help: "导出数据", list: [], +}) diff --git a/style.css b/style.css new file mode 100644 index 00000000..e69de29b