1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 16:58:06 +08:00
This commit is contained in:
shylinux 2020-02-26 02:00:01 +08:00
parent 8695a556f9
commit 36abc32595
19 changed files with 1161 additions and 701 deletions

View File

@ -62,7 +62,7 @@ var can = Volcanos("chat", {
// 导入数据 // 导入数据
typeof cb == "function" && cb(event, pane, value, key, field); typeof cb == "function" && cb(event, pane, value, key, field);
// 分发数据 // 分发数据
// can.core.List(pane._plugins, function(item) {item.Import(event, value, key)}) can.core.List(pane._plugins, function(item) {item.Import(event, value, key)})
// 显示数据 // 显示数据
pane.page.Select(pane, pane.action, "input."+key, function(item) {item.value = value}) pane.page.Select(pane, pane.action, "input."+key, function(item) {item.value = value})
}, },
@ -146,7 +146,7 @@ var can = Volcanos("chat", {
var exports = JSON.parse(meta.exports||'""')||feature.exports||[]; var exports = JSON.parse(meta.exports||'""')||feature.exports||[];
var plugin = Volcanos(name, {_type: "local", _local: {}, target: field, var plugin = Volcanos(name, {_type: "local", _local: {}, target: field,
option: option, action: action, output: output, option: option, action: action, output: output,
Inputs: can.Inputs, Output: can.Output, Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Export: function(event, value, key) {var cb = plugin.onexport[key]; Export: function(event, value, key) {var cb = plugin.onexport[key];
typeof cb == "function"? cb(event, plugin, value, key, field): can.Export(event, value, key) typeof cb == "function"? cb(event, plugin, value, key, field): can.Export(event, value, key)
@ -156,6 +156,8 @@ var can = Volcanos("chat", {
typeof cb == "function" && cb(event, plugin, value, key, plugin.output); typeof cb == "function" && cb(event, plugin, value, key, plugin.output);
// 下发数据 // 下发数据
key && plugin[key] && plugin[key].target && plugin[key].Import(event, value, key) key && plugin[key] && plugin[key].target && plugin[key].Import(event, value, key)
// 下发数据
plugin._output && plugin._output.Import(event, value, key)
}, },
Report: function(event, value, key, index) { Report: function(event, value, key, index) {
// 导入数据 // 导入数据
@ -168,7 +170,8 @@ var can = Volcanos("chat", {
value = typeof cb == "function" && ((res = cb(event, plugin, plugin.msg, value, key, index)) != undefined) && res || value; value = typeof cb == "function" && ((res = cb(event, plugin, plugin.msg, value, key, index)) != undefined) && res || value;
} }
// 上报数据 // 上报数据
key && can.Import(event, value, key) // 上下循环
// key && can.Import(event, value, key)
} }
} }
}, },
@ -240,7 +243,7 @@ var can = Volcanos("chat", {
}, },
Delete: function(event) {field.parentNode.removeChild(field)}, Delete: function(event) {field.parentNode.removeChild(field)},
}, Config.libs.concat(["plugin/"+(meta.type||feature.active||"state")]), function(plugin) {plugin.Conf(meta); }, Config.libs.concat(["plugin/"+(meta.type||feature.active||"state")]), function(plugin) {plugin.Conf(meta);
var list = JSON.parse(meta.inputs||"[]"); var list = typeof meta.inputs == "string"? JSON.parse(meta.inputs||"[]"): meta.inputs;
// 加载配置 // 加载配置
plugin.onimport._init? plugin.onimport._init(plugin, feature, plugin.output, plugin.action, plugin.option): plugin.onimport._init? plugin.onimport._init(plugin, feature, plugin.output, plugin.action, plugin.option):
// 加载控件 // 加载控件
@ -278,6 +281,7 @@ var can = Volcanos("chat", {
Output: shy("构造组件", function(can, feature, type, msg, cb, target, action, option, status) { Output: shy("构造组件", function(can, feature, type, msg, cb, target, action, option, status) {
var output = Volcanos(type, {_type: "output", feature: feature, msg: msg, var output = Volcanos(type, {_type: "output", feature: feature, msg: msg,
target: target, action: action, target: target, action: action,
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Run: can.Run, Runs: can.Runs, Run: can.Run, Runs: can.Runs,
Import: function(event, value, key) {var cb = output.onimport && output.onimport[key]; Import: function(event, value, key) {var cb = output.onimport && output.onimport[key];
@ -290,12 +294,12 @@ var can = Volcanos("chat", {
}), value) }), value)
}, },
Action: function(key, value) { Action: function(key, value) {
return can.page.Select(can, can.action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) { return can.page.Select(can, action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) {
value != undefined && (item.value = value), value = item.value value != undefined && (item.value = value), value = item.value
}), value }), value
}, },
Status: function(event, value, key) {var cb = output.onstatus[key]; Status: function(event, value, key) {var cb = output.onstatus[key];
typeof cb == "function"? cb(event, output, value, key, can.page.Select(can, status, "div."+key)[0]): false && output.run(event, ["status", key, value], function(msg) { typeof cb == "function"? cb(event, output, value, key, can.page.Select(can, status, "div."+key)[0]||{}): false && output.run(event, ["status", key, value], function(msg) {
output.Export(event, msg, key) output.Export(event, msg, key)
}, true) }, true)
}, },
@ -311,7 +315,9 @@ var can = Volcanos("chat", {
}, },
}, Config.libs.concat([(type.startsWith("/")? "": "plugin/")+type]), function(output) { }, Config.libs.concat([(type.startsWith("/")? "": "plugin/")+type]), function(output) {
status.innerHTML = "", output.onstatus && can.page.AppendStatus(output, status, output.onstatus.list) status.innerHTML = "", output.onstatus && can.page.AppendStatus(output, status, output.onstatus.list)
output.onimport.Action = output.Action
output.onimport.init(output, msg, cb, target, action, option); output.onimport.init(output, msg, cb, target, action, option);
output.onfigure && (output.onfigure.sup = output, output.onfigure.target = target)
}, msg) }, msg)
return output return output
}), }),
@ -319,8 +325,8 @@ var can = Volcanos("chat", {
can.user.Search(can, "sessid") && can.user.Cookie(can, "sessid", can.user.Search(can, "sessid")) && can.user.Search(can, "sessid", "") can.user.Search(can, "sessid") && can.user.Cookie(can, "sessid", can.user.Search(can, "sessid")) && can.user.Search(can, "sessid", "")
can[Config.main] = can.Page(can, Config.main, Config, function(chat) { can[Config.main] = can.Page(can, Config.main, Config, function(chat) {
chat.Import({}, can.user.Search(can, "layout")||Config.layout.def, "layout")
chat.Import({}, can.user.Search(can, "you")||can.user.Search(can, "title")||Config.title, "title") chat.Import({}, can.user.Search(can, "you")||can.user.Search(can, "title")||Config.title, "title")
chat.Import({}, can.user.Search(can, "layout")||Config.layout.def, "layout")
chat.Import({}, "", "login") chat.Import({}, "", "login")
}, document.body, can.user.Search(can, "topic")||Config.topic) }, document.body, can.user.Search(can, "topic")||Config.topic)
}) })

View File

@ -10,6 +10,7 @@ Volcanos("base", {help: "基础模块",
}, },
Int: function(value) {return parseInt(value)||0}, Int: function(value) {return parseInt(value)||0},
Duration: function(n) {var res = "", h = 0; Duration: function(n) {var res = "", h = 0;
h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24);
h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000; h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000;
h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000; h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000;
h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000; h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000;

View File

@ -53,6 +53,13 @@ Volcanos("core", {help: "核心模块",
} }
next(obj, cb) next(obj, cb)
}), }),
Trim: shy("迭代器", function(obj) {
for (var i = obj.length; i >= 0; i--) {
if (obj[i]) {break}
obj = obj.slice(0, i)
}
return obj
}),
Split: shy("分词器", function(str, sep) { Split: shy("分词器", function(str, sep) {
return str.trim().split(sep||" ") return str.trim().split(sep||" ")

View File

@ -16,6 +16,9 @@ Volcanos("page", {help: "网页模块",
return list.indexOf(value) == -1? value: undefined; return list.indexOf(value) == -1? value: undefined;
}).join(" ").trim(); }).join(" ").trim();
}, },
neg: function(can, obj, key) {
this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)
},
}, },
Select: shy("选择节点", function(can, obj, key, cb, interval, cbs) { Select: shy("选择节点", function(can, obj, key, cb, interval, cbs) {
@ -214,7 +217,10 @@ Volcanos("page", {help: "网页模块",
can.page.Append(can, table, can.core.List(msg.Table(), function(line, index) { can.page.Append(can, table, can.core.List(msg.Table(), function(line, index) {
return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) {var cbcb, cbcbs; return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) {var cbcb, cbcbs;
typeof cb == "function" && (cbcb = function(event) {cb(event, line[key], key, index, event.target.parentNode, event.target)}); typeof cb == "function" && (cbcb = function(event) {cb(event, line[key], key, index, event.target.parentNode, event.target)});
typeof cbs == "function" && (cbcbs = function(event) {cbs(event, line[key], key, index, event.target.parentNode, event.target)}); typeof cbs == "function" && (cbcbs = function(event) {
cbs(event, line[key], key, index, event.target.parentNode, event.target);
event.stopPropagation(), event.preventDefault();
});
return {type: "td", inner: can.page.Display(line[key]), click: cbcb, oncontextmenu: cbcbs}; return {type: "td", inner: can.page.Display(line[key]), click: cbcb, oncontextmenu: cbcbs};
})} })}
})) }))
@ -238,17 +244,24 @@ Volcanos("page", {help: "网页模块",
is_number? parseInt(text): text is_number? parseInt(text): text
}) })
// 选择排序
for (var i = 0; i < num_list.length; i++) { for (var i = 0; i < num_list.length; i++) {
var min = i;
for (var j = i+1; j < num_list.length; j++) { for (var j = i+1; j < num_list.length; j++) {
if (sort_asc? num_list[i] < num_list[j]: num_list[i] > num_list[j]) { if (sort_asc? num_list[min] <= num_list[j]: num_list[min] >= num_list[j]) {
min = j
}
}
if (min != i) {
var temp = num_list[i] var temp = num_list[i]
num_list[i] = num_list[j] num_list[i] = num_list[min]
num_list[j] = temp num_list[min] = temp
var temp = list[i] var temp = list[i]
list[i] = list[j] list[i] = list[min]
list[j] = temp list[min] = temp
}
} }
var tbody = list[i].parentElement var tbody = list[i].parentElement
list[i].parentElement && tbody.removeChild(list[i]) list[i].parentElement && tbody.removeChild(list[i])
tbody.appendChild(list[i]) tbody.appendChild(list[i])
@ -397,9 +410,10 @@ Volcanos("page", {help: "网页模块",
return true return true
}, },
Prepos: function(event, item) { Prepos: function(event, item, p) {
p = p || item.getBoundingClientRect();
var pos = 1; var pos = 1;
var p = item.getBoundingClientRect();
var y = (event.clientY - p.y) / p.height var y = (event.clientY - p.y) / p.height
if (y < 0.2) { if (y < 0.2) {
pos += 0; pos += 0;
@ -464,5 +478,44 @@ Volcanos("page", {help: "网页模块",
break break
} }
}, },
Resizes: function(event, item, begin, p0, p1, pos) {
switch (pos) {
case 5:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("y", begin.y + p1.y - p0.y)
return
}
switch (pos) {
case 1:
case 2:
case 3:
item.Value("y", begin.y + p1.y - p0.y)
item.Value("height", begin.height - p1.y + p0.y)
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.Value("x", begin.x + p1.x - p0.x)
item.Value("width", begin.width - p1.x + p0.x)
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.Value("width", begin.width + p1.x - p0.x)
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.Value("height", begin.height + p1.y - p0.y)
break
}
},
}) })

View File

@ -6,7 +6,6 @@ fieldset.item {
border:ridge 1px cyan; border:ridge 1px cyan;
margin:2px; margin:2px;
} }
fieldset.item:hover { fieldset.item:hover {
/* background-color:gold; */ /* background-color:gold; */
border:ridge 2px red; border:ridge 2px red;
@ -16,7 +15,23 @@ fieldset.item.select {
border:ridge 2px red; border:ridge 2px red;
} }
fieldset.dialog { fieldset.input {
border:solid 2px yellow;
}
fieldset.input table tr:hover {
background-color:yellow;
}
fieldset.input table td:hover {
background-color:red;
cursor:pointer;
}
fieldset.input table td.select {
background-color:red;
}
fieldset.story {
border:ridge 1px cyan;
margin:2px;
} }
fieldset input { fieldset input {
@ -34,6 +49,9 @@ fieldset input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
fieldset table tr:hover { fieldset table tr:hover {
background-color:#0fbd45; background-color:#0fbd45;
} }
fieldset table tr.over {
background:red;
}
fieldset table tr.select { fieldset table tr.select {
background-color:#0fbd45; background-color:#0fbd45;
} }
@ -49,9 +67,6 @@ fieldset table td {
padding: 0 6px; padding: 0 6px;
/* white-space: pre; */ /* white-space: pre; */
} }
fieldset table td.over {
border:solid 2px red;
}
fieldset table td:hover { fieldset table td:hover {
background-color:red; background-color:red;
} }

View File

@ -33,9 +33,11 @@ Volcanos("onaction", {help: "组件交互", list: [],
switch (event.key) { switch (event.key) {
case "j": case "j":
can.Report(event, {x: 0, y: conf.scroll.line}, "scroll") can.Report(event, {x: 0, y: conf.scroll.line}, "scroll")
can.Report(event, event.key, "keydown")
break break
case "k": case "k":
can.Report(event, {x: 0, y: -conf.scroll.line}, "scroll") can.Report(event, {x: 0, y: -conf.scroll.line}, "scroll")
can.Report(event, event.key, "keydown")
break break
case "Escape": case "Escape":
can.Report(event, event.key, "escape") can.Report(event, event.key, "escape")

View File

@ -196,8 +196,9 @@ Volcanos("onchoice", {help: "组件菜单", list: ["共享", "保存", "刷新"]
}, },
"保存": function(event, can, msg, cmd, field) { "保存": function(event, can, msg, cmd, field) {
var list = [] var list = []
can.page.Select(can, field, "fieldset", function(item) {var meta = item.Meta can.page.Select(can, field, "fieldset.item", function(item) {var meta = item.Meta
can.page.Select(can, item, "form.option", function(option) { can.page.Select(can, item, "form.option", function(option) {
if (option.parentNode != item) {return}
meta.args = can.page.Select(can, option, ".args", function(item) {return item.value}) meta.args = can.page.Select(can, option, ".args", function(item) {return item.value})
}) })
list.push(meta.node||"", meta.group, meta.index, meta.help, JSON.stringify(meta.args||[])) list.push(meta.node||"", meta.group, meta.index, meta.help, JSON.stringify(meta.args||[]))

13
plugin/inner.js Normal file
View File

@ -0,0 +1,13 @@
Volcanos("onimport", {help: "导入数据", list: [],
init: shy("添加控件", function(can, msg, cb, output, action, option) {output.innerHTML = ""
can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
can.Export(event, value.trim(), key, index)
}) || (output.innerHTML = msg.Result())
}),
})
Volcanos("onaction", {help: "控件交互", list: []})
Volcanos("onchoice", {help: "控件菜单", list: []})
Volcanos("ondetail", {help: "控件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

4
plugin/story/field.js Normal file
View File

@ -0,0 +1,4 @@
Volcanos("onimport", {help: "you",
init: function(event, can, value, cmd, target) {var data = target.dataset
},
})

138
plugin/story/trend.js Normal file
View File

@ -0,0 +1,138 @@
Volcanos("onimport", {help: "导入数据", list: [],
init: function(can, meta, cb, target, action, option) {target.innerHTML = ""
if (can.msg.Option("_display") == "table") {
can.page.AppendTable(can, target, can.msg, can.msg.append, function(event, value, key, index, tr, td) {
can.Export(event, value, key)
})
return
}
can.data = can.msg.Table()
can.ui = can.page.Append(can, target, [{view: "action"}, {view: "output"}, {view: "total"}, {view: "status"}])
can.ui.table = can.page.AppendTable(can, target, can.msg, can.msg.append)
can.ui.table.style.clear = "both"
can.sub = can.Output(can, {}, "/plugin/wiki/draw", can.Event({}), function() {
can.onaction["编辑"]({}, can)
can.onaction["表格"]({}, can)
can.onaction["股价图"]({}, can)
}, can.ui.output, can.ui.action, option, can.ui.status)
},
})
Volcanos("onaction", {help: "组件菜单", list: ["股价图", "趋势", "比例", "表格", "编辑"],
"表格": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
can.page.ClassList.neg(can, can.ui.table, "hidden")
},
"股价图": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
if (!can.list) {
var add = 0, del = 0, count = 0, max = 0
can.total = 0, can.list = can.core.List(data, function(value, index) {
var line = {};
line.note = value[can.msg.append[4]]
line.date = value[can.msg.append[0]]
line.add = parseInt(value[can.msg.append[1]])
line.del = parseInt(value[can.msg.append[2]])
line.begin = can.total
line.max = can.total + line.add
line.min = can.total - line.del
line.close = can.total = can.total + line.add - line.del
add += line.add
del += line.del
if (line.max - line.min > max) {
max = line.max - line.min
}
count++
return line
})
var begin = new Date(data[0].date)
var end = new Date(data[data.length-1].date)
var avg = parseInt((add + del) / (end - begin) * 1000 * 3600 * 24)
can.ui.total.innerHTML = can.base.Duration(end-begin) + " count: " + count + " add: " + add + " del: " + del
+ " max: " + max + " avg: " + avg + " rest: " + can.total
}
var step = 20
var view = 200
var space = 10
var max = 600
if (can.list.length * space > max) {
step = parseInt(max / can.list.length)||2
}
var width = can.list.length * step + space * 2
sub.svg.Val("width", width)
var height = view + space * 2
sub.svg.Val("height", height)
var display = can.page.Append(can, can.target, [{view: ["display"], style: {position: "absolute", "white-space": "pre"}, onclick: function() {
can.page.ClassList.add(can, display, "hidden")
}}]).first
can.core.List(can.list, function(line, index) {
sub.onimport.draw({}, sub, {
shape: "line", point: [
{x: space/2+step*index+step/4, y: space/2+view-line.min/can.total*view},
{x: space/2+step*index+step/4, y: space/2+view-line.max/can.total*view},
], style: {
},
})
var one = line.begin < line.close? sub.onimport.draw({}, sub, {
shape: "rect", point: [
{x: space/2+step*index, y: space/2+view-line.begin/can.total*view},
{x: space/2+step*index+step/2, y: space/2+view-line.close/can.total*view},
], style: {
"rx": 0, "ry": 0,
"stroke-width": 1,
"fill": "white",
},
}): sub.onimport.draw({}, sub, {
shape: "rect", point: [
{x: space/2+step*index, y: space/2+view-line.close/can.total*view},
{x: space/2+step*index+step/2, y: space/2+view-line.begin/can.total*view},
], style: {
"rx": 0, "ry": 0,
"stroke-width": 1,
"fill": "black",
},
})
one.onmouseover = function(event) {
can.page.ClassList.del(can, display, "hidden")
display.style.left = event.clientX+space/2+"px"
display.style.top = event.clientY+space/2+"px"
display.innerHTML =
"date: "+line.date+"\n"
+ "note: "+line.note+"\n"
+ "begin: "+line.begin+"\n"
+ "add: "+line.add+"\n"
+ "del: "+line.del+"\n"
+ "close: "+line.close+"\n"
}
})
},
"趋势": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
var width = data.length * 20 + 10
sub.svg.Val("width", width)
var height = can.msg.append.length * 100 + 10
sub.svg.Val("height", height)
can.core.List(can.msg.append, function(key, which) {
can.core.List(data, function(value, index) {
sub.onimport.draw({}, sub, {
shape: "rect",
point: [{x: 10+20*index, y: 100*(which+1)}, {x: 20*index+20, y: 100*(which+1)-parseInt(value[key])}],
})
})
})
},
"编辑": function(event, can, value, cmd, target) {
can.page.ClassList.neg(can, can.ui.action, "hidden")
can.page.ClassList.neg(can, can.ui.status, "hidden")
},
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -13,8 +13,6 @@ Volcanos("onimport", {help: "导入数据", list: [],
can.user.toast(msg.Result()) can.user.toast(msg.Result())
}, true) }, true)
})) }))
event.stopPropagation()
event.preventDefault()
}); });
msg.result && can.page.Append(can, output, [{view: ["code", "div", can.page.Display(msg.Result())]}]).code; msg.result && can.page.Append(can, output, [{view: ["code", "div", can.page.Display(msg.Result())]}]).code;

View File

@ -1,85 +1,145 @@
Volcanos("onimport", {help: "导入数据", list: [], Volcanos("onimport", {help: "导入数据", list: [],
init: function(can, msg, cb, output, action, option) {output.innerHTML = ""; init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
var isData = msg.result && msg.result.length > 0; can.table = can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
if (msg.append && msg.append.length > 0) { can.Export(event, value, key)
var table = can.page.AppendTable(can, output, msg, msg.append); }, function(event, value, key, index, tr, td) {
table.onclick = function(event) {switch (event.target.tagName) { can.user.carte(event, shy("上下文菜单", can.ondetail, can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
case "TD": var sub = can.Event(event);
if (isData) { msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
var target = event.target;
can.page.Appends(can, event.target, [{type: "input", value: target.innerHTML, onkeydown: function(event) {
if (event.key == "Enter") {
target.innerHTML = event.target.value
}
}}])
break
}
can.onimport.which(event, table, msg.append, function(index, key) { typeof cb == "function"? cb(event, can, msg, index, key, cmd, td, tr):
can.Option("name", event.target.innerHTML.trim()) (cb = can.onchoice[cmd], typeof cb == "function")? cb(event, can, msg, index, key, cmd, td, tr):
can.run(event, [event.target.innerHTML.trim()], function(msg) {}) (cb = can.onaction[cmd], typeof cb == "function")? cb(event, can, msg, index, key, cmd, td, tr):
}) can.run(event, ["action", typeof cb == "string"? cb: cmd, key, value.trim(), msg.Ids(index)], function(msg) {
break can.user.toast(msg.Result())
case "TH": }, true)
break }))
case "TR": });
case "TABLE":
}}
return typeof cb == "function" && cb(msg), table;
}
},
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
can.page.Select(can, tr, "th,td", function(td, order) {
if (event.target == td) {return cb(index-1, list[order])}
})
})
}, },
}) })
Volcanos("onaction", {help: "组件菜单", list: ["保存", Volcanos("onfigure", {help: "组件菜单", list: ["保存", "求和"],
], "求和": function(event, can, res, td, index) {
res[index] = parseInt(td.innerText) + (res[index]||0);
},
"最大": function(event, can, res, td, index) {
var n = parseInt(td.innerText);
n > (res[index]||-10000) && (res[index] = n);
},
"最小": function(event, can, res, td, index) {
var n = parseInt(td.innerText);
n < (res[index]||10000) && (res[index] = n);
},
"平均": function(event, can, res, td, ncol, cols, rows, nrow) {
res[ncol] = parseInt(td.innerText) + (res[ncol]||0);
if (nrow == rows.length - 1) {
res[ncol] = res[ncol] / nrow
}
},
})
Volcanos("onaction", {help: "组件菜单", list: ["保存", ["mode", "正常", "块选", "反选", "多选", "拖动", "编辑"], "求和", "最大", "最小", "平均"],
"正常": function(event, can, msg, cmd, target) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.table, "tr", function(item) {
item.setAttribute("contenteditable", false)
item.setAttribute("draggable", false)
item.onmouseenter = null
item.onclick = null
})
},
"块选": function(event, can, msg, cmd, target) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.table, "tr", function(item) {
item.onmouseenter = function() {
can.page.ClassList.add(can, item, "select")
}
})
},
"反选": function(event, can, msg, cmd, target) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.table, "tr", function(item) {
item.onmouseenter = function() {
can.page.ClassList.del(can, item, "select")
}
})
},
"多选": function(event, can, msg, cmd, target) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.table, "tr", function(item) {
item.onclick = function() {
can.page.ClassList.neg(can, item, "select")
}
})
},
"拖动": function(event, can, msg, cmd, target) {
can.onaction["正常"](event, can, msg, cmd, target)
can.page.Select(can, can.table, "tr", function(item) {
item.setAttribute("draggable", true)
item.ondragstart = function(event) {can.drag = item}
item.ondragover = function(event) {
event.preventDefault(),
can.page.ClassList.add(can, item, "over")}
item.ondragleave = function(event) {
can.page.ClassList.del(can, item, "over")
}
item.ondrop = function(event) {event.preventDefault()
can.table.insertBefore(can.drag, item)
}
})
},
"编辑": function(event, can, msg, cmd, target) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.table, "tr", function(item) {
item.setAttribute("contenteditable", true)
})
},
"保存": function(event, can, msg, cmd, target) { "保存": function(event, can, msg, cmd, target) {
can.run(event, ["action", cmd, can.Option("name"), can.page.Select(can, target, "tr", function(tr) {return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")}).join("\n")], function() { can.run(event, ["action", cmd, can.Option("path"), can.page.Select(can, target, "tr", function(tr) {
return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")
}).join("\n")], function() {
can.user.toast("保存成功") can.user.toast("保存成功")
}, true) }, true)
}, },
})
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空", ["rect", "rect", "line", "circle"]],
"清空": function(event, can, msg, cmd, target) {
console.log("choice", cmd)
},
})
Volcanos("ondetail", {help: "组件详情", list: ["编辑", "删除"],
"编辑": function(event, can, msg, index, key, cmd, target) {
can.user.prompt("文字", function(text) {
if (target.tagName == "text") {return target.innerHTML = text}
var data = {"text-anchor": "middle", "dominant-baseline": "middle"} show: function(event, can, msg, cmd, target) {
var figure = can.onfigure[target.tagName] var res = {};
figure.text(event, can, data, target) var method = can.onfigure[cmd];
var mul = "tr" + (can.Action("mode") == "正常"? "": ".select");
var p = can.onaction.push(event, can, data, "text", can.svg)
p.innerHTML = text;
target.Text && can.page.Remove(can, target.Text) && delete(target.Text) can.page.Select(can, can.table, mul, function(tr, nrow, rows) {
target.Text = p (mul != "tr" || nrow > 0) && can.page.Select(can, tr, "td", function(td, ncol, cols) {
}, target.Text && target.Text.innerText || "") method && method(event, can, res, td, ncol, cols, rows, nrow)
})
});
can.page.Append(can, can.target, [{type: "table", list: [{type: "tr", list: can.core.Item(res, function(key, value) {
return {text: [value, "td"]}
}).concat([{text: [cmd, "td"]}])}]}]);
}, },
"复制": function(event, can, msg, index, key, cmd, target) { "求和": function(event, can, msg, cmd, target) {
var figure = can.onfigure[target.tagName] can.onaction.show(event, can, msg, cmd, target)
figure.copy(event, can, target)
}, },
"删除": function(event, can, msg, index, key, cmd, target) { "最大": function(event, can, msg, cmd, target) {
can.page.Remove(can, target) can.onaction.show(event, can, msg, cmd, target)
},
"最小": function(event, can, msg, cmd, target) {
can.onaction.show(event, can, msg, cmd, target)
},
"平均": function(event, can, msg, cmd, target) {
can.onaction.show(event, can, msg, cmd, target)
}, },
}) })
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"], Volcanos("onchoice", {help: "组件交互", list: ["保存", "块选", "反选", "求和"]})
"begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""}, Volcanos("ondetail", {help: "组件详情", list: ["复制", "块选", "反选", "编辑", "删除"],
"width": function(event, can, value, cmd, target) {target.innerHTML = value? value.width+","+value.height: ""}, "复制": function(event, can, msg, index, key, cmd, td, tr) {
"point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y}, var end = can.page.Append(can, can.table, [{type: "tr", list: can.page.Select(can, tr, "td", function(item) {
"which": function(event, can, value, cmd, target) {var figure = can.onfigure[value.tagName]; return {text: [item.innerHTML, "td"]}
target.innerHTML = figure? figure.show(event, can, value, target): value.tagName; })}]).tr
can.table.insertBefore(end, tr)
},
"删除": function(event, can, msg, index, key, cmd, td, tr) {
can.page.Remove(can, tr)
}, },
}) })
Volcanos("onstatus", {help: "组件状态", list: []})
Volcanos("onexport", {help: "导出数据", list: []}) Volcanos("onexport", {help: "导出数据", list: []})

37
plugin/wiki/draw.css Normal file
View File

@ -0,0 +1,37 @@
fieldset.item>div.output>div.code svg {
border: solid 2px red;
}
fieldset.item>div.output>div.status>div {
float:left;
height:20px;
border:1px solid black;
}
fieldset.item>div.output>div.status>input.cmd {
float:left;
background-color:black;
color:lightgreen;;
font-size:16px;
width:250px;
}
fieldset.item>div.output>div.action>button.trap {
background-color:lightblue;
border:2px blue solid;
}
fieldset.item>div.output>div.action>div.space {
width:10px;
display:inline-block;
}
fieldset.item>div.output>canvas {
background-color:#8dd09e;
}
fieldset table tr.hidden {
display:none;
}
fieldset table th.order {
background-color:red;
cursor:pointer;
}
fieldset table td.clip {
background-color:red;
}

617
plugin/wiki/draw.js Normal file
View File

@ -0,0 +1,617 @@
Volcanos("onimport", {help: "导入数据", list: [],
_begin: function(can) {},
_start: function(can) {
var def = {
"font-size": "24",
"fill": "purple",
"stroke": "yellow",
"stroke-width": 2,
"grid": "10",
}
can.core.Item(def, function(key, value) {
can.svg && can.svg.Value(key, can.Action(key, can.svg.Value(key)||value))
})
can.Action("mode", "select")
},
init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
can.Export(event, value, key)
});
var code = can.page.Append(can, output, [{view: ["code", "div", msg.Result()||can.Export(event, null, "file")]}]).code;
can.page.Select(can, output, "svg", function(svg) {
can.group = can.svg = svg;
can.onaction.init(event, can, msg, "init", svg);
var list = can.core.List(can.onaction.list, function(item, index) {if (item[0] == "group") {
return can.onaction.list[index] = ["group", "svg"]
}})[0]
// 分组
can.page.Select(can, svg, "*", function(item, index) {
can.onaction.init(event, can, msg, index, item);
switch (item.tagName) {
case "g":
list.push(item.Value("class"));
break
}
})
})
can.point = [];
can.keys = [];
return typeof cb == "function" && cb(msg);
},
keydown: function(event, can, value, cmd, target) {
can.keys.push(value)
var list = {
a: {prefix: ["mode", "mode"],
w: {list: ["draw"]},
m: {list: ["move"]},
r: {list: ["resize"]},
s: {list: ["select"]},
d: {list: ["delete"]},
},
s: {prefix: ["shape", "shape"],
r: {list: ["rect"]},
c: {list: ["circle"]},
e: {list: ["ecllipse"]},
t: {list: ["text"]},
l: {list: ["line"]},
},
c: {prefix: ["stroke", "stroke"],
r: {list: ["red"]},
b: {list: ["blue"]},
g: {list: ["green"]},
y: {list: ["yellow"]},
p: {list: ["purple"]},
c: {list: ["cyan"]},
h: {list: ["black"]},
w: {list: ["white"]},
},
f: {prefix: ["fill", "fill"],
r: {list: ["red"]},
b: {list: ["blue"]},
g: {list: ["green"]},
y: {list: ["yellow"]},
p: {list: ["purple"]},
c: {list: ["cyan"]},
h: {list: ["black"]},
w: {list: ["white"]},
},
}
var prefix = []
can.core.List(can.keys, function(key) {
if (!list) {
// 查找失败
return can.keys = [], can.Status(event, can.keys, "keys")
}
// 查找递进
prefix = prefix.concat(can.core.List(list.prefix))
list = list[key]
})
if (!list || !list.list) {
// 等待输入
return can.Status(event, can.keys+"("+can.core.Item(list).join(",")+")", "keys")
}
function call(cmds) {
cmds && can.onaction[cmds[0]] && can.onaction[cmds[0]].apply(can, [event, can].concat(cmds.slice(1)))
}
// 执行命令
call(prefix.concat(list.list))
return can.keys = [], can.Status(event, can.keys, "keys")
},
draw: function(event, can, value) {
var figure = can.onfigure[value.shape]
var data = figure.draw(event, can, value.point, value.style)
return can.onaction.push(event, can, data, value.shape, can.group||can.svg)
},
}, ["/plugin/wiki/draw.css"])
Volcanos("onfigure", {help: "图形绘制", list: [],
svg: {
data: {
size: {x: "x", y: "y"},
},
show: function(event, can, value, target) {
return can.svg.Val("width") +","+ can.svg.Val("width")
},
},
rect: {
data: {
rx: 4, ry: 4,
size: {x: "x", y: "y"},
copy: ["width", "height", "rx", "ry"],
}, // <rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
draw: function(event, can, point, style) {if (point.length < 2) {return}
var p0 = point[0], p1 = point[1];
var data = {
"x": p0.x > p1.x? p1.x: p0.x,
"y": p0.y > p1.y? p1.y: p0.y,
"width": Math.abs(p0.x-p1.x),
"height": Math.abs(p0.y-p1.y),
"rx": this.data.rx,
"ry": this.data.ry,
}
can.core.Item(style, function(key, value) {data[key] = value})
can.Status(event, data, "width");
return event.type == "click" && point.length == 2 && (can.point = []), data;
},
space: function(event, can) {
can.user.prompt("width", function(width) {
can.user.prompt("height", function(height) {
can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
can.onaction.push(event, can, can.onfigure.rect.draw(event, can, [can.point[0], [can.point[0]+width, can.point[1]+height]]), "rect", can.group||can.svg)
can.point = []
})
})
},
text: function(event, can, data, target) {
data.x = target.x.baseVal.value+target.width.baseVal.value/2
data.y = target.y.baseVal.value+target.height.baseVal.value/2
return data
},
show: function(event, can, value, target) {
return value.parentNode.Value("class") + " " + value.tagName
+ ": (" + value.x.baseVal.value + "," + value.y.baseVal.value+ ")"
+ " + (" + value.width.baseVal.value + "," + value.height.baseVal.value+ ")"
},
},
circle: {
data: {
size: {x: "cx", y: "cy", width: "r", height: "r"},
copy: ["r"],
}, // <circle cx="25" cy="75" r="20"/>
draw: function(event, can, point) {
if (point.length == 1) {return}
var p0 = point[0], p1 = point[1];
var data = {
"cx": p0.x, "cy": p0.y,
"r": Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2)),
}
event.type == "click" && point.length == 2 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = target.cx.baseVal.value
data.y = target.cy.baseVal.value
return data
},
show: function(event, can, value, target) {
return value.parentNode.Value("class") + " " + value.tagName
+ ": (" + value.cx.baseVal.value + "," + value.cy.baseVal.value+ ")"
+ " > (" + parseInt(value.r.baseVal.value) + ")"
},
},
ellipse: {
data: {
size: {x: "cx", y: "cy", width: "rx", height: "ry"},
}, // <ellipse cx="75" cy="75" rx="20" ry="5"/>
draw: function(event, can, point) {
var p0 = point[0], p1 = point[1];
var data = {
"cx": p0.x, "cy": p0.y,
"rx": Math.abs(p0.x - p1.x), "ry": Math.abs(p0.y - p1.y),
}
event.type == "click" && point.length == 2 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = target.cx.baseVal.value
data.y = target.cy.baseVal.value
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.cx.baseVal.value + "," + value.cy.baseVal.value+ ")"
+ " > (" + parseInt(value.rx.baseVal.value) + parseInt(value.ry.baseVal.value) + ")"
},
},
text: {
data: {
size: {x: "x", y: "y"},
}, // <text x="60" y="10">hi<text>
draw: function(event, can, point) {if (point.length < 1) {return}
var p0 = point[0];
var data = {
"x": p0.x, "y": p0.y,
"inner": can.user.prompt("text"),
}
return can.point = [], data;
},
show: function(event, can, value, target) {
return value.parentNode.Value("class") + " " + value.tagName
+ ": (" + target.Val("x") + "," + target.Val("y")+ ")"
}
},
line: {
data: {
size: {x: "x1", y: "y1", x2: "x2", y: "y2"},
copy: ["x1", "y1", "x2", "y2"],
}, // <line x1="10" x2="50" y1="110" y2="150"/>
draw: function(event, can, point) {
if (point.length < 2) {return}
var p0 = point[0], p1 = point[1];
var data = {
"x1": p0.x, "y1": p0.y,
"x2": p1.x, "y2": p1.y,
}
return event.type == "click" && point.length == 2 && (can.point = []), data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
},
},
path: {
data: {}, // <path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
draw: function(event, can, point) {
var data = {
d: can.core.List(point, function(p, i) {
switch (i) {
case 0: return "M " + p.x + " " + p.y; break
case 1: return "H " + p.x; break
case 2: return "V " + p.y; break
case 3: return "H " + p.x + " Z"; break
}
}).join(" ")
}
event.type == "click" && point.length == 4 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
},
},
polyline: {
data: {}, // <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var data = {
points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
}
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName + ": (" + value.points.baseVal.value + ")"
},
},
polygon: {
data: {}, // <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var data = {
points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
}
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName + ": (" + value.points.baseVal.value + ")"
},
},
})
Volcanos("onaction", {help: "组件菜单", list: ["保存", "清空", "删除", "添加",
["group", "svg"],
["font-size", 12, 16, 18, 24, 32],
["stroke-width", 1, 2, 3, 4, 5],
{text: "c"}, ["stroke", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black"],
{text: "f"}, ["fill", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black", "#0000"],
{text: "a"}, ["mode", "draw", "move", "resize", "select", "scale", "delete"],
{text: "s"}, ["shape", "rect", "circle", "ellipse", "text", "line", "path", "polyline", "polygon"],
["grid", 1, 2, 3, 4, 5, 10, 20],
],
"保存": function(event, can, msg, cmd, target) {
can.run(event, ["action", cmd, can.Option("path"), can.Export(event, can.svg, "file")], function() {
can.user.toast("保存成功")
}, true)
},
"清空": function(event, can, msg, cmd, target) {can.svg.innerHTML = ""},
"删除": function(event, can, msg, cmd, target) {
if (can.group == can.svg) {return}
can.page.Remove(can, can.group)
can.page.Select(can, can.action, "option[value="+can.group.Value("class")+"]", function(item) {
can.page.Remove(can, item)
})
can.Action("group", "svg")
},
"添加": function(event, can, msg, cmd, target) {
can.user.prompt("add group", function(name) {
var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
can.group.append(can.onaction.init(event, can, msg, cmd, group))
can.group = group, can.group.Value("class", name)
can.core.List(["font-size", "stroke-width", "stroke", "fill"], function(name) {
can.group.Value(name, can.Action(name))
})
can.page.Select(can, can.action, "select.group", function(item) {
can.page.Append(can, item, [{type: "option", value: name, inner: name}]);
item.value = name
})
})
},
group: function(event, can, value, cmd, target) {
if (cmd == "svg") {
can.group = can.svg
} else {
can.page.Select(can, can.svg, "g."+cmd, function(item) {
can.group = item
})
}
can.core.List(["font-size", "storke-width", "stroke", "fill"], function(key) {
can.Action(key, can.group.Value(key)||can.Action(key))
})
return can.group
},
"font-size": function(event, can, value, cmd, target) {can.group.Value(value, cmd)},
"stroke-width": function(event, can, value, cmd, target) {can.group.Value(value, cmd)},
stroke: function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
fill: function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
shape: function(event, can, value, cmd, target) {cmd && can.Action(value, cmd)},
grid: function(event, can, value, cmd, target) {cmd && can.Action(value, cmd)},
init: function(event, can, msg, cmd, item) {
item.Value = function(key, value) {
var figure = can.onfigure[item.tagName];
key && (key = figure && figure.data && figure.data.size && figure.data.size[key] || key)
return value && item.setAttribute(key, value), item.getAttribute(key||"class")||item[key]&&item[key].baseVal&&item[key].baseVal.value||item[key]&&item[key].baseVal||"";
}
item.Val = function(key, value) {
return parseInt(item.Value(key, value == undefined? value: parseInt(value)||0));
}
item.Group = function() {
var target = item
while (target) {
if (["svg", "g"].indexOf(target.tagName) > -1) {
return target;
}
target = target.parentNode;
}
return can.svg
}
return item;
},
push: function(event, can, msg, cmd, target) {cmd = {select: "rect"}[cmd] || cmd
var rect = document.createElementNS("http://www.w3.org/2000/svg", cmd);
target.appendChild(can.onaction.init(event, can, msg, cmd, rect));
can.core.Item(msg, function(key, value) {
if (key == "inner") {
rect.innerHTML = value
return
}
rect.Value(key, value)
});
return rect;
},
mode: function(event, can, value, cmd) {
cmd && can.Action("mode", cmd)
},
_draw: function(event, can, point) {
can.Status(event, null, "width");
can.Status(event, null, "begin");
can.Status(event, point[0], "begin")
var shape = can.page.Select(can, can.action, "select.shape", function(item) {return item.value})[0]
var figure = can.onfigure[shape];
var data = figure && figure.draw(event, can, point);
return data && can.onaction.push(event, can, data, shape, can.group||can.svg)
},
_move: function(event, can, point) {
if (point.length == 1) {if (event.type != "click") {return}
// 记录图形
can.onaction._select(event, can, point)
can.point = point, can.current = {target: can.group}
} else if (point.length == 2) {
if (event.type == "click") {
can.point = [], delete(can.current); return
}
}
var target = can.current.target
var figure = can.onfigure[target.tagName];
if (point.length == 1) {
target.style.cursor = "move"
can.current.pos = 5, can.current.begin = can.page.Select(can, target, "*", function(item) {
if (item.tagName == "g") {return}
target.style.cursor = "move"
return {
target: item,
x: item.Val("x"),
y: item.Val("y"),
width: item.Val("width"),
height: item.Val("height"),
}
})
} else {
can.core.List(can.current.begin, function(item) {
can.page.Resizes(event, item.target, item, point[0], point[1], can.current.pos)
})
}
},
_resize: function(event, can, point) {
if (point.length == 1) {if (event.type != "click") {return}
// 记录图形
can.current = {target: event.target}
} else if (point.length == 2) {
if (event.type == "click") {
can.point = [], delete(can.current); return
}
}
var target = can.current.target
var figure = can.onfigure[target.tagName];
if (point.length == 1) {
can.current.pos = can.page.Prepos(event, target)
can.current.begin = {
x: target.Val("x"),
y: target.Val("y"),
width: target.Val("width"),
height: target.Val("height"),
}
} else {
can.page.Resizes(event, target, can.current.begin, point[0], point[1], can.current.pos)
}
},
_scale: function(event, can, point) {
if (point.length < 2) {
return
}
if (point.length == 2) {
can.last && can.page.Remove(can, can.last)
var figure = can.onfigure["line"];
var data = figure && figure.draw(event, can, point);
can.last = can.onaction.push(event, can, data, "line", can.group||can.svg)
if (event.type == "click" && point.length == 2) {
can.point = point
}
return
}
can.now && can.page.Remove(can, can.now)
var figure = can.onfigure["line"];
var data = figure && figure.draw(event, can, [point[0], point[2]]);
can.now = can.onaction.push(event, can, data, "line", can.group||can.svg)
if (event.type == "click" && point.length == 3) {
can.now && can.page.Remove(can, can.now)
can.last && can.page.Remove(can, can.last)
can.point = []
}
can.group.Value("transform", "scale("+(point[2].x-point[0].x)/(point[1].x-point[0].x)+","+(point[2].y-point[0].y)/(point[1].y-point[0].y)+")")
},
_delete: function(event, can, point) {
event.target != can.svg && can.page.Remove(can, event.target)
can.point = []
},
_select: function(event, can, point) {
var target = event.target
while (target) {
if (target.tagName == "g") {
can.Action("group", target.Value("class"))
can.group = target
break
}
if (target.tagName == "svg") {
can.Action("group", "svg")
can.group = can.svg
break
}
target = target.parentNode
}
can.point = []
},
space: function(event, can) {
if (!can.current) {return}
var figure = can.onfigure[can.current.tagName]
figure && figure.space(event, can)
},
oncontextmenu: function(event, can) {var target = event.target
var figure = can.onfigure[event.target.tagName]||{data: {}}
can.user.carte(event, shy("", can.ondetail, figure.data.detail || can.ondetail.list, function(event, key, meta) {var cb = meta[key];
typeof cb == "function" && cb(event, can, figure, key, target);
}), can), event.stopPropagation(), event.preventDefault()
},
onclick: function(event, can) {if (!can.svg) {return}
var p = can.svg.getBoundingClientRect();
var point = {x: event.clientX-p.x, y: event.clientY-p.y};
point.x = point.x - point.x % parseInt(can.Action("grid"));
point.y = point.y - point.y % parseInt(can.Action("grid"));
can.point = (can.point || []).concat([point]);
can.temp && can.page.Remove(can, can.temp) && delete(can.temp);
can.onaction["_"+can.Action("mode")](event, can, can.point);
},
onmouseover: function(event, can) {
can.Status(event, event.target, "which")
},
onmousemove: function(event, can) {
if (["move", "resize"].indexOf(can.Action("mode"))) {
can.current || can.page.Prepos(event, event.target)
}
if (!can.svg || can.point.length == 0) {return}
var p = can.svg.getBoundingClientRect()
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
point.x = point.x - point.x % parseInt(can.Action("grid"));
point.y = point.y - point.y % parseInt(can.Action("grid"));
can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
can.temp = can.onaction["_"+can.Action("mode")](event, can, can.point.concat(point))
can.Status(event, point, "point")
},
})
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空"]})
Volcanos("ondetail", {help: "组件详情", list: ["编辑", "复制", "删除"],
"编辑": function(event, can, value, cmd, target) {
can.user.prompt("文字", function(text) {
if (target.tagName == "text") {return target.innerHTML = text}
var data = {}
var figure = can.onfigure[target.tagName]
figure.text(event, can, data, target)
var p = can.onaction.push(event, can, data, "text", target.Group())
p.innerHTML = text;
target.Text && can.page.Remove(can, target.Text) && delete(target.Text)
target.Text = p
}, target.Text && target.Text.innerText || "")
},
"复制": function(event, can, value, cmd, target) {
var figure = can.onfigure[target.tagName].data
var data = {}
data[figure.move.x] = parseInt(target.Value(figure.move.x))+20;
data[figure.move.y] = parseInt(target.Value(figure.move.y))+20;
can.core.List(figure.copy, function(item) {data[item] = target.Value(item)});
return data && can.onaction.push(event, can, data, target.tagName, can.group||can.svg)
},
"删除": function(event, can, value, key, cmd, target) {can.page.Remove(can, target)},
})
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which", "keys"],
"begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
"width": function(event, can, value, cmd, target) {target.innerHTML = value? value.width+","+value.height: ""},
"point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y},
"which": function(event, can, value, cmd, target) {var figure = can.onfigure[value.tagName];
target.innerHTML = figure? figure.show(event, can, value, value): value.tagName;
},
"keys": function(event, can, value, cmd, target) {target.innerHTML = value},
})
Volcanos("onexport", {help: "导出数据", list: [],
file: function(event, can, svg, cmd, target) {
return ['<svg vertion="1.1" xmlns="https://www.w3.org/2000/svg" text-anchor="middle" dominant-baseline="middle"'].concat(svg? can.core.List(["width", "height", "stroke", "fill", "stroke-width"], function(item) {
return svg.Value(item)? ' ' + item + '="' + svg.Value(item) + '"': ""
}): []).concat(['>', svg?svg.innerHTML:"", "</svg>"]).join("")
},
})

View File

@ -1,414 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_begin: function(can) {
},
_start: function(can) {
can.Action("stroke-width", 2)
can.Action("stroke", "yellow")
can.Action("fill", "purple")
can.Action("grid", "20")
},
init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
if (msg.append && msg.append.length > 0) {action.innerHTML = "";
var table = can.page.AppendTable(can, output, msg, msg.append);
table.onclick = function(event) {switch (event.target.tagName) {
case "TD":
can.onimport.which(event, table, msg.append, function(index, key) {
can.run(event, [can.Option("name", event.target.innerHTML.trim())])
})
break
case "TH":
break
case "TR":
case "TABLE":
}}
return typeof cb == "function" && cb(msg), table;
}
var code = can.page.Append(can, output, [{view: ["code", "div", msg.Result()||can.Export(event, null, "file")]}]).code;
can.page.Select(can, output, "svg", function(svg) {can.group = can.svg = svg;
can.onaction.init(event, can, msg, "init", svg);
can.onaction.list[2] = ["group", "svg", "add"];
can.page.Select(can, svg, "*", function(item, index) {
can.onaction.init(event, can, msg, index, item);
switch (item.tagName) {
case "g":
can.onaction.list[2].push(item.Value("class"));
break
}
})
}), can.point = [];
return typeof cb == "function" && cb(msg), code;
},
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
can.page.Select(can, tr, "th,td", function(td, order) {
if (event.target == td) {return cb(index-1, list[order])}
})
})
},
})
Volcanos("onfigure", {help: "图形绘制", list: [],
select: {draw: function(event, can, point) {if (point.length == 1) {return}
var p0 = point[0], p1 = point[1];
var data = {
"x": p0.x > p1.x? p1.x: p0.x,
"y": p0.y > p1.y? p1.y: p0.y,
"width": Math.abs(p0.x-p1.x),
"height": Math.abs(p0.y-p1.y),
"fill": "#11000000",
"class": "temp",
}
can.Status(event, data, "width");
event.type == "click" && point.length == 2 && (can.point = [])
return data;
}},
resize: {draw: function(event, can, point) {
if (point.length == 1) {if (event.type != "click") {return}
// 记录图形
can.current = {target: event.target}
} else if (point.length == 2) {
if (event.type == "click") {can.point = [], delete(can.current); return}
}
var target = can.current.target
var figure = can.onfigure[target.tagName];
if (point.length == 1) {
// 记录起点
can.core.Item(figure.data.resize, function(key, value) {
can.current[key] = parseInt(target.Value(value))
})
} else {
var resize = figure.data.resize;
target.Value(resize.width, can.current.width + point[1].x - point[0].x)
target.Value(resize.height, can.current.height + point[1].y - point[0].y)
}
}},
move: {draw: function(event, can, point) {
if (point.length == 1) {if (event.type != "click") {return}
// 记录图形
can.current = {target: event.target}
} else if (point.length == 2) {
if (event.type == "click") {return can.point = [], delete(can.current), null}
}
var target = can.current.target
var figure = can.onfigure[can.current.target.tagName];
var move = figure.data.move || {x: "x", y: "y"}
if (point.length == 1) {
// 记录起点
can.current.x = parseInt(target.Value(move.x))
can.current.y = parseInt(target.Value(move.y))
} else {
// 移动图形
target.Value(move.x, can.current.x+point[1].x-point[0].x)
target.Value(move.y, can.current.y+point[1].y-point[0].y)
}
}},
svg: {
data: {resize: {width: "width", height: "height"}},
show: function(event, can, value, target) {},
},
text: {
data: {move: {x: "x", y: "y"}}, // <text x="60" y="10">hi<text>
show: function(event, can, value, target) {}
},
rect: {
data: {
resize: {width: "width", height: "height"},
move: {x: "x", y: "y"}, copy: ["width", "height", "rx", "ry"],
rx: 4, ry: 4,
}, // <rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var p0 = point[0], p1 = point[1];
var data = {
"x": p0.x > p1.x? p1.x: p0.x,
"y": p0.y > p1.y? p1.y: p0.y,
"width": Math.abs(p0.x-p1.x),
"height": Math.abs(p0.y-p1.y),
"rx": this.data.rx,
"ry": this.data.ry,
}
can.Status(event, data, "width");
return event.type == "click" && point.length == 2 && (can.point = []), data;
},
text: function(event, can, data, target) {
data.x = target.x.baseVal.value+target.width.baseVal.value/2
data.y = target.y.baseVal.value+target.height.baseVal.value/2
return data
},
show: function(event, can, value, target) {
return value.parentNode.Value("class") + " " + value.tagName
+ ": (" + value.x.baseVal.value + "," + value.y.baseVal.value+ ")"
+ " + (" + value.width.baseVal.value + "," + value.height.baseVal.value+ ")"
},
},
line: {
data: {
resize: {width: "x2", height: "y2"},
move: {x: "x1", y: "y1"}, copy: ["x1", "y1", "x2", "y2"],
}, // <line x1="10" x2="50" y1="110" y2="150"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var p0 = point[0], p1 = point[1];
var data = {
"x1": p0.x, "y1": p0.y,
"x2": p1.x, "y2": p1.y,
}
return event.type == "click" && point.length == 2 && (can.point = []), data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
},
},
circle: {
data: {move: {x: "cx", y: "cy"}, copy: ["r"]}, // <circle cx="25" cy="75" r="20"/>
draw: function(event, can, point) {
if (point.length == 1) {return}
var p0 = point[0], p1 = point[1];
var data = {
"cx": p0.x, "cy": p0.y,
"r": Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2)),
}
event.type == "click" && point.length == 2 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = target.cx.baseVal.value
data.y = target.cy.baseVal.value
return data
},
show: function(event, can, value, target) {
return value.parentNode.Value("class") + " " + value.tagName
+ ": (" + value.cx.baseVal.value + "," + value.cy.baseVal.value+ ")"
+ " > (" + parseInt(value.r.baseVal.value) + ")"
},
},
ellipse: {
data: {}, // <ellipse cx="75" cy="75" rx="20" ry="5"/>
draw: function(event, can, point) {
var p0 = point[0], p1 = point[1];
var data = {
"cx": p0.x, "cy": p0.y,
"rx": Math.abs(p0.x - p1.x), "ry": Math.abs(p0.y - p1.y),
}
event.type == "click" && point.length == 2 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = target.cx.baseVal.value
data.y = target.cy.baseVal.value
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.cx.baseVal.value + "," + value.cy.baseVal.value+ ")"
+ " > (" + parseInt(value.rx.baseVal.value) + parseInt(value.ry.baseVal.value) + ")"
},
},
path: {
data: {}, // <path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
draw: function(event, can, point) {
var data = {
d: can.core.List(point, function(p, i) {
switch (i) {
case 0: return "M " + p.x + " " + p.y; break
case 1: return "H " + p.x; break
case 2: return "V " + p.y; break
case 3: return "H " + p.x + " Z"; break
}
}).join(" ")
}
event.type == "click" && point.length == 4 && (can.point = [])
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName
+ ": (" + value.x1.baseVal.value + "," + value.y1.baseVal.value+ ")"
+ " - (" + value.x2.baseVal.value + "," + value.y2.baseVal.value+ ")"
},
},
polyline: {
data: {}, // <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var data = {
points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
}
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName + ": (" + value.points.baseVal.value + ")"
},
},
polygon: {
data: {}, // <polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
draw: function(event, can, point) {if (point.length < 2) {return}
var data = {
points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
}
return data;
},
text: function(event, can, data, target) {
data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
return data
},
show: function(event, can, value, target) {
return value.tagName + ": (" + value.points.baseVal.value + ")"
},
},
})
Volcanos("onaction", {help: "组件菜单", list: ["保存", "清空",
["group", "svg", "add"],
["stroke-width", 1, 2, 3, 4, 5],
["stroke", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black"],
["fill", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black", "#0000"],
["shape", "move", "select", "resize", "rect", "circle", "ellipse", "path", "line", "polyline", "polygon"],
["grid", 1, 2, 3, 4, 5, 10, 20],
],
"保存": function(event, can, msg, cmd, target) {
can.run(event, ["action", cmd, can.Option("name"), can.Export(event, can.svg, "file")], function() {
can.user.toast("保存成功")
}, true)
},
"清空": function(event, can, msg, cmd, target) {can.svg.innerHTML = ""},
group: function(event, can, value, cmd, target) {
switch (value) {
case "svg": return can.group = can.svg;
case "add":
can.user.prompt("add group", function(name) {
can.svg.append(can.onaction.init(event, can, value, cmd, can.group = document.createElementNS('http://www.w3.org/2000/svg', 'g')))
can.group.Value("class", name)
can.core.List(["stroke-width", "stroke", "fill"], function(name) {
can.group.Value(name, can.Action(name))
})
can.page.Select(can, can.action, "select.group", function(item) {
can.page.Append(can, item, [{type: "option", value: name, inner: name}]);
item.value = name
})
})
break
default:
can.page.Select(can, can.svg, "g."+value, function(item) {
can.group = item
})
}
return can.group
},
"stroke-width": function(event, can, value, cmd, target) {can.group.Value(cmd, value)},
stroke: function(event, can, value, cmd, target) {can.group.Value(cmd, value)},
fill: function(event, can, value, cmd, target) {can.group.Value(cmd, value)},
shape: function(event, can, value, cmd, target) {can.shape = value},
grid: function(event, can, value, cmd, target) {can.grid = value},
init: function(event, can, msg, cmd, item) {
item.ondblclick = item.oncontextmenu = function(event) {can.user.carte(event, shy("", can.ondetail, can.ondetail.list, function(event, key, meta) {var cb = meta[key];
typeof cb == "function" && cb(event, can, msg, cmd, key, key, item);
}), can), event.stopPropagation(), event.preventDefault()}
item.onclick = function() {
}
item.Value = function(key, value) {return value && item.setAttribute(key, value), item.getAttribute(key||"class")||item[key]&&item[key].baseVal&&item[key].baseVal.value||item[key]&&item[key].baseVal||""}
return item;
},
push: function(event, can, msg, cmd, target) {cmd = {select: "rect"}[cmd] || cmd
var rect = document.createElementNS("http://www.w3.org/2000/svg", cmd);
target.appendChild(can.onaction.init(event, can, msg, cmd, rect));
can.core.Item(msg, function(key, value) {rect.Value(key, value)});
return rect;
},
draw: function(event, can, point) {
can.Status(event, null, "width");
can.Status(event, null, "begin");
can.Status(event, point[0], "begin")
var shape = can.page.Select(can, can.action, "select.shape", function(item) {return item.value})[0]
var figure = can.onfigure[shape];
var data = figure && figure.draw(event, can, point);
return data && can.onaction.push(event, can, data, shape, can.group||can.svg)
},
onclick: function(event, can) {if (!can.svg) {return}
var p = can.svg.getBoundingClientRect();
var point = {x: event.clientX-p.x, y: event.clientY-p.y};
point.x = point.x - point.x % parseInt(can.Action("grid"));
point.y = point.y - point.y % parseInt(can.Action("grid"));
can.point = (can.point || []).concat([point]);
can.temp && can.page.Remove(can, can.temp) && delete(can.temp);
can.onaction.draw(event, can, can.point);
},
onmouseover: function(event, can) {
can.Status(event, event.target, "which")
},
onmousemove: function(event, can) {if (!can.svg || can.point.length == 0) {return}
var p = can.svg.getBoundingClientRect()
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
point.x = point.x - point.x % parseInt(can.Action("grid"));
point.y = point.y - point.y % parseInt(can.Action("grid"));
can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
can.temp = can.onaction.draw(event, can, can.point.concat(point))
can.Status(event, point, "point")
},
})
Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空"]})
Volcanos("ondetail", {help: "组件详情", list: ["编辑", "复制", "删除"],
"编辑": function(event, can, msg, index, key, cmd, target) {
can.user.prompt("文字", function(text) {
if (target.tagName == "text") {return target.innerHTML = text}
var data = {"text-anchor": "middle", "dominant-baseline": "middle"}
var figure = can.onfigure[target.tagName]
figure.text(event, can, data, target)
var p = can.onaction.push(event, can, data, "text", can.svg)
p.innerHTML = text;
target.Text && can.page.Remove(can, target.Text) && delete(target.Text)
target.Text = p
}, target.Text && target.Text.innerText || "")
},
"复制": function(event, can, msg, index, key, cmd, target) {
var figure = can.onfigure[target.tagName].data
var data = {}
data[figure.move.x] = parseInt(target.Value(figure.move.x))+20;
data[figure.move.y] = parseInt(target.Value(figure.move.y))+20;
can.core.List(figure.copy, function(item) {data[item] = target.Value(item)});
return data && can.onaction.push(event, can, data, target.tagName, can.group||can.svg)
},
"删除": function(event, can, msg, index, key, cmd, target) {can.page.Remove(can, target)},
})
Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"],
"begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
"width": function(event, can, value, cmd, target) {target.innerHTML = value? value.width+","+value.height: ""},
"point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y},
"which": function(event, can, value, cmd, target) {var figure = can.onfigure[value.tagName];
target.innerHTML = figure? figure.show(event, can, value, target): value.tagName;
},
})
Volcanos("onexport", {help: "导出数据", list: [],
file: function(event, can, svg, cmd, target) {
return ['<svg vertion="1.1" xmlns="https://www.w3.org/2000/svg"'].concat(svg? can.core.List(["width", "height", "stroke-width", "stroke", "fill"], function(item) {
return svg.Value(item)? ' ' + item + '="' + svg.Value(item) + '"': ""
}): []).concat(['>', svg?svg.innerHTML:"", "</svg>"]).join("")
},
})

51
plugin/wiki/word.css Normal file
View File

@ -0,0 +1,51 @@
fieldset .story {
border:solid 2px #f000;
}
fieldset .story:hover {
border:solid 2px red;
}
fieldset fieldset.story {
border:ridge 1px cyan;
}
fieldset p.story {
white-space:pre;
}
fieldset ul.story li:hover {
border:solid 2px red;
cursor:pointer;
}
fieldset code.story {
display:block;
color:white;
font-size:14px;
font-family:monospace;
background-color:#272822;
white-space:pre;
padding:10px;
overflow:auto;
border:solid 3px green;
max-height:640px;
}
fieldset div.stack:hover {
background-color:red;
}
fieldset div.stack {
cursor:pointer;
width:fit-content;
}
fieldset div.stack.fold {
font-weight:bold;
}
fieldset ul.stack {
border:solid 2px #0000;
margin:0px;
}
fieldset ul.stack:hover {
border:solid 2px red;
}

View File

@ -1,53 +1,45 @@
Volcanos("onimport", {help: "导入数据", list: [], Volcanos("onimport", {help: "导入数据", list: [],
_begin: function(can) {},
_start: function(can) {},
init: function(can, msg, cb, output, action, option) {output.innerHTML = ""; init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
if (msg.append && msg.append.length > 0) { if (can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
var table = can.page.AppendTable(can, output, msg, msg.append); can.Export(event, value, key)
table.onclick = function(event) {switch (event.target.tagName) { })) {return}
case "TD":
can.onimport.which(event, table, msg.append, function(index, key) { output.innerHTML = msg.Result()
can.Option("name", event.target.innerHTML.trim())
can.run(event, [event.target.innerHTML.trim()], function(msg) {}) can.page.Select(can, output, ".story", function(item) {var data = item.dataset
}) item.oncontextmenu = function(event) {
break can.user.carte(event, shy("组件菜单", can.ondetail, can.ondetail.list, function(event, key, meta) {
case "TH": var cb = meta[key] || can.onchoice[key] || can.onaction[key]; typeof cb == "function" && cb(event, can, data, key, item);
break }));
case "TR": event.stopPropagation(), event.preventDefault();
case "TABLE":
}}
return typeof cb == "function" && cb(msg), table;
} }
can.preview = can.page.Append(can, output, [{view: "preview", inner: msg.Result(), switch (item.tagName) {
style: {border: "solid 2px red"}, case "FIELDSET":
}]).last can.Plugin(can, item.name, JSON.parse(data.meta||"{}"), function(event, cmds, cb, silent) {
can.run(event, ["action", "story", data.type, data.name, data.text].concat(cmds), cb, true)
}, item, function(sub) {
can.page.Select(can, can.preview, ".story", function(item) {
var figure = can.onfigure[item.dataset.type] || can.onfigure[item.localName];
item.onclick = function(event) {can.node = item}
item.oncontextmenu = function(event) {var target = event.target; can.user.carte(event, shy("", can.ondetail, figure.menu||can.ondetail.list, function(event, key, meta) {var cb = meta[key];
cb? typeof cb == "function" && cb(event, can, msg, 0, key, key, target):
(cb = can.onchoice[key] || can.onaction[key], typeof cb == "function" && cb(event, can, key, key, target))
}), can), event.stopPropagation(), event.preventDefault()}
figure && figure.init && figure.init({}, can, item.localName, "init", item)
}) })
return typeof cb == "function" && cb(msg), can.preview; break
default:
var figure = can.onfigure[item.type||item.tagName]
figure && figure.init && figure.init({}, can, msg, "init", item)
}
})
return typeof cb == "function" && cb(msg)
}, },
which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")} }, ["/plugin/wiki/word.css"])
can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
can.page.Select(can, tr, "th,td", function(td, order) {
if (event.target == td) {return cb(index-1, list[order])}
})
})
},
})
Volcanos("onfigure", {help: "图形绘制", list: [], Volcanos("onfigure", {help: "图形绘制", list: [],
_spawn: function(sup, can) {can.sup = sup},
_begin: function(can) {},
_start: function(can) {},
_close: function(can) {},
premenu: { premenu: {
init: function(event, can, value, cmd, target) { init: function(event, can, value, cmd, target) {
can.page.Append(can, target, can.page.Select(can, can.preview, "h1.story,h2.story,h3.story", function(item) {var data = item.dataset; can.page.Append(can, target, can.page.Select(can, can.target, "h1.story,h2.story,h3.story", function(item) {var data = item.dataset;
return {text: [item.innerHTML, "li"], onclick: function(event) { return {text: [item.innerHTML, "li"], onclick: function(event) {
item.scrollIntoView(); item.scrollIntoView();
}}; }};
@ -235,6 +227,8 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
return value? 'chain "'+data.name+'"' +' `\n' + data.text + '\n`': "" return value? 'chain "'+data.name+'"' +' `\n' + data.text + '\n`': ""
}, },
}, },
}, [], function(can) {var sup = can.sup
}) })
Volcanos("onaction", {help: "组件菜单", list: ["刷新", "保存", ["操作", "只读", "排序", "编辑"], Volcanos("onaction", {help: "组件菜单", list: ["刷新", "保存", ["操作", "只读", "排序", "编辑"],
"插入", ["元素", "h1", "h2", "h3", "brief", "refer", "spark", "shell", "order", "table", "stack"]], "插入", ["元素", "h1", "h2", "h3", "brief", "refer", "spark", "shell", "order", "table", "stack"]],
@ -263,28 +257,28 @@ Volcanos("onaction", {help: "组件菜单", list: ["刷新", "保存", ["操作"
}, true) }, true)
}, },
"只读": function(event, can, value, cmd, target) { "只读": function(event, can, value, cmd, target) {
can.page.Select(can, can.preview, ".story", function(item) { can.page.Select(can, can.target, ".story", function(item) {
item.setAttribute("contenteditable", false) item.setAttribute("contenteditable", false)
item.setAttribute("draggable", false) item.setAttribute("draggable", false)
}) })
}, },
"排序": function(event, can, value, cmd, target) { "排序": function(event, can, value, cmd, target) {
can.page.Select(can, can.preview, ".story", function(item) { can.page.Select(can, can.target, ".story", function(item) {
item.setAttribute("draggable", true) item.setAttribute("draggable", true)
item.ondragstart = function(event) {can.drag = event.target} item.ondragstart = function(event) {can.drag = event.target}
item.ondragover = function(event) {event.preventDefault()} item.ondragover = function(event) {event.preventDefault()}
item.ondrop = function(event) {event.preventDefault() item.ondrop = function(event) {event.preventDefault()
can.preview.insertBefore(can.drag, item) can.target.insertBefore(can.drag, item)
} }
}) })
}, },
"编辑": function(event, can, value, cmd, target) { "编辑": function(event, can, value, cmd, target) {
can.page.Select(can, can.preview, ".story", function(item) { can.page.Select(can, can.target, ".story", function(item) {
item.setAttribute("contenteditable", true) item.setAttribute("contenteditable", true)
}) })
}, },
"插入": function(event, can, value, cmd, target) {var figure = can.onfigure[can.Action("元素")]; "插入": function(event, can, value, cmd, target) {var figure = can.onfigure[can.Action("元素")];
can.page.Append(can, can.preview, figure.push(event, can, value, cmd, target)).first.setAttribute("contenteditable", true) can.page.Append(can, can.target, figure.push(event, can, value, cmd, target)).first.setAttribute("contenteditable", true)
}, },
}) })
Volcanos("onchoice", {help: "组件交互", list: ["刷新", "保存", "追加", "清空", ["rect", "rect", "line", "circle"]], Volcanos("onchoice", {help: "组件交互", list: ["刷新", "保存", "追加", "清空", ["rect", "rect", "line", "circle"]],

View File

@ -22,20 +22,23 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
var id = 1, conf = {}, conf_cb = {}, sync = {}, cache = {}; var id = 1, conf = {}, conf_cb = {}, sync = {}, cache = {};
can = can || {}, list.push(can) && (can.__proto__ = {_name: name, _help: "插件模块", _create_time: new Date(), _load: function(name) { can = can || {}, list.push(can) && (can.__proto__ = {_name: name, _help: "插件模块", _create_time: new Date(), _load: function(name) {
if (meta.cache[name]) {var cache = meta.cache[name]; if (meta.cache[name]) {var cache = meta.cache[name];
for (var i = 0; i < cache.length; i++) {var item = cache[i]; for (var i = 0; i < cache.length; i++) {var sub = cache[i];
if (item._name == can._name) {continue} // if (sub._name == can._name) {continue}
// 加载索引 // 加载索引
can[item._name] = item; can[sub._name] = sub;
typeof sub._spawn == "function" && sub._spawn(can, sub)
} }
return can return can
} }
meta.cache[name] = [] meta.cache[name] = []
for (var i = meta.index; i < list.length; i++) {var item = list[i]; for (var i = meta.index; i < list.length; i++) {var sub = list[i];
if (item._name == can._name || item._type == "local"|| item._type == "input" || item._type == "output") {continue} // if (sub._name == can._name) {continue}
if (sub._type == "local"|| sub._type == "input" || sub._type == "output") {continue}
// 加载缓存 // 加载缓存
can[item._name] = item; can[sub._name] = sub;
meta.cache[name].push(item); meta.cache[name].push(sub);
typeof sub._spawn == "function" && sub._spawn(can, sub)
} }
meta.index = i; meta.index = i;
return can return can
@ -201,7 +204,7 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
if (type.endsWith(".js")) { if (type.endsWith(".js")) {
var script = document.createElement("script"); var script = document.createElement("script");
script.src = (type.startsWith("/")? "": Config.volcano)+type; script.src = (type.startsWith("/")? "": Config.volcano)+type;
script.onload = line; script.onload = line
target.appendChild(script); target.appendChild(script);
return script return script
} }
@ -265,16 +268,17 @@ function Volcanos(name, can, libs, cb, msg) { // 封装模块
} }
} }
// 注册事件
can.core.Item(can.onaction, function(key, cb) {key.indexOf("on") == 0 && (can.target[key] = function(event) {cb(event, can)})});
// 注册控件 // 注册控件
can.action && (can.action.innerHTML = ""), can.onaction && can.page.AppendAction(can, can.action, can.onaction.list, function(event, value, key) { can.action && (can.action.innerHTML = ""), can.onaction && can.page.AppendAction(can, can.action, can.onaction.list, function(event, value, key) {
key? run(event, value, key, can.onaction[key]||can.onaction[value]): run(event, msg, value, can.onaction[value]); key? run(event, key, value, can.onaction[key]||can.onaction[value]): run(event, msg, value, can.onaction[value]);
}) })
// 注册菜单 // 注册菜单
can.target.oncontextmenu = function(event) {can.user.carte(event, shy("", can.onchoice, can.onchoice.list, function(event, key, meta) { can.target.oncontextmenu = function(event) {can.user.carte(event, shy("", can.onchoice, can.onchoice.list, function(event, key, meta) {
run(event, msg, key, can.onchoice[key] || can.onaction[key]); run(event, msg, key, can.onchoice[key] || can.onaction[key]);
}), can), event.stopPropagation(), event.preventDefault()} }), can), event.stopPropagation(), event.preventDefault()}
// 注册事件
can.core.Item(can.onaction, function(key, cb) {key.indexOf("on") == 0 && (can.target[key] = function(event) {cb(event, can)})});
} }
can.onimport && can.onimport._start && can.onimport._start(can) can.onimport && can.onimport._start && can.onimport._start(can)
}) })

155
style.css
View File

@ -13,6 +13,9 @@ fieldset {
legend { legend {
margin-left:10px; margin-left:10px;
} }
.hidden {
display:none;
}
fieldset>form.option { fieldset>form.option {
padding:0 5px; padding:0 5px;
@ -58,35 +61,35 @@ fieldset>form.option textarea.args {
width:300px; width:300px;
height:50px; height:50px;
} }
fieldset>div.action { fieldset div.action {
padding:6px; padding:6px;
clear:both; clear:both;
} }
fieldset>div.action>div.item { fieldset div.action>div.item {
float:left; float:left;
} }
fieldset>div.action>div.item.space { fieldset div.action>div.item.space {
display:inline-block; display:inline-block;
width:10px; width:10px;
} }
fieldset>div.action input { fieldset div.action input {
width:60px; width:60px;
margin-left:6px; margin-left:6px;
} }
fieldset>div.action input:hover { fieldset div.action input:hover {
width:100px; width:100px;
} }
fieldset>div.action input:focus { fieldset div.action input:focus {
width:120px; width:120px;
} }
fieldset>div.output { fieldset div.output {
padding:5px; padding:5px;
clear:both; clear:both;
} }
fieldset>div.output>div.item { fieldset div.output>div.item {
padding:2px; padding:2px;
} }
fieldset>div.output>div.item:hover { fieldset div.output>div.item:hover {
cursor:pointer; cursor:pointer;
background-color:red; background-color:red;
border:ridge 2px yellow; border:ridge 2px yellow;
@ -121,88 +124,16 @@ fieldset.dialog>div.create table {
fieldset.item { fieldset.item {
float:left; float:left;
} }
fieldset.item>form.option>div.item {
padding:0;
border:0;
}
fieldset.item>form.option>div.item:hover {
border:0;
}
fieldset.item>form.option>div.item.select {
border:0;
}
fieldset.item>div.output { fieldset.item>div.output {
overflow:auto; overflow:auto;
} }
fieldset.item>div.output>canvas {
background-color:#8dd09e;
}
fieldset.item>div.output>div.action>button.trap {
background-color:lightblue;
border:2px blue solid;
}
fieldset.item>div.output>div.action>div.space {
width:10px;
display:inline-block;
}
fieldset.item>div.output>div.status>div {
float:left;
height:20px;
border:1px solid black;
}
fieldset.item>div.output>div.status>input.cmd {
float:left;
background-color:black;
color:lightgreen;;
font-size:16px;
width:250px;
}
fieldset.item>div.output>div.code svg {
border: solid 2px red;
}
fieldset.item div.border-left {
position:absolute;
width:2px;
height:inherit;
height:-webkit-fill-available;
background:green;
cursor:ew-resize;
}
fieldset.item div.border-right {
position:absolute;
right:0px;
width:2px;
height:inherit;
height:-webkit-fill-available;
background:green;
cursor:ew-resize;
}
fieldset.item div.border-bottom {
position:absolute;
bottom:0px;
height:2px;
width:-webkit-fill-available;
background:green;
cursor:ns-resize;
}
fieldset.input { fieldset.input {
border:solid 2px yellow;
position:absolute; position:absolute;
} }
fieldset.input>legend { fieldset.input>legend {
padding-top:4px; padding-top:4px;
} }
fieldset.input table tr:hover {
background-color:yellow;
}
fieldset.input table td:hover {
background-color:red;
cursor:pointer;
}
fieldset.input table td.select {
background-color:red;
}
fieldset table { fieldset table {
font-size:14px; font-size:14px;
@ -217,16 +148,6 @@ fieldset table caption {
fieldset table tbody { fieldset table tbody {
overflow:auto; overflow:auto;
} }
fieldset table tr.hidden {
display:none;
}
fieldset table th.order {
background-color:red;
cursor:pointer;
}
fieldset table td.clip {
background-color:red;
}
fieldset table td sup.more { fieldset table td sup.more {
color:red; color:red;
} }
@ -242,54 +163,6 @@ fieldset div.code {
border:solid 3px green; border:solid 3px green;
max-height:640px; max-height:640px;
} }
fieldset div.code span.red { fieldset div.hidden {
color:red; display:none;
} }
fieldset div.code span.green {
color:green;
}
fieldset .story {
border:solid 2px #f000;
}
fieldset .story:hover {
border:solid 2px red;
}
fieldset p.story {
white-space:pre;
}
fieldset ul.story li:hover {
border:solid 2px red;
cursor:pointer;
}
fieldset code.story {
display:block;
color:white;
font-size:14px;
font-family:monospace;
background-color:#272822;
white-space:pre;
padding:10px;
overflow:auto;
border:solid 3px green;
max-height:640px;
}
fieldset div.stack:hover {
background-color:red;
}
fieldset div.stack {
cursor:pointer;
width:fit-content;
}
fieldset div.stack.fold {
font-weight:bold;
}
fieldset ul.stack {
border:solid 2px #0000;
margin:0px;
}
fieldset ul.stack:hover {
border:solid 2px red;
}