1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 08:48:06 +08:00

opt frame.js

This commit is contained in:
shylinux 2020-12-18 20:12:54 +08:00
parent 6f17d35c7c
commit 0ea50d737e
124 changed files with 674 additions and 7243 deletions

View File

@ -1,52 +1,4 @@
# volcanos
volcanos是一个前端框架通过模块化、共享化、自动化、快速的创建、共享应用程序、数据。
volcanos是一个前端框架通过模块化、集群化、自动化、快速的创建、共享应用程序和数据。
## 1 原型 proto.js
### 1.1 ID 生成器
### 1.2 Log 日志器
### 1.3 Conf 配置器
### 1.4 Sync 同步器
### 1.5 Timer 定时器
### 1.6 Event 触发器
### 1.7 Dream 构造器
### 1.8 Cache 缓存器
### 1.9 Story 存储器
## 2 框架 frame.js
### 2.1 Page 页面
### 2.2 Pane 面板
### 2.3 Plugin 插件
### 2.4 Inputs 控件
### 2.5 Output 组件
## 3 工具模块 lib/
### 3.1 数据类型 base.js
### 3.2 数据结构 core.js
### 3.3 后端通信 misc.js
### 3.4 网页操作 page.js
### 3.5 用户交互 user.js
## 4 网页模块 page/
### 4.1 应用页面 index.html
### 4.2 共享页面 share.html
## 4 面板模块 pane/
### 4.1 标题栏 Header.js
### 4.2 用户列表 Ocean.js
### 4.3 群组列表 River.js
### 4.4 工作台 Action.js
### 4.5 应用列表 Storm.js
### 4.6 设备列表 Steam.js
### 4.7 状态栏 Footer.js
## 5 插件模块 plugin/
### 5.1 插件模块 state.js
### 5.2 输入模块 input.js
### 5.3 输出模块 table.js
### 5.4 输入插件 input/
### 5.5 输出插件 story/
### 5.6 其它模块 local/
## 6 客户端 client/
### 6.1 小程序 mp/

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/index.css">
</head>
<body>
<script src="/proto.js"></script>
<script src="/chrome/chrome.js"></script>
</body>
<html>

View File

@ -1,96 +0,0 @@
var can = Volcanos("chrome", {
chrome: function(msg, cmd, cb) {
if (cmd.length == 0) {
// 窗口列表
chrome.windows.getAll(function(wins) {
can.core.List(wins, function(win) {win.wid = win.id
msg.Push(win, ["wid", "state", "left", "top", "width", "height"])
})
typeof cb == "function" && cb(msg)
})
return
}
if (cmd.length == 1) {
// 标签列表
chrome.tabs.getAllInWindow(parseInt(cmd[0]), function(tabs) {
can.core.List(tabs, function(tab) {tab.tid = tab.id
msg.Push(tab, ["tid", "active", "width", "height", "index", "title", "url"])
})
typeof cb == "function" && cb(msg)
})
return
}
delete(msg._can)
delete(msg._event)
if (cmd[1] == "") {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
cmd[1] = tabs[0].id
chrome.tabs.sendMessage(parseInt(cmd[1]), msg, function (res) {
msg.Copy(res), typeof cb == "function" && cb(msg)
})
})
} else {
chrome.tabs.sendMessage(parseInt(cmd[1]), msg, function (res) {
msg.Copy(res), typeof cb == "function" && cb(msg)
})
}
return
// 新建标签
chrome.tabs.create({windowId: parseInt(cmd[0]), url: cmd[1], selected: false}, function() {
can.chrome(msg, [cmd[0]], cb)
})
},
bookmark: function(msg, cmd, cb) {
chrome.bookmarks.getSubTree(cmd[0]||"0", function(labs) {
for (var i = 0; i < labs.length; i++) {labs[i].pid = labs[i].parentId
msg.Push("time", can.base.Time(labs[i].dateAdded))
msg.Push(labs[i], ["pid", "id", "index", "title", "url"])
labs = labs.concat(labs[i].children||[])
}
typeof cb == "function" && cb(msg)
})
},
}, ["/lib/base", "/lib/core", "/lib/misc", "/lib/page", "/lib/user"], function(can) {can.Conf({iceberg: "http://localhost:9020/"})
can.user.toast = function(message, title) {chrome.notifications.create(null, {
message: message, title: title||"volcanos", iconUrl: "/favicon.ico", type: "basic",
})},
can.misc.WSS(can, "ws://localhost:9020/space/", {name: "chrome", type: "chrome"}, function(event, msg) {
if (msg.Option("_handle")) { return can.user.toast(msg.result.join("")) }
// can.user.toast(msg.detail.join(" "))
try {
switch (msg.detail[0]) {
case "space": can._share = msg.detail[2]; break
case "pwd": msg.Echo("hello world"); break
default: (can[msg.detail[0]]||can.chrome[msg.detail[0]])(msg, msg.detail.slice(1), function(msg) {
msg.Reply(msg)
}); return
}
} catch (e) {
can.user.toast(e)
}
msg.Reply(msg)
}, function() {can.user.toast("wss connect", "iceberg")})
can.run = function(event, cmd, cb, silent) { var msg = can.request(event)
can.misc.Run(event, can, {names: "code/chrome/crx"}, cmd, cb)
},
chrome.history.onVisited.addListener(function(item) {
can.run({}, ["history", item.id, item.title, item.url])
})
chrome.contextMenus.create({
title: "favor",
onclick: function(event) {
chrome.tabs.query({ active: true}, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, { action: "copy" }, function (response) {
console.log(response)
can.run({}, ["history", "id", response.title, response.src])
})
})
},
})
})

View File

@ -1,56 +0,0 @@
var can = Volcanos("chrome", {
spide: function(can, msg) {
can.page.Select(can, document.body, "video", function(item) {
var p = can.page.Select(can, document.body, "p.title")[0]
var ls = item.src.split("?")
var ls = ls[0].split(".")
msg.Push("time", can.base.Time())
msg.Push("type", "video")
msg.Push("name", (p && p.innerText || "video")+"."+ls[ls.length-1])
msg.Push("text", item.src)
msg.Push("link", item.src)
})
can.page.Select(can, document.body, "img", function(item) {
var ls = item.src.split("?")
var ls = ls[0].split("/")
msg.Push("time", can.base.Time())
msg.Push("type", "img")
if (item.src.startsWith("data:image")) {
msg.Push("name", item.src.slice(item.src.length-20))
} else {
msg.Push("name", ls[ls.length-1]||"image.jpg")
}
msg.Push("text", item.src)
msg.Push("link", item.src)
})
},
}, [], function(can) {
can.user = user
can.page = page
can.misc = misc
can.core = core
can.base = base
chrome.extension.onMessage.addListener( function (msg, sender, cb) { var action = can[msg.detail[3]||"spide"]
msg = can.request({}, msg)
delete(msg._event)
delete(msg._can)
typeof action == "function" && action(can, msg) || typeof cb == "function" && cb(msg)
})
return
chrome.extension.onMessage.addListener( function (request, sender, sendResponse) {
var title = can.page.Select(can, document.body, "p.title", function(item) {
return item.innerText
}).join("-")
can.page.Select(can, document.body, "video", function(item) {
sendResponse({poster: item.poster, src: item.src, title: title})
console.log(item)
})
})
})

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/index.css">
</head>
<body style="min-width:800px; min-height:600px; overflow:auto">
<script src="/proto.js"></script>
<script src="/chrome/popup.js"></script>
</body>
<html>

View File

@ -1,12 +0,0 @@
Volcanos({name: "demo", volcano: "/frame.js", iceberg: "http://localhost:9020/chat/", intshell: "plug.sh",
libs: ["/lib/base", "/lib/core", "/lib/misc", "/lib/page", "/lib/user"], panes: [
{name: "Header", help: "标题栏", pos: "head", state: ["time", "username"]},
{name: "River", help: "群聊组", pos: "left"},
{name: "Action", help: "工作台", pos: "middle"},
{name: "Search", help: "搜索框", pos: "float"},
{name: "Footer", help: "状态条", pos: "foot", state: ["ncmd" ]},
], main: {name: "Header", engine: "remote", list: ["/publish/order.js"]}, plugin: [
"/plugin/state.js", "/plugin/input.js", "/plugin/table.js",
],
})

View File

@ -1,28 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { can._output.innerHTML = "";
can.ui = can.page.Append(can, can._target, [
{view: ["content", "div"]}, {view: ["display", "pre"]},
])
can.onappend.table(can, msg, can.ui.content, "table")
can.onappend.board(can, msg,can.ui.display, "board")
var refresh = msg.Option("_refresh") || can.Conf("feature")["_refresh"]
refresh && can.core.Timer(refresh, function() {
can.run({})
})
return typeof cb == "function" && cb(msg)
},
})
Volcanos("onaction", {help: "控件交互", list: [],
onclick: function(event, can) {
can.run(event, [], function() {})
},
})
Volcanos("ondetail", {help: "控件交互", list: ["编辑", "删除"],
"编辑": function(event, can, key) {
console.log(key)
},
"删除": function(event, can, key) {
console.log(key)
},
})

View File

@ -1,134 +0,0 @@
const kit = require("utils/kit.js")
App({
// data: {}, conf: {serve: "https://shylinux.com/chat", space: "mac"},
data: {}, conf: {serve: "https://shylinux.com/chat", space: ""},
request: function(cmd, data, cb) { var app = this; data.sessid = app.conf.sessid, data.pod = app.conf.space
wx.request({method: "POST", url: app.conf.serve+"/"+cmd, data: data, success: function(res) { var msg = res.data
if (res.statusCode == 401) { return app.usercode(function() {app.request(cmd, data, cb)}) }
console.log("POST", cmd, msg)
msg.__proto__ = {
nRow: function() { return msg.append && msg.append[0] && msg[msg.append[0]].length || 0 },
Result: function() { return msg.result && msg.result.length > 0 && msg.result.join("") || "" },
Table: function(cb) { var row = 0
for (var i = 0; i < msg.append.length; i++) {
row = msg[msg.append[i]].length > row? msg[msg.append[i]].length: row
}
for (var i = 0; i < row; i++) { var line = {}
for (var k in msg.append) {
line[msg.append[k]] = msg[msg.append[k]][i]
}
typeof cb == "function" && cb(line, i, row)
}
},
}
var row = 0
var index = []
if (msg.append) {
for (var i = 0; i < msg.append.length; i++) {
row = msg[msg.append[i]].length > row? msg[msg.append[i]].length: row
}
for (var i = 0; i < row; i++) {
index.push(i)
}
}
msg._index = index
typeof cb == "function" && cb(msg)
}})
},
download: function(cmd, data, cb) { var app = this; data.sessid = app.conf.sessid
wx.downloadFile({url: app.conf.serve+"/"+cmd, data: data, success: cb})
},
usercode: function(cb) { var app = this
wx.login({success: function(res) { app.request("mp/login/sess", {code: res.code}, function(msg) {
wx.setStorage({key: "sessid", data: msg.Result()})
app.conf.sessid = msg.Result(), typeof cb == "function" && cb()
})}})
},
userinfo: function(cb) { var app = this
if (app.conf.userInfo) {
app.request("mp/login/user", app.conf.userInfo, function(msg) {
typeof cb == "function" && cb(app.conf.userInfo)
})
return
}
app.usercode(function() {
wx.getSetting({ success: function(res) { res.authSetting['scope.userInfo'] && wx.getUserInfo({success: function(res) {
app.request("mp/login/user", res.userInfo, function(msg) { app.conf.userInfo = res.userInfo
typeof cb == "function" && cb(res.userInfo)
})
}})}})
})
},
location: function(arg) { wx.chooseLocation(arg) },
title: function(title) { wx.setNavigationBarTitle({title: title, success: function() {}})},
modal: function(title, content, cb) { wx.showModal({title: title||"", content: content||"", success: cb})},
toast: function(title, content) { wx.showToast({title: title, content: content||""})},
jumps: function(url, args, cb) { var next = "/pages/"+kit.Args(url, args)
console.log("jump", next), wx.navigateTo({url: next, success: cb})
},
scans: function(cb) { var app = this
wx.scanCode({success: function(res) { console.log("scan", res)
try {
var value = JSON.parse(res.result)
} catch(e) {
try {
var value = {"type": "url", "text": res.result}
var ls = res.result.split("?"); if (ls.length > 1) { ls = ls[1].split("&")
for (var i = 0; i < ls.length; i++) { var vs = ls[i].split("=")
value[vs[0]] = decodeURIComponent(vs[1])
}
}
} catch(e) {
typeof cb == "function" && cb({type: "", text: res.result})
return
}
}
switch (value.type) {
case "share":
switch (value.name) {
case "invite":
app.userinfo(function(userInfo) {
app.modal("接受邀请", value.name, function(res) {
res.confirm && app.request("mp/login/auth", value, function(msg) {
app.toast("回执成功")
})
})
})
break
}
break
case "login":
app.userinfo(function(userInfo) {
app.modal("授权登录", value.name, function(res) {
res.confirm && app.request("mp/login/auth", value, function(msg) {
app.toast("授权成功")
})
})
})
break
case "active":
app.userinfo(function(userInfo) {
app.modal("授权登录", value.name, function(res) {
res.confirm && app.request("mp/login/auth", value, function(msg) {
app.toast("授权成功")
})
})
})
break
default:
typeof cb == "function" && cb(value)
}
}})
},
onLaunch: function() {
this.conf.sessid = wx.getStorageSync("sessid")
console.log("load", "sessid", this.conf.sessid)
},
})

View File

@ -1,16 +0,0 @@
{
"pages": [
"pages/river/river",
"pages/action/action",
"pages/insert/insert"
],
"window": {
"backgroundColor": "#000",
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#000",
"navigationBarTitleText": "终端工具链",
"navigationBarTextStyle": "white"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}

View File

@ -1,13 +0,0 @@
<template name="action">
<view class="action">
<view class="item" wx:for="{{action}}" wx:key="name">
<button size="mini" bindtap="onaction" data-name="{{item}}">{{item}}</button>
</view>
</view>
</template>
<template name="list-name">
<view class="output" wx:if="{{msg.name}}">
<view class="item" wx:for="{{msg.name}}" wx:key="name" bindtap="ondetail" data-name="{{item}}" data-index="{{index}}">{{item}}</view>
</view>
</template>

View File

@ -1,84 +0,0 @@
page {
color:white;
font-size:14px;
font-family:monospace;
background-color:#272822;
white-space:pre;
}
view.action>view.item {
float:left;
}
view.option>view.item {
padding:0;
border: 0;
float:left;
}
view.option input {
width:80px;
margin:2px;
padding:2px;
border:solid 1px green;
}
view.option view.textarea {
clear:both;
width:calc(100% - 2px);
border:solid 1px green;
}
view.option view.select {
border:solid 1px green;
float:left;
/* width:40px; */
padding:6px;
}
view.option view.select picker {
}
view.option view.select picker view {
}
view.output {
clear:both;
}
view.output view.item {
text-align:center;
font-size:18px;
padding:10px;
border:solid 1px green;
}
view.output view.list view.item {
background-color:darkgray;
margin-left:20px;
}
view.output view.code {
margin-left:10px;
padding:10px;
border-left:solid 2px cyan;
}
view.title {
margin-top:20px;
margin-bottom:10px;
font-weight:bold;
font-size:18px;
}
view.field {
}
table {
}
tr {
display:flex;
justify-content:space-between;
}
th {
padding:5px;
width:100%;
text-align:center;
border:solid 1px red;
}
td {
padding:5px;
width:100%;
text-align:center;
border:solid 1px green;
}

View File

@ -1,185 +0,0 @@
const kit = require("../../utils/kit.js")
const app = getApp()
Page({
data: {
action: ["扫码", "刷新", "清屏", "串行", "并行"],
river: "", storm: "", title: "",
res: [], his: {}, inputs: {},
},
action: {
"扫码": function(event, page, data, name) {
// app.jumps("scans/scans")
app.scans(function(res) {
res["sess.river"] = page.data.river
res["sess.storm"] = page.data.storm
app.request("mp/login/scan", res)
page.onaction(event, res, res.name)
})
},
"刷新": function(event, page, data, name) {
var list = []; app.data[page.data.river+page.data.storm] = page.data.res = list
wx.showLoading()
app.request("action", {cmds: [page.data.river, page.data.storm]}, function(msg) {
wx.hideLoading()
msg.Table(function(line, index) {
line.name = line.name.split(" ")[0]
page.data.his[index] = []
line.inputs = JSON.parse(line.list)
line.feature = JSON.parse(line.meta)
if (!line.inputs || line.inputs.length === 0) {
line.inputs = [{_input: "text"}, {_input: "button", value: "执行"}]
}
list.push(line), line.inputs.forEach(function(input) {
input.action = input.action || input.value
input.value == "auto" && (input.value = "")
input.value = input.value || kit.Value(line, "feature.trans."+input.name)
if (input.value && input.value.startsWith("@")) {
input.value = ""
}
if (input._input == "select") {
input.values = input.values || input.value && input.value.split("|")
}
input._input == "button" && input.action == "auto" && page.run(event, index)
})
})
page.setData({res: list})
})
},
"串行": function(event, page, data, name) {
function cb(i) {
page.run(event, i, null, function() {i < page.data.res.length - 1&& cb(i+1)})
}
cb(0)
},
"并行": function(event, page, data, name) {
kit.List(page.data.res, function(field, index) {
page.run(event, index)
})
},
"清屏": function(event, page, data, name) {
kit.List(page.data.res, function(field, index) {
delete(field.msg)
})
page.setData({res: page.data.res})
},
},
onaction: function(event, data, name) {
data = data || event.target.dataset, name = name || data.name
console.log("action", "action", name)
this.action[name](event, this, data)
},
run: function(event, order, cmd, cb) {var page = this, field = page.data.res[order]
var cmds = [page.data.river, page.data.storm, field.id || field.key]
cmds = cmds.concat(cmd||kit.List(field.inputs, function(input) {
if (["text", "textarea", "select"].indexOf(input._input) > -1) {
return input.value || ""
}
}))
for (var i = cmds.length-1; i > 0; i--) {
if (cmds[i] === "") {cmds.pop()} else {break}
}
wx.showLoading()
app.request("action?="+field.name, {cmds: cmds}, function(msg) {
wx.hideLoading()
page.data.res[order].msg = msg
page.setData({res: page.data.res})
typeof cb == "function" && cb(msg)
})
},
onBlur: function(event) {var page = this, data = event.target.dataset
},
onFocus: function(event) {},
onInput: function(event) {var page = this, data = event.target.dataset
page.data.res[data.order].inputs[data.index].value = event.detail.value
page.setData({res: page.data.res})
},
onChange: function(event) {var page = this, data = event.target.dataset
page.data.res[data.order].inputs[data.index].index = parseInt(event.detail.value)
page.data.res[data.order].inputs[data.index].value = data.input.values[parseInt(event.detail.value)]
page.setData({res: page.data.res})
},
onEnter: function(event) {var page = this, data = event.target.dataset
page.data.res[data.order].inputs[data.index].value = event.detail.value
},
onClick: function(event) {var page = this, data = event.target.dataset
var field = page.data.res[data.order]
if (field.feature[data.input.name]) {
app.data.insert = {
field: field, input: data.input,
data: {}, list: field.feature[data.input.name], cb: function(res) {
var list = ["action", data.input.name]
kit.Item(res, function(key, value) {
key && value && list.push(key, value)
})
page.run(event, data.order, list)
}
}
app.jumps("insert/insert", {river: page.data.river, storm: page.data.storm, title: field.name})
return
}
switch (data.input.name) {
case "返回":
// 恢复命令
page.data.his[data.order].pop()
var line = page.data.his[data.order].pop()
kit.List(field.inputs, function(input, index) {
input.value = line && line[index] || ""
})
default:
// 执行命令
page.data.his[data.order].push(kit.List(field.inputs, function(input) {
return input.value
})) && page.run(event, data.order)
}
},
onWhich: function(event) {var page = this, data = event.target.dataset
var field = page.data.res[data.order]
field.inputs.forEach(function(input, index) {
if (input.name == data.field) {
// 导入参数
page.data.res[data.order].inputs[index].value = data.value
page.setData({res: page.data.res})
// 执行命令
input.action == "auto" && page.data.his[data.order].push(kit.List(field.inputs, function(input) {
return input.value
})) && page.run(event, data.order)
}
})
},
onLoad: function (options) {
console.log("page", "action", options)
app.conf.sessid = options.sessid || app.conf.sessid
this.data.river = options.river
this.data.storm = options.storm
this.data.title = options.title
app.title(options.title)
var data = app.data[options.river+options.storm]
if (data) { return this.setData({res: this.data.res = data}) }
this.onaction({}, {}, "刷新")
},
onReady: function () {},
onShow: function () {},
onHide: function () {},
onUnload: function () {},
onPullDownRefresh: function () {
this.onaction({}, {}, "刷新")
},
onReachBottom: function () {},
onShareAppMessage: function (res) {
console.log("action", "share", res)
return {
title: this.data.title,
path: "pages/action/action?river="+this.data.river+"&storm="+this.data.storm+"&title="+this.data.title,
}
},
})

View File

@ -1,3 +0,0 @@
{
"usingComponents": {}
}

View File

@ -1,45 +0,0 @@
<import src="../../app.wxml"/>
<template is="action" data="{{action}}"></template>
<view class="output">
<view class="field" wx:for="{{res}}" wx:key="name" wx:for-index="order" wx:for-item="field">
<view class="title"><text>{{field.name}}({{field.help}})</text></view>
<view class="option">
<!-- 参数 -->
<view class="item {{item._input}}" wx:for="{{field.inputs}}" wx:key="name">
<!-- 文本 -->
<input wx:if="{{item._input == 'text'}}" type="text" value="{{item.value}}" placeholder="{{item.name}}"
bindtap="onClick" bindinput="onInput" bindconfirm="onEnter" data-order="{{order}}" data-index="{{index}}" data-input="{{item}}"/>
<!-- 文本 -->
<textarea wx:elif="{{item._input == 'textarea'}}" value="{{item.value}}" placeholder="{{item.name}}"
bindtap="onClick" bindinput="onInput" data-field="{{field}}" data-order="{{order}}" data-index="{{index}}" data-input="{{item}}"></textarea>
<!-- 列表 -->
<picker wx:elif="{{item._input == 'select'}}" bindchange="onChange" value="{{item.index||0}}" range="{{item.values}}"
data-field="{{field}}" data-order="{{order}}" data-index="{{index}}" data-input="{{item}}">
<view>{{item.values[item.index||0]}}</view>
</picker>
<!-- 按钮 -->
<button wx:elif="{{item._input == 'button'}}" size="mini" bindtap="onClick" data-field="{{field}}" data-order="{{order}}" data-index="{{index}}" data-input="{{item}}">{{item.value||item.name}}</button>
</view>
</view>
<!-- 输出 -->
<view class="output">
<!-- 表格 -->
<table wx:if="{{field.msg}}">
<tr><th wx:for="{{field.msg.append}}" wx:key="name">{{item}}</th></tr>
<tr wx:for="{{field.msg._index}}" wx:key="name" wx:for-index="line">
<td wx:for="{{field.msg.append}}" bindtap="onWhich" data-value="{{field.msg[item][line]}}" data-index="{{line}}" data-field="{{item}}" data-order="{{order}}">{{field.msg[item][line]}}</td>
</tr>
</table>
<!-- 文本 -->
<view class="output"><rich-text wx:for="{{field.msg.result}}" wx:key="name" nodes="{{item}}"></rich-text></view>
<!-- <view class="code" wx:elif="{{field.msg.result}}"><text wx:for="{{field.msg.result}}" wx:key="name">{{item}}</text></view> -->
</view>
</view>
</view>

View File

@ -1,6 +0,0 @@
view.option view.item {
padding:0;
}
view.option view.item.select {
padding:3px;
}

View File

@ -1,80 +0,0 @@
const kit = require("../../utils/kit.js")
const app = getApp()
Page({
data: {
action: ["扫码"],
field: {},
insert: [],
},
action: {
"扫码": function(event, page, data, name) {
app.scans(function(res) {
res["sess.river"] = page.data.river
res["sess.storm"] = page.data.storm
app.request("mp/login/scan", res)
page.onaction(event, res, res.name)
})
},
},
onaction: function(event, data, name) {
data = data || event.target.dataset, name = name || data.name
console.log("action", "action", name)
this.action[name](event, this, data)
},
onInput: function(event) {var page = this, data = event.target.dataset
app.data.insert[data.index].value = event.detail.value
},
onFocus: function(event) {},
onConfirm: function (event) { var page = this
kit.List(page.data.insert, function(item) {
app.data.insert.data[item.name] = item.value
})
app.data.insert.cb(app.data.insert.data)
wx.navigateBack()
},
onLoad: function (options) {
this.data.insert = app.data.insert.list
var p = app.data.insert.input.action
if (p.startsWith("@")) {
var cb = this.plugin[p.slice(1,-1)]; cb && cb(this)
}
var cb = this.plugin[p]; cb && cb(this)
kit.List(app.data.insert.list, function(item) {
item.action = item.action || item.value
item.value && item.value.startsWith("@") && (item.value = "")
app.data.insert.data[item.name] = item.value
})
console.log("page", "insert", options)
app.title(options.title)
this.setData(this.data)
},
onReady: function () {},
onShow: function () {},
onHide: function () {},
onUnload: function () {},
onPullDownRefresh: function () {},
onReachBottom: function () {},
plugin: {
getLocation: function(page, data) { app.location({success: function(res) {
res.latitude = parseInt(res.latitude * 100000)
res.longitude = parseInt(res.longitude * 100000)
kit.List(page.data.insert, function(item) {
res[item.name] && (item.value = res[item.name])
}), page.setData(page.data)
}}) },
scanQRCode: function(page) { app.scans(function(res) {
kit.List(page.data.insert, function(item) {
res[item.name] && (item.value = res[item.name])
}), page.setData(page.data)
}) },
paste: function(page, data) { wx.getClipboardData({success: function(res) {
kit.List(page.data.insert, function(item) {
res[item.name] && (item.value = res[item.name])
}), page.setData(page.data)
}}) },
},
})

View File

@ -1,3 +0,0 @@
{
"usingComponents": {}
}

View File

@ -1,26 +0,0 @@
<import src="../../app.wxml"/>
<template is="action" data="{{action}}"></template>
<view class="output">
<view class="item" wx:for="{{insert}}" wx:key="name">
<!-- 文本 -->
<input wx:if="{{item._input == 'text'}}" type="text" value="{{item.value}}" placeholder="{{item.name}}"
bindtap="onClick" bindinput="onInput" bindconfirm="onEnter" data-index="{{index}}" data-input="{{item}}"/>
<!-- 文本 -->
<textarea wx:elif="{{item._input == 'textarea'}}" value="{{item.value}}" placeholder="{{item.name}}"
bindtap="onClick" bindinput="onInput" data-index="{{index}}" data-input="{{item}}"></textarea>
<!-- 列表 -->
<picker wx:elif="{{item._input == 'select'}}" bindchange="onChange" value="{{item.index||0}}" range="{{item.values}}"
data-index="{{index}}" data-input="{{item}}">
<view>{{item.values[item.index||0]}}</view>
</picker>
<!-- 按钮 -->
<button wx:elif="{{item._input == 'button'}}" size="mini" bindtap="onClick" data-index="{{index}}" data-input="{{item}}">{{item.name||item.value}}</button>
</view>
<button bindtap="onConfirm">提交</button>
<button bindtap="onCancel">取消</button>
</view>

View File

@ -1 +0,0 @@
/* pages/insert/insert.wxss */

View File

@ -1,84 +0,0 @@
const kit = require("../../utils/kit.js")
const app = getApp()
Page({
data: {
action: ["扫码", "刷新", "登录"],
river: {},
},
action: {
"扫码": function(event, page, data) { app.scans(function(res) {
switch (res.type) {
case "url":
app.request("mp/login/scan", res, function(msg) {
page.onaction({}, {}, "刷新")
})
break
default:
res.name && page.onaction(event, res, res.name)
}
}) },
"刷新": function(event, page, data) {
wx.showLoading()
app.request("river", {}, function(msg) {
wx.hideLoading()
var river = {}; msg.Table(function(value) {
river[value.hash] = value
})
page.setData({river: river})
})
},
"登录": function(event, page, data) { app.conf.sessid = "",
app.userinfo(function(res) {
page.onaction(event, data, "刷新")
})
},
},
onaction: function(event, data, name) {
data = data || event.target.dataset, name = name || data.name
console.log("action", "river", name)
this.action[name](event, this, data)
},
ondetail: function(event, data) { var page = this
data = data || event.target.dataset.item
console.log("detail", "river", data)
var river = page.data.river[data.hash]
if (river.tool) {
river.hidetool = !river.hidetool
page.setData({river: page.data.river})
return
}
wx.showLoading()
app.request("river", {cmds: [data.hash, "tool"]}, function(msg) {
wx.hideLoading()
river.tool = {}; msg.Table(function(value) {
river.tool[value.hash] = value
value.river = data
})
page.setData({river: page.data.river})
})
},
onchange: function(event, data) { var page = this
data = data || event.target.dataset.item
app.jumps("action/action", {river: data.river.hash, storm: data.hash, title: data.river.name+"."+data.name})
},
onLoad: function (options) { var page = this
console.log("page", "river", options)
app.conf.sessid = options.sessid || app.conf.sessid
app.usercode(function() {
page.onaction({}, options, "刷新")
})
},
onReady: function () {},
onShow: function () {},
onHide: function () {},
onUnload: function () {},
onPullDownRefresh: function () {
this.onaction({}, {}, "刷新")
},
onReachBottom: function () {},
onShareAppMessage: function () {}
})

View File

@ -1,3 +0,0 @@
{
"usingComponents": {}
}

View File

@ -1,12 +0,0 @@
<import src="../../app.wxml"/>
<template is="action" data="{{action}}"></template>
<view class="output">
<view class="item" wx:for="{{river}}" wx:key="name">
<view class="item" bindtap="ondetail" data-item="{{item}}">{{item.name}}</view>
<view class="list" wx:if="{{!item.hidetool}}">
<view class="item" bindtap="onchange" wx:for="{{item.tool}}" wx:key="name" data-item="{{item}}">{{item.name}}</view>
</view>
</view>
</view>

View File

@ -1,4 +0,0 @@
module.exports = {
onimport: function() {},
}

View File

@ -1 +0,0 @@
hello wrold

View File

@ -1,89 +0,0 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"autoAudits": false,
"coverView": true,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false
},
"compileType": "miniprogram",
"libVersion": "2.0.4",
"appid": "wxf4e5104d83476ed6",
"projectname": "%E7%BB%88%E7%AB%AF%E5%B7%A5%E5%85%B7%E9%93%BE",
"debugOptions": {
"hidedInDevtools": []
},
"isGameTourist": false,
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"gamePlugin": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": [
{
"id": 0,
"name": "pages/action/action",
"pathName": "pages/action/action",
"query": "river=c796cd&storm=9092d5",
"scene": 1008
},
{
"id": 1,
"name": "action",
"pathName": "pages/action/action",
"query": "river=d022b3&storm= c22d21",
"scene": null
},
{
"id": 2,
"name": "pages/river/river",
"pathName": "pages/river/river",
"query": "river=c796cd&storm=9092d5",
"scene": null
},
{
"id": -1,
"name": "pages/scans/scans",
"pathName": "pages/scans/scans",
"query": "river=c796cd&storm=9092d5",
"scene": null
},
{
"id": 4,
"name": "pages/action/action",
"pathName": "pages/action/action",
"query": "river=d82c1d&storm=12d1d7&title=mac.paste",
"scene": null
}
]
}
}
}

View File

@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@ -1,42 +0,0 @@
module.exports = {
Number: function(d, n) {var res = [];
while (d > 0) {res.push(d % 10); d = parseInt(d / 10); n--}
while (n > 0) {res.push("0"); n--}
return res.reverse(), res.join("");
},
Time: function(t, fmt) {var now = t? new Date(t): new Date();
fmt = fmt || "%y-%m-%d %H:%M:%S";
fmt = fmt.replace("%y", now.getFullYear())
fmt = fmt.replace("%m", Number(now.getMonth()+1, 2))
fmt = fmt.replace("%d", Number(now.getDate(), 2))
fmt = fmt.replace("%H", Number(now.getHours(), 2))
fmt = fmt.replace("%M", Number(now.getMinutes(), 2))
fmt = fmt.replace("%S", Number(now.getSeconds(), 2))
return fmt
},
Args: function(url, args) {var list = []
for (var k in args) {
list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k]))
}
return url+"?"+list.join("&")
},
List: function(list, cb, cbs) {var res = [], val;
for (var i = 0; i < list.length; i++) {
typeof cb == "function"? (val = cb(list[i], i, list)) != undefined && res.push(val): res.push(list[i])
}
return typeof cbs == "function" && cbs(res), res
},
Item: function(list, cb, cbs) {
for (var k in list) {
cb(k, list[k])
}
},
Value: function(item, key) {
var p = item, ls = key.split(".")
while (p && ls.length > 0) {
p = p[ls[0]], ls = ls.slice(1)
}
return p
},
}

View File

@ -1,50 +0,0 @@
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
function Number(d, n) {var res = [];
while (d > 0) {res.push(d % 10); d = parseInt(d / 10); n--}
while (n > 0) {res.push("0"); n--}
return res.reverse(), res.join("");
}
function Time(t, fmt) {var now = t? new Date(t): new Date();
fmt = fmt || "%y-%m-%d %H:%M:%S";
fmt = fmt.replace("%y", now.getFullYear())
fmt = fmt.replace("%m", Number(now.getMonth()+1, 2))
fmt = fmt.replace("%d", Number(now.getDate(), 2))
fmt = fmt.replace("%H", Number(now.getHours(), 2))
fmt = fmt.replace("%M", Number(now.getMinutes(), 2))
fmt = fmt.replace("%S", Number(now.getSeconds(), 2))
return fmt
}
function Args(url, args) {var list = []
for (var k in args) {
list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k]))
}
return url+"?"+list.join("&")
}
module.exports = {
formatTime: formatTime,
Time: Time,
Args: Args,
List: function(list, cb) {
var res = [], val;
for (var i = 0; i < list.length; i++) {
typeof cb == "function"? (val = cb(list[i], i, list)) != undefined && res.push(val): res.push(list[i])
}
return res
},
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

264
frame.js
View File

@ -3,14 +3,14 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
can.onappend._init(can, item, item.list, function(pane) {
pane.Status = function(key, value) { pane.run({}, ["search", "Footer.onimport."+key, value]) }
pane.onaction && pane.onappend._action(pane, pane._action, item._action||pane.onaction.list)
pane.onaction && pane.onappend._action(pane, pane._action, item.action||pane.onaction.list)
pane.run = function(event, cmds, cb, silent) { var msg = pane.request(event); cmds = cmds || []
return (can.onengine[cmds[0]]||can.onengine[meta.main.engine])(event, can, msg, pane, cmds, function(msg) {
return (can.onengine[cmds[0]]||can.onengine[meta.main.engine]||can.onengine.remote)(event, can, msg, pane, cmds, function(msg) {
typeof cb == "function" && cb(msg)
})
}, can[item.name] = pane, next()
}, target)
}, function() { can.onlayout._init(can, target)
}, function() {
can.require(meta.main.list, function(can) {
var pane = can[meta.main.name], msg = can.request({})
pane.onkeypop._init(pane, target), pane.onmotion._init(pane)
@ -19,69 +19,31 @@ Volcanos("onengine", {help: "解析引擎", list: [], _init: function(can, meta,
})
})
},
_daemon: function(can, name) {
can.misc.WSS(can, "", {type: "chrome", name: name}, function(event, msg, cmd, arg) {
if (msg.Option("_handle")) { return can.user.toast(can, msg.result.join("")) }
can.user.toast(can, msg.detail.join(" "))
switch (cmd) {
case "pwd":
msg.Echo("hello world")
break
default:
can.run(event, ["search"].concat(msg.detail), function(msg) {
msg.Reply(msg)
})
return
}
msg.Reply(msg)
}, function() { can.user.toast(can, "wss connect", "iceberg") })
_daemon: function(can, name, cb) {
can.misc.WSS(can, {type: "chrome", name: name}, cb||function(event, msg, cmd, arg) {
msg && can.run(event, ["search"].concat(msg["detail"]||[]), function(msg) {
msg.Reply()
})
})
},
search: function(event, can, msg, pane, cmds, cb) {
var sub, mod = can, fun = can; can.core.List(cmds[1].split("."), function(value, index, array) {
fun && (sub = mod, mod = fun, fun = mod[value])
}); if (!sub || !mod || !fun) { console.info("not found", cmds[1]); return }
return typeof fun == "function" && fun(sub, msg, cmds.slice(2), cb, sub._target)
var sub, mod = can, fun = can, key = ""; can.core.List(cmds[1].split("."), function(value) {
fun && (sub = mod, mod = fun, fun = mod[value], key = value)
}); if (!sub || !mod || !fun) { can.base.Warn("not found", cmds[1]); return }
return can.core.CallFunc(fun, {
"event": event, "can": sub, "msg": msg,
"cmd": key, "button": key, "cmds": cmds.slice(2),
"list": cmds.slice(2), "cb": cb, "target": sub._target,
}, mod)
},
remote: function(event, can, msg, pane, cmds, cb) {
if (can.onengine.engine(event, can, msg, pane, cmds, cb)) { return }
if (pane.onengine.engine(event, can, msg, pane, cmds, cb)) { return }
can.misc.Run(event, can, {names: pane._name}, cmds, cb)
pane.run(event, ["search", "Footer.onimport.ncmd"])
},
engine: function(event, can, msg, pane, cmds, cb) {
switch (pane._name) {
case "River":
cmds.length == 0 && can.core.Item(can.onengine.river, function(key, value) {
msg.Push({hash: key, name: value.name})
}); if (cmds.length != 1 && cmds[1] != "tool") { return false }
}, engine: function(event, can, msg, pane, cmds, cb) { return false },
var river = can.onengine.river[cmds[0]]; if (!river) { return false }
can.core.Item(river.storm, function(key, value) {
msg.Push({hash: key, name: value.name})
}), typeof cb == "function" && cb(msg); return true
case "Action":
var river = can.onengine.river[cmds[0]]
var storm = river && river.storm[cmds[1]]
if (!storm || cmds.length != 2) { break }
if (storm.index) {
can.misc.Run(event, can, {names: pane._name}, ["action", "command"].concat(storm.index), cb)
} else {
can.core.List(storm.action, function(value) {
msg.Push("name", value.name||"")
msg.Push("help", value.help||"")
msg.Push("inputs", JSON.stringify(value.inputs||[]))
msg.Push("feature", JSON.stringify(value.feature||{}))
msg.Push("index", value.index||"")
msg.Push("args", value.args||"[]")
}), typeof cb == "function" && cb(msg)
}
return true
}
return false
},
river: {
"serivce": {name: "运营群", storm: {
"wx": {name: "公众号 wx", action: [
@ -201,6 +163,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
var action = can.page.Select(can, field, "div.action")[0]
var output = can.page.Select(can, field, "div.output")[0]
var status = can.page.Select(can, field, "div.status")[0]
can.core.Value(meta, {"width": can._width, "height": can._height})
var sub = Volcanos(meta.name, {_follow: can._follow+"."+meta.name,
_legend: legend, _option: option, _action: action, _output: output, _status: status,
@ -282,7 +245,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
item === ""? /*空白*/ can.page.Append(can, action, [{view: "item space"}]):
typeof item == "string"? /*按键*/ can.onappend.input(can, action, "input", {type: "button", value: item, onclick: function(event) {
var cb = can.onaction[item] || can.onaction["_engine"] || can.onkeymap && can.onkeymap._remote
cb? cb(event, can, item): can.run(event, ["action", item], function(msg) {}, true)
typeof cb == "function"? cb(event, can, item): can.run(event, ["action", item], function(msg) {}, true)
}}): item.length > 0? /*列表*/ can.onappend.input(can, action, "input", {type: "select", name: item[0], values: item.slice(1), title: item[0], onchange: function(event) {
var which = item[event.target.selectedIndex+1]
var cb = can.onaction[which]
@ -302,7 +265,6 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
can.run(event, cmds||[], function(msg) {
if (can.onimport._process(can, msg, cmds, cb)) { return }
typeof cb == "function" && cb(msg)
if (silent) { return }
@ -331,7 +293,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
},
_detail: function(can, target, list, cb) {
list.length > 0 && (target.oncontextmenu = function(event) {
can.user.carte(can, can.ondetail||{}, list, function(ev, item, meta) {
can.user.carte(event, can, can.ondetail||{}, list, function(ev, item, meta) {
(cb||can.ondetail[item]||can.onaction[item])(event, can, item)
})
})
@ -346,7 +308,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
item: function(can, target, type, item, cb, cbs) {
var ui = can.page.Append(can, target, [{view: [type, "div", item.nick||item.name],
click: function(event) {
onclick: function(event) {
can.page.Select(can, target, "div."+type, function(item) {
can.page.ClassList.del(can, item, "select")
}), can.page.ClassList.add(can, ui.item, "select")
@ -426,61 +388,58 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
return text && can.page.Append(can, target, [{view: ["code", "div", text]}]).code
},
plugin: function(can, value, cb, target) { value = value || {}
can.run({}, ["action", "command", value.index], function(msg) {
value.feature = can.base.Obj(msg.meta&&msg.meta[0] || "{}", {})
value.inputs = can.base.Obj(msg.list&&msg.list[0] || "[]", [])
plugin: function(can, meta, cb, target) { meta = meta || {}
can.run({}, ["action", "command", meta.index], function(msg) {
meta.feature = can.base.Obj(msg.meta&&msg.meta[0] || "{}", {})
meta.inputs = can.base.Obj(msg.list&&msg.list[0] || "[]", [])
value.name = value.name || msg.name&&msg.name[0] || "story"
value.help = value.help || msg.help&&msg.help[0] || "story"
value.width = can._target.offsetWidth
value.type = "story"
meta.name = meta.name || msg.name&&msg.name[0] || "story"
meta.help = meta.help || msg.help&&msg.help[0] || "story"
meta.width = can._target.offsetWidth
meta.type = "story"
can.onappend._init(can, value, ["/plugin/state.js"], function(story) {
can.onappend._init(can, meta, ["/plugin/state.js"], function(story) {
typeof cb == "function" && cb(story, meta)
story.page.Remove(story, story._legend)
typeof cb == "function" && cb(story, value)
}, target || can._output)
}, true)
},
}, [], function(can) {})
Volcanos("onlayout", {help: "页面布局", list: [], _init: function(can, target) {
if (can.user.Search(can, "share")) { return }
var width = can._width, height = can._height
can.page.Select(can, target, "fieldset.head", function(field) {
height -= field.offsetHeight + 15
})
can.page.Select(can, target, "fieldset.foot", function(field) {
Volcanos("onlayout", {help: "页面布局", list: [], _init: function(can, target, width, height) {
can.page.Select(can, target, ["fieldset.head", "fieldset.foot"], function(field) {
can.page.Modify(can, field, {style: {display: can.user.isMobile && width > height? "none": ""}})
height -= field.offsetHeight
})
can.page.Select(can, target, ["fieldset.middle"], function(field, index) {
var border = field.offsetHeight - field.clientHeight
can.page.Modify(can, field, { style: {
height: height-border*2+"px",
} })
can.page.Select(can, field, "div.output", function(output) {
var border = output.offsetHeight - output.clientHeight
can.page.Modify(can, output, { style: {
height: height-border*2-14+"px",
} })
})
})
can.page.Select(can, target, ["fieldset.left", "fieldset.right"], function(field, index) {
var border = field.offsetHeight - field.clientHeight
can.page.Modify(can, field, { style: {
height: height-border*2+"px",
} })
can.page.Modify(can, field, {style: {height: height-4}})
can.page.Select(can, field, "div.output", function(output) {
var border = output.offsetHeight - output.clientHeight
can.page.Modify(can, output, { style: {
height: height-border*2-40+"px",
} })
can.page.Modify(can, output, {style: {height: height-26}})
})
width -= field.offsetWidth
})
can.Action._width = width, can.Action._height = height
if (can.user.isMobile) { return }
can.page.Select(can, target, ["fieldset.middle"], function(field, index) {
var border = field.offsetHeight - field.clientHeight
can.page.Modify(can, field, {style: {height: height-border*2}})
})
can.page.Select(can, target, ["fieldset.middle>div.output"], function(output) {
var border = output.offsetHeight - output.clientHeight
can.page.Modify(can, output, {style: {height: height-border*2-14}})
})
can.core.List(can.onlayout.resize.list, function(item) {
item(width, height)
})
},
resize: shy("", {}, [], function(cb) { arguments.callee.list.push(cb) }),
})
Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, target) {
can.core.Item(can.onkeypop._mode, function(item, value) { var engine = {}
@ -500,7 +459,8 @@ Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, targe
}
},
_parse: function(event, can, target, mode, list) {
event.key.length == 1 && list.push(event.key)
// event.key.length == 1 &&
list.push(event.key)
can.Status && can.Status("keys", list.join(""))
for (var pre = 0; pre < list.length; pre++) {
@ -532,7 +492,8 @@ Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, targe
normal: {
j: function(event, can, target) { target.scrollBy(0, 30) },
k: function(event, can, target) { target.scrollBy(0, -30) },
hello: function(event, can, target) { can.base.Log("nice") },
b: function(event, can, target) { can.run(event, ["search", "Header.onaction.black"]) },
w: function(event, can, target) { can.run(event, ["search", "Header.onaction.white"]) },
" ": function(event, can, target) {
can.page.Select(can, document.body, "fieldset.pane.Header div.search input", function(target) {
@ -614,7 +575,7 @@ Volcanos("onkeypop", {help: "键盘交互", list: [], _init: function(can, targe
},
}, _engine: {},
input: function(event, can, local) { var target = event.target
input: function(event, can) { var target = event.target
target._keys = can.onkeypop._parse(event, can, target, event.ctrlKey? "insert_ctrl": "insert", target._keys||[])
if (target._keys.length == 0) { event.stopPropagation(), event.preventDefault() }
},
@ -633,44 +594,6 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can) {
})
})
},
modifys: function(can, target, cb) { var back = target.innerHTML
var ui = can.page.Appends(can, target, [{type: "textarea", value: back, style: {height: "80px"}, onkeydown: function(event) {
switch (event.key) {
case "Enter":
if (event.ctrlKey) { target.innerHTML = event.target.value
if (event.target.value != back) {
cb(event, event.target.value, back)
}
}
break
case "Escape":
td.innerHTML = back
break
}
}, onkeyup: function(event) {
}}]); ui.first.focus(), ui.first.setSelectionRange(0, -1)
},
modify: function(can, target, cb) { var back = target.innerHTML
var ui = can.page.Appends(can, target, [{type: "input", value: back, onkeydown: function(event) {
switch (event.key) {
case "Enter":
target.innerHTML = event.target.value
if (event.target.value != back) {
cb(event, event.target.value, back)
}
break
case "Escape":
td.innerHTML = back
break
}
}, onkeyup: function(event) {
}}]); ui.first.focus(), ui.first.setSelectionRange(0, -1)
},
clear: function(can, target) { target = target || can._output
target.innerHTML = ""
},
show: function(can, time, cb, target) { target = target || can._target
time = typeof time == "object"? time: {value: 10, length: time||20}
@ -687,7 +610,58 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can) {
can.page.Modify(can, target, {style: {opacity: 1-(index+1)/time.length}})
}, cb)
},
clear: function(can, target) {
can.page.Modify(can, target||can._output, "")
},
modify: function(can, target, cb) { var back = target.innerHTML
var ui = can.page.Appends(can, target, [{type: "input", value: back, onkeydown: function(event) {
switch (event.key) {
case "Enter":
target.innerHTML = event.target.value
if (event.target.value != back) {
cb(event, event.target.value, back)
}
break
case "Escape":
target.innerHTML = back
break
default:
can.onkeypop.input(event, can)
}
}}]); ui.first.focus(), ui.first.setSelectionRange(0, -1)
},
modifys: function(can, target, cb) { var back = target.innerHTML
var ui = can.page.Appends(can, target, [{type: "textarea", value: back, style: {height: "80px"}, onkeydown: function(event) {
switch (event.key) {
case "Enter":
if (event.ctrlKey) {
target.innerHTML = event.target.value
if (event.target.value != back) {
cb(event, event.target.value, back)
}
}
break
case "Escape":
target.innerHTML = back
break
default:
can.onkeypop.input(event, can)
}
}}]); ui.first.focus(), ui.first.setSelectionRange(0, -1)
},
autosize: function(can, msg, list, cb, target) {
can.page.Select(can, target, "div.output", function(item, index) {
index == 0 && (item.style.height = "")
}), target.style.height = ""
typeof cb == "function" && cb(msg)
},
hidden: function(can, msg, list, cb, target) {
can.page.Modify(can, target, {style: {display: "none"}})
},
toggle: function(can, msg, list, cb, target) {
can.page.Toggle(can, target)
},
move: function(can, target, layout) { var begin
target.onmousedown = function(event) {
begin = {x: event.x, y: event.y, left: layout.left, top: layout.top, width: layout.width, height: layout.height}
@ -706,15 +680,5 @@ Volcanos("onmotion", {help: "动态交互", list: [], _init: function(can) {
}
}
},
toggle: function(can, msg, list, cb, target) {
can.page.Toggle(can, target)
},
autosize: function(can, msg, list, cb, target) {
can.page.Select(can, target, "div.output", function(item, index) {
index == 0 && (item.style.height = "")
})
target.style.height = ""
},
})

View File

@ -1,3 +1,60 @@
body.mobile fieldset.Header.head {
position:fixed;
width:-webkit-fill-available;
height:48px; font-size:24px;
background-color:#000000b8;
z-index:10;
}
body.mobile fieldset.Footer.foot {
position:fixed; bottom:0px;
width:-webkit-fill-available;
height:64px; font-size:24px;
background-color:#000000b8;
z-index:10;
}
body.mobile fieldset.Action fieldset>form.option {
padding:0 5px;
height:36px;
min-width:640px;
}
body.mobile fieldset.Action {
padding-top:48px;
}
body.mobile fieldset.River {
font-size:24px;
min-width:240px;
position:fixed;
z-index:10;
background-color:#243950bf;
top:56px;
}
body.mobile input {
font-size:18px;
}
body.mobile select {
font-size:18px;
}
fieldset.River>div.output div.list {
margin-left:8px;
padding-left:5px;
}
fieldset.River>div.output div.item {
border-left:solid 3px #00ffae;
}
fieldset.River>div.output div.list div.item {
border-left:solid 3px #ccdc4c;
background-color:#181d15;
}
fieldset.River>div.output div.list div.item:hover {
cursor:pointer;
background-color:#2e515f;
}
fieldset.River>div.output div.list div.item.select {
border-left:solid 3px #ccdc4c;
background-color:#2e515f;
}
body {
margin:0; padding:0;
background:black;
@ -32,6 +89,7 @@ table {
border:0; white-space: pre;
font-size:14px; font-family:monospace;
cursor:pointer; overflow: auto;
background:#04272f;
}
table tr:hover {
background-color:#0fbd45;
@ -178,7 +236,6 @@ fieldset>div.output>pre.display:hover {
fieldset.input {
background-color:black;
position:fixed;
left:0; top:0;
}
fieldset.input {
z-index:99;
@ -190,10 +247,32 @@ fieldset.input.key {
z-index:101;
}
fieldset.Header>div.output>div.menus {
margin-left:5px;
cursor:pointer;
float:left;
}
fieldset.Header>div.output>div.menus:hover {
background:gray;
}
div.menu {
position:absolute;
background:#295b61;
color:white;
padding:4px;
}
div.menu div.item {
padding:3px 12px;
cursor:pointer;
}
div.menu div.item:hover {
background:red;
}
div.toast {
color:yellow;
background:#0e3369b3;
border:solid 2px red;
border:solid 2px #0c8e4c;
position:fixed;
padding:5px;
z-index:100;
@ -343,3 +422,4 @@ fieldset.max>form.option>div.item textarea.args {
width:500px;
height:120px;
}

View File

@ -1,6 +1,6 @@
<!DOCTYPE html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=0.7,user-scalable=no">
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<meta charset="utf-8">
<title>volcanos</title>
<link rel="shortcut icon" type="image/ico" href="favicon.ico">

View File

@ -1,9 +1,8 @@
_can_name = ""
Volcanos({name: "chat", iceberg: "/chat/", volcano: "/frame.js",
libs: ["/lib/base.js", "/lib/core.js", "/lib/misc.js", "/lib/page.js", "/lib/user.js"], panes: [
{name: "Header", help: "标题栏", pos: "head", state: ["time", "username"]},
{name: "Search", help: "搜索框", pos: "float"},
{name: "River", help: "群聊组", pos: "left"},
{name: "River", help: "群聊组", pos: "left", action: ["创建", "刷新"]},
{name: "Action", help: "工作台", pos: "middle"},
{name: "Footer", help: "状态条", pos: "foot", state: ["ncmd", "keys"]},
], main: {name: "Header", engine: "remote", list: ["/publish/order.js"]}, plugin: [

View File

@ -8,6 +8,37 @@ Volcanos("base", {help: "基础模块",
}
},
URLMerge: function(url) { var args = {}
var arg = url.split("?")[1]||""
arg && arg.split("&").forEach(function(item) {
var ls = item.split("=")
args[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1])
})
for (var i = 1; i < arguments.length; i++) {
switch (typeof arguments[i]) {
case "object":
if (arguments[i].length > 0) {
for (var j = 0; j < arguments[i].length; j += 2) {
args[arguments[i][j]] = arguments[i][j]
}
break
}
for (var k in arguments[i]) {
args[k] = arguments[i][k]
}
break
case "string":
args[arguments[i]] = arguments[i+1]
i++
break
}
}
var list = []; for (var k in args) {
list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k]))
}
return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "")
},
Ext: function(file) { return (file.split("/").pop().split(".").pop()||"txt").toLowerCase() },
Path: function() { var res = ""
for (var i = 0; i < arguments.length; i++) {
@ -98,24 +129,32 @@ Volcanos("base", {help: "基础模块",
return parseInt(size)
},
_fileLine: function() { var obj = {}; Error.captureStackTrace(obj, arguments.callee); return obj.stack },
FileLine: function(depth) { return this._fileLine().split("\n")[1+depth].trim() },
_fileLine: function() { var obj = {}
Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee)
return obj.stack || ""
},
fileLine: function(depth) {
return (this._fileLine().split("\n")[1+depth]||"").trim()
},
FileLine: function(depth, length) {
return this.fileLine(depth+1).split("/").slice(3).slice(-length).join("/").split(")")[0]
},
Log: function() {
var args = [this.Time(), this.FileLine(2, 3).split("/").slice(3).slice(-length).join("/") ]
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3)]
for (var i in arguments) { args.push(arguments[i]) }
console.log.apply(console, args)
},
Logs: function() {
var args = [this.Time()]
for (var i in arguments) { args.push(arguments[i]) }
args.push(this.FileLine(2, 3))
console.log.apply(console, args)
},
Error: function() {
var args = [this.Time()]
Warn: function() {
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3), "error"]
for (var i in arguments) { args.push(arguments[i]) }
args.push("\n", this._fileLine().split("\n").slice(2).join("\n"))
console.log.apply(console, args)
},
Debug: function() {
var args = [this.Time(null, "%H:%M:%S"), this.FileLine(2, 3), "warn"]
for (var i in arguments) { args.push(arguments[i]) }
args.push(this.fileLine(2, 3))
console.log.apply(console, args)
},
})

View File

@ -55,6 +55,35 @@ Volcanos("core", {help: "核心模块",
next(obj, cb, 0)
}),
Value: function(data, key, value) {
if (key == undefined) { return data }
if (typeof key == "object") { for (var k in key) {
arguments.callee.call(this, data, k, key[k])
}; return data }
if (value != undefined) { data[key] = value }
if (data[key] != undefined) { return data[key] }
var p = data, ls = key.split("."); while (p && ls.length > 0) {
p = p[ls[0]], ls = ls.slice(1)
}; return p
},
CallFunc: shy("调用器", function(func, args, mod) {
func = typeof func == "string"? this.Value(mod, func): func
if (typeof func != "function") { return }
var ls = func.toString(); ls = ls.split(")")[0], ls = ls.split("(")[1]
var echo = false
var list = []; this.List(ls.split(","), function(item) {
list.push(args[item.trim()]||args)
if (item == "cb") { echo = true}
})
var res = typeof func == "function" && func.apply(mod||this, list)
if (!echo && typeof args.cb == "function") { res && args.msg.Echo(res), args.cb(args.msg) }
return res
}),
Split: shy("分词器", function(str) { if (!str || !str.length) { return [] }
var opt = {simple: false}, arg = []; for (var i = 1; i < arguments.length; i++) {
typeof arguments[i] == "object"? opt = arguments[i]: arg.push(arguments[i])

View File

@ -1,26 +1,22 @@
Volcanos("misc", {help: "工具模块",
Message: function(event, can) { var msg = {}
Volcanos("misc", {help: "工具模块", Message: function(event, can) { var msg = {}
msg.__proto__ = {_event: event, _can: can,
Option: function(key, val) {
if (key == undefined) { return msg && msg.option || [] }
if (typeof key == "object") { can.core.Item(key, msg.Option) }
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)
return val
return msg[key] = can.core.List(arguments).slice(1), val
},
Append: function(key, val) {
if (key == undefined) { return msg && msg.append || [] }
if (typeof key == "object") { can.core.Item(key, msg.Append) }
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
msg.append = msg.append || [], can.core.List(msg.append, function(k) { if (k == key) { return k } }).length > 0 || msg.append.push(key)
msg[key] = can.core.List(arguments).slice(1)
return val
return msg[key] = can.core.List(arguments).slice(1), val
},
Result: function() {
return msg.result && msg.result.join("") || ""
},
Table: function(cb) { if (!msg.append || !msg.append.length || !msg[msg.append[0]]) { return }
Result: function() { return msg.result && msg.result.join("") || "" },
Table: function(cb) { if (!msg.append || msg.append.length == 0 || !msg[msg.append[0]]) { return }
var max = "", len = 0; can.core.List(msg.append, function(key, index) {
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length }
})
@ -34,11 +30,8 @@ Volcanos("misc", {help: "工具模块",
switch (key) {
case "append":
case "option":
can.core.List(msg[key], function(item) {
delete(msg[item])
})
default:
msg[key] = []
can.core.List(msg[key], function(item) { delete(msg[item]) })
default: msg[key] = []
}
},
Copy: function(res) { if (!res) { return msg }
@ -53,22 +46,19 @@ Volcanos("misc", {help: "工具模块",
},
Push: function(key, value, detail) { msg.append = msg.append || []
if (typeof key == "object") {
value = value || can.core.Item(key)
can.core.List(value, function(item) {
value = value || can.core.Item(key), can.core.List(value, function(item) {
detail? msg.Push("key", item).Push("value", key[item]||""):
msg.Push(item, key[item]||"")
})
return
return msg
}
for (var i = 0; i < msg.append.length; i++) {
if (msg.append[i] == key) {
break
}
}
if (i >= msg.append.length) { msg.append.push(key) }
if (msg.append[i] == key) { break }
}; i >= msg.append.length && msg.append.push(key)
msg[key] = msg[key] || []
msg[key].push(""+(typeof value == "object"? JSON.stringify(value): value)+"")
msg[key].push(""+(typeof value == "string"? value: JSON.stringify(value))+"")
return msg
},
Echo: function(res) { msg.result = msg.result || []
@ -79,130 +69,93 @@ Volcanos("misc", {help: "工具模块",
return msg
},
POST: shy("请求后端", {order: 0}, function(can, msg, url, form, cb) {
var xhr = new XMLHttpRequest()
var xhr = new XMLHttpRequest(); msg._xhr = xhr
xhr.open("POST", url), xhr.onreadystatechange = function() {
if (xhr.readyState != 4) {return}
if (xhr.readyState != 4) { return }
switch (xhr.getResponseHeader("content-type")) {
case "image/png":
if (xhr.responseType != "blob") {
msg.responseType = "blob"
can.misc.POST(can, msg, url, form, cb)
return
}
break
default:
try { // 解析响应
var res = JSON.parse(xhr.responseText)
} catch (e) {
var res = {"result": [xhr.responseText]}
}
try { // 解析响应
var res = JSON.parse(xhr.responseText)
} catch (e) {
var res = {"result": [xhr.responseText]}
}
xhr.status == 200 && typeof cb == "function" && cb(msg.Copy(res))
}
if (msg.upload) {
// 文件参数
if (msg.upload) { // 上传文件
var data = new FormData()
can.core.Items(form, function(value, index, key) {
data.append(key, item)
data.append(key, value)
}), data.append("upload", msg.upload)
xhr.upload.onprogress = function(event) {
typeof msg._progress == "function" && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded)
}
} else {
// 表单参数
} else { // 请求数据
var data = can.core.Items(form, function(value, index, key) {
return key+"="+encodeURIComponent(value)
}).join("&")
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
// 发送请求
++arguments.callee.meta.order
xhr.setRequestHeader("Accept", "application/json")
xhr.responseType = msg.responseType || ""
try {
xhr.send(data)
} catch(e) {
console.error(e)
cb == "function" && cb(msg)
}
msg._xhr = xhr
try { xhr.send(data) } catch(e) { can.base.Log(e) }
}),
Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmd, cb) {
Run: shy("请求后端", {order: 0}, function(event, can, dataset, cmds, cb) {
var msg = can.request(event = event || {})
// 解析参数
var option = {cmds: cmd||msg.cmd}
var form = {cmds: cmds||msg.cmd}
msg.option && msg.option.forEach(function(item) {
msg[item] && (option[item] = msg[item])
})
msg.option = can.core.Item(option, function(key, value) {
return msg[key] = value, key
msg[item] && (form[item] = msg[item])
})
msg._hand = true, can.misc.POST(can, msg, can.Conf("iceberg")+(msg.names||dataset.names||event.names||"").toLowerCase()+"?="+(msg._can.sup||msg._can)._name, option, function(msg) {
can.misc.POST(can, msg, can.Conf("iceberg")+dataset.names.toLowerCase()+"?="+(msg._can.sup||msg._can)._name, form, function(msg) {
typeof cb == "function" && cb(msg)
}), delete(event.msg)
})
}),
WSS: shy("请求后端", {order: 0}, function(can, url, args, cb, onopen, onerror, onclose) {var meta = arguments.callee.meta
if (url.indexOf("ws") == -1) {
url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/" + (url||"")
}
if (url.indexOf("chrome") == 0) {
url = "ws://localhost:9020/space/"
}
WSS: shy("请求后端", {order: 0}, function(can, args, cb, onopen, onclose, onerror) {
var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/"
if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" }
if (can._socket) {return can._socket}
args["share"] = can._share || ""
can._socket = new WebSocket(url+"?"+can.base.Args(args))
can._socket.onclose = onclose || function() {if (!can._socket) {return}
console.log("socket close")
delete(can._socket), setTimeout(function() {
// 断线重连
var socket = new WebSocket(can.base.URLMerge(url, args))
socket.onclose = function() { can.base.Log("wss", "close", args)
typeof onclose == "function"? onclose(socket): can.core.Timer(1000, function() {
can.misc.WSS(can, url, args, cb, onopen, onerror, onclose)
}, 1000)
}, can._socket.onerror = onerror || function() {if (!can._socket) {return}
console.log("socket error")
can._socket.close(), delete(can._socket), setTimeout(function() {
// 断线重连
can.misc.WSS(can, url, args, cb, onerror, onclose, onopen)
}, 1000)
}, can._socket.onopen = onopen || function() {
})
}, socket.onerror = function() { can.base.Log("wss", "error", args)
typeof onerror == "function"? onerror(socket): socket.close()
}, socket.onopen = function() { can.base.Log("wss", "open", args)
typeof onopen == "function" && onopen(socket)
}
can._socket.onmessage = function(event) {var order = ++meta.order
socket.onmessage = function(event) {
try { // 解析命令
var data = JSON.parse(event.data)
} catch (e) {
var data = {"result": [event.data]}
var data = {"detail": [event.data]}
}
var msg = can.request(event); msg.Reply = function() {
msg.result = (msg.result||[]).concat(can.core.List(arguments))
// 回复命令
delete(msg._can)
delete(msg._event)
msg.Option("_handle", true)
msg.Option("_target", msg.Option("_source"))
console.log(["wss", order, "result"].concat(msg.result).concat([msg]))
can._socket.send(JSON.stringify(msg))
can.base.Log("wss", "result", msg.result, msg)
socket.send(JSON.stringify(msg))
}, msg.detail = data.detail, msg.Copy(data)
try { // 执行命令
console.log(["wss", order].concat(msg.detail).concat([msg]))
can.base.Log("wss", "detail", msg.detail, msg)
typeof cb == "function" && cb(event, msg, msg.detail[0], msg.detail.slice(1))
} catch (e) { // 执行失败
console.log(e)
can.base.Log(e)
msg.Reply(e)
}
}
return can._socket
}),
})

View File

@ -1,20 +1,20 @@
Volcanos("page", {help: "网页模块",
ClassList: {
has: function(can, obj, key) {var list = obj.className? obj.className.split(" "): [];
has: function(can, obj, key) {var list = obj.className? obj.className.split(" "): []
for (var i = 2; i < arguments.length; i++) {
if (list.indexOf(arguments[i]) == -1) {return false}
}
return true;
return true
},
add: function(can, obj, key) {var list = obj.className? obj.className.split(" "): []
return obj.className = list.concat(can.core.List(key, function(value, index) {
return list.indexOf(value) == -1? value: undefined;
})).join(" ").trim();
return list.indexOf(value) == -1? value: undefined
})).join(" ").trim()
},
del: function(can, obj, key) {var list = can.core.List(arguments, function(value, index) {return index > 0? value: undefined})
return obj.className = can.core.List(obj.className.split(" "), function(value) {
return list.indexOf(value) == -1? value: undefined;
}).join(" ").trim();
return list.indexOf(value) == -1? value: undefined
}).join(" ").trim()
},
set: function(can, obj, key, condition) {
condition? can.page.ClassList.add(can, obj, key): can.page.ClassList.del(can, obj, key)
@ -25,11 +25,11 @@ Volcanos("page", {help: "网页模块",
},
Select: shy("选择节点", function(can, obj, key, cb, interval, cbs) {if (key == ".") {return []}
var item = obj && obj.querySelectorAll(key);
return can.core.List(item, cb, interval, cbs);
var item = obj && obj.querySelectorAll(key)
return can.core.List(item, cb, interval, cbs)
}),
Modify: shy("修改节点", function(can, target, value) {
target = typeof target == "string"? document.querySelector(target): target;
target = typeof target == "string"? document.querySelector(target): target
typeof value == "string"? (target.innerHTML = value): can.core.Item(value, function(key, value) {
typeof value != "object"? (target[key] = value): can.core.Item(value, function(sub, value) {
var size = {
@ -38,29 +38,27 @@ Volcanos("page", {help: "网页模块",
"left": true, "right": true, "top": true, "bottom": true,
"margin-top": true, "margin-left": true,
}
if (size[sub] && (typeof value == "number" || !value.endsWith("px"))) {
if (size[sub] && value && (typeof value == "number" || !value.endsWith("px"))) {
value += "px"
}
target[key] && (target[key][sub] = value);
target[key] && (target[key][sub] = value)
})
});
return target;
})
return target
}),
Create: shy("创建节点", function(can, key, value) {
return can.page.Modify(can, document.createElement(key), value);
return can.page.Modify(can, document.createElement(key), value)
}),
Append: shy("添加节点", function(can, target, key, value) {
if (typeof key == "string") {var res = can.page.Create(can, key, value); return target.appendChild(res), res}
if (typeof key == "string") { var res = can.page.Create(can, key, value); return target.appendChild(res), res }
value = value || {}
can.core.List(key, function(item, index) {if (!item) {return}
if (item.nodeName) {
target.appendChild(item)
return
}
can.core.List(key, function(item, index) { if (!item) { return }
if (item.nodeName) { target.appendChild(item); return }
// 基本结构: type name data list
var type = item.type || "div", data = item.data || {};
var name = item.name || data.name || "";
var type = item.type || "div", data = item.data || {}
var name = item.name || data.name || ""
// 数据调整
can.core.Item(item, function(key, value) {
@ -71,111 +69,110 @@ Volcanos("page", {help: "网页模块",
case "list":
break
case "click":
data.onclick = item.click;
data.onclick = item.click
break
case "inner":
data.innerHTML = item.inner;
data.innerHTML = item.inner
break
default:
data[key] = item[key];
data[key] = item[key]
}
})
if (item.view) {var list = can.core.List(item.view);
(list.length > 0 && list[0]) && can.page.ClassList.add(can, data, list[0]);
type = list[1] || "div";
data.innerHTML = list[2] || data.innerHTML || "";
name = name || list[3] || "";
if (item.view) { var list = can.core.List(item.view)
list.length > 0 && list[0] && can.page.ClassList.add(can, data, list[0])
type = list[1] || "div"
data.innerHTML = can.user.trans(can, list[2]) || data.innerHTML || ""
name = name || list[3] || ""
} else if (item.text) {var list = can.core.List(item.text);
data.innerHTML = list[0] || data.innerHTML || "";
type = list[1] || "span";
list.length > 2 && (data.className = list[2]);
} else if (item.text) { var list = can.core.List(item.text)
data.innerHTML = can.user.trans(can, list[0]) || data.innerHTML || ""
type = list[1] || "span"
list.length > 2 && list[2] && can.page.ClassList.add(can, data, list[2])
} else if (item.button) {var list = can.core.List(item.button);
type = "button", name = name || list[0];
data.value = data.value || name;
data.innerText = list[0], data.onclick = function(event) {
typeof list[1] == "function" && list[1](event, name);
} else if (item.button) { var list = can.core.List(item.button)
type = "button", name = name || list[0]
data.value = data.value || name
data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) {
typeof list[1] == "function" && list[1](event, name)
event.stopPropagation()
event.preventDefault()
return true
}
} else if (item.select) {var list = item.select;
type = "select", name = name || list[0][0];
} else if (item.select) { var list = item.select
type = "select", name = name || list[0][0]
data.onchange = function(event) {
typeof list[1] == "function" && list[1](event, event.target.value, name);
typeof list[1] == "function" && list[1](event, event.target.value, name)
}
item.list = list[0].slice(1).map(function(value) {
return {type: "option", value: value, inner: value};
return {type: "option", value: value, inner: can.user.trans(can, value)}
})
data.className = data.className || list[0][0] || "";
data.title = data.title || name;
data.name = name;
data.className = data.className || list[0][0] || ""
data.title = can.user.trans(can, data.title || name)
data.name = name
} else if (item.input) {var list = can.core.List(item.input)
} else if (item.input) { var list = can.core.List(item.input)
type = "input", name = name || list[0] || ""
data.name = data.name || name
data.className = data.className || data.name
data.placeholder = data.placeholder || data.name
data.placeholder = data.placeholder.split(".").pop()
data.title = data.title || data.placeholder
data.placeholder = can.user.trans(can, data.placeholder.split(".").pop())
data.title = can.user.trans(can, data.title || data.placeholder)
data.autocomplete = "none"
data.onfocus = data.onfocus || function(event) {
event.target.setSelectionRange(0, -1)
}
data.onkeydown = function(event) {
typeof list[1] == "function" && list[1](event);
typeof list[1] == "function" && list[1](event)
}
data.onkeyup = function(event) {
typeof list[2] == "function" && list[2](event);
typeof list[2] == "function" && list[2](event)
}
} else if (item.username) {var list = can.core.List(item.username);
type = "input", name = name || list[0] || "username";
data.name = data.name || name;
data.className = list[1] || data.className || data.name;
data.placeholder = data.placeholder || data.name;
data.title = data.title || data.placeholder;
} else if (item.username) { var list = can.core.List(item.username)
type = "input", name = name || list[0] || "username"
data.name = data.name || name
data.className = list[1] || data.className || data.name
data.placeholder = data.placeholder || data.name
data.title = data.title || data.placeholder
data.autocomplete = data.autocomplete || "username"
} else if (item.password) {var list = can.core.List(item.password);
type = "input", name = name || list[0] || "password";
} else if (item.password) { var list = can.core.List(item.password)
type = "input", name = name || list[0] || "password"
data.type = "password"
data.name = data.name || name;
data.className = list[1], data.className || data.name;
data.placeholder = data.placeholder || data.name;
data.title = data.title || data.placeholder;
data.name = data.name || name
data.className = list[1], data.className || data.name
data.placeholder = data.placeholder || data.name
data.title = data.title || data.placeholder
data.autocomplete = data.autocomplete || "current-password"
} else if (item.img) {var list = can.core.List(item.img);
type = "img";
data.src = list[0];
} else if (item.img) { var list = can.core.List(item.img)
type = "img"
data.src = list[0]
} else if (item.row) {type = "tr";
} else if (item.row) { type = "tr"
item.list = item.row.map(function(text) {return {text: [text, item.sub||"td"]}})
} else if (item.th) {type = "tr";
} else if (item.th) { type = "tr"
item.list = item.th.map(function(text) {return {text: [text, "th"]}})
} else if (item.td) {type = "tr";
} else if (item.td) { type = "tr"
item.list = item.td.map(function(text) {return {text: [text, "td"]}})
} else if (item.include) {var list = can.core.List(item.include)
type = "script";
data.src = list[0];
data.onload = list[1];
type = "script"
data.src = list[0]
data.onload = list[1]
}
// 创建节点
name = name || data.className || type || "";
name = name || data.className || type || ""
!data.name && item.name && (data.name = item.name)
var node = can.page.Create(can, type, data)
value.last = node, value.first = value.first || node, value[name||""] = value[data.className||""] = value[type] = node
item.list && can.page.Append(can, node, item.list, value)
target && target.append && target.append(node)
typeof item._init == "function" && item._init(node)
target && target.append && target.append(node)
})
return value
}),
@ -199,24 +196,24 @@ Volcanos("page", {help: "网页模块",
AppendTable: shy("添加表格", function(can, msg, target, list, cb) {
if (!msg.append || msg.append.length == 0) {return}
var table = can.page.Append(can, target, "table");
var tr = can.page.Append(can, table, "tr", {dataset: {index: -1}});
var table = can.page.Append(can, target, "table")
var tr = can.page.Append(can, table, "tr", {dataset: {index: -1}})
can.core.List(list, function(key, index) {if (key.indexOf("_") == 0) {return}
key = can.Conf("feature.table.trans."+key) || {}[key] || key
can.page.Append(can, tr, "th", key.trim()).onclick = function(event) {
var dataset = event.target.dataset;
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1;
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1");
var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
});
})
can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) {
return {type: "tr", dataset: {index: index}, list: can.core.List(list, function(key) {if (key.indexOf("_") == 0) {return}
return cb(can.page.Display(line[key]).trim(), key, index, line, array)
})}
}))
return table;
return table
}),
RangeTable: function(can, table, index, sort_asc) {
var list = can.page.Select(can, table, "tr", function(tr) {
@ -238,7 +235,7 @@ Volcanos("page", {help: "网页模块",
// 选择排序
for (var i = 0; i < num_list.length; i++) {
var min = i;
var min = i
for (var j = i+1; j < num_list.length; j++) {
if (sort_asc? num_list[min] <= num_list[j]: num_list[min] >= num_list[j]) {
min = j
@ -262,9 +259,9 @@ Volcanos("page", {help: "网页模块",
OrderTable: function(can, table) {
can.page.Select(can, table, "th", function(th, index) {
table.onclick = function(event) {
var dataset = event.target.dataset;
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1;
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1");
var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
})
},
@ -286,7 +283,7 @@ Volcanos("page", {help: "网页模块",
text = text.replace(/\033\[0m/g, "</span>")
text = text.replace(/\033\[m/g, "</span>")
text = text.replace(/\\n/g, "<br>")
return text;
return text
},
Format: function(type) {
switch (type) {
@ -373,21 +370,21 @@ Volcanos("page", {help: "网页模块",
},
Prepos: function(event, item, p, q) {
var max = 20
p = p || item.getBoundingClientRect();
p = p || item.getBoundingClientRect()
q = q || {x: event.clientX, y: event.clientY}
var pos = 5;
var pos = 5
var y = (q.y - p.y) / p.height
if (y < 0.2 && q.y - p.y < max) {
pos -= 3;
pos -= 3
} else if (y > 0.8 && q.y - p.y - p.height > -max) {
pos += 3;
pos += 3
}
var x = (q.x - p.x) / p.width
if (x < 0.2 && q.x - p.x < max) {
pos -= 1;
pos -= 1
} else if (x > 0.8 && q.x - p.x - p.width > -max) {
pos += 1;
pos += 1
}
var cursor = [

View File

@ -47,8 +47,12 @@ Volcanos("user", {help: "用户模块", agent: {
can.user.toast(can, {text: text, title: "复制成功", width: 400})
},
trans: function(can, text) {
return can._trans && can._trans[text] || text
},
topic: function(can, name) {
can.page.Modify(can, document.body, {className: name})
if (can.user.isMobile) { can.page.ClassList.add(can, document.body, "mobile") }
},
toast: function(can, text, title, duration, progress) {
var meta = typeof text == "object"? text: {text: text, title: title||can._help, duration: duration, progress: progress}
@ -82,29 +86,6 @@ Volcanos("user", {help: "用户模块", agent: {
}]}] })
})
},
carte: function(can, meta, list, cb) { meta = meta || can.ondetail, list = list && list.length > 0? list: meta.list; if (list.length == 0) { return }
meta = meta||can.ondetail||{}, cb = cb||function(ev, item, meta) {
var cb = can.ondetail[item] || can.onaction[item] || can.onkeymap&&can.onkeymap._remote
cb && cb(event, can, item)
}
var x = event.clientX, y = event.clientY; y += 0; if (x > 600) { x -= 20 }
var ui = can.page.Append(can, document.body, [{view: "carte", style: {left: x+"px", top: y+"px"}, onmouseleave: function(event) {
can.page.Remove(can, ui.first)
}, list: can.core.List(list, function(item) {
return {view: "item", list: [typeof item == "string"? /* button */ {text: item, click: function(event) {
typeof cb == "function" && cb(event, item, meta)
}}: item.args? /* input */ {text: item.name, click: function(event) {
can.user.input(event, can, item.args, cb)
}}: /* select */ {select: [item, function(event) {
typeof cb == "function" && cb(event, event.target.value, meta)
}]} ]}
}) }])
event.stopPropagation()
event.preventDefault()
return ui
},
login: function(can, cb) {
var ui = can.user.input({clientX: 200, clientY: 100}, can, [
{username: "username", name: "用户"},
@ -124,6 +105,31 @@ Volcanos("user", {help: "用户模块", agent: {
// TODO
})
},
carte: function(event, can, meta, list, cb) {
meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||[]; if (list.length == 0) { return }
cb = cb||function(ev, item, meta) {
var cb = meta[item] || can.ondetail&&can.ondetail[item] || can.onaction&&can.onaction[item] || can.onkeymap&&can.onkeymap._remote
typeof cb == "function" && cb(event, can, item)
}
var x = event.clientX, y = event.clientY; y += 0; if (x > 600) { x -= 20 }
var ui = can.page.Append(can, document.body, [{view: "carte", style: {left: x, top: y}, onmouseleave: function(event) {
can.page.Remove(can, ui.first)
}, list: can.core.List(list, function(item) {
return {view: "item", list: [typeof item == "string"? /* button */ {text: item, click: function(event) {
typeof cb == "function" && cb(event, item, meta)
}}: item.args? /* input */ {text: item.name, click: function(event) {
can.user.input(event, can, item.args, cb)
}}: /* select */ {select: [item, function(event) {
typeof cb == "function" && cb(event, event.target.value, meta)
}]} ]}
}) }])
event.stopPropagation()
event.preventDefault()
return ui
},
input: function(event, can, form, cb) { // form [ string, {_input: }, array, object, button ]
function cbs(event, button) {
var data = {}; var list = can.page.Select(can, ui.table, "select,input,textarea", function(item) {
@ -136,6 +142,7 @@ Volcanos("user", {help: "用户模块", agent: {
var msg = can.request(event)
var x = event.clientX, y = event.clientY; y += 10; if (x > 600) { x -= 160 }
if (can.user.isMobile) { x = 100, y = 100 }
var button; var ui = can.page.Append(can, document.body, [{view: ["input", "fieldset"], style: {left: x+"px", top: y+"px"}, list: [
{view: ["option", "table"], list: can.core.List(form, function(item) {
if (item.button) { button = can.core.List(item.button, function(item) {
@ -193,6 +200,7 @@ Volcanos("user", {help: "用户模块", agent: {
},
upload: function(event, can) { var begin = new Date()
var x = event.clientX, y = event.clientY; y += 10; if (x > 400) { x -= 200 }
if (can.user.isMobile) { x = 100, y = 100 }
var ui = can.page.Append(can, document.body, [{view: "upload", style: {left: x+"px", top: y+"px"}, list: [
{view: "action"}, {view: "output"},
]}])

View File

@ -7,21 +7,22 @@
"48": "favicon.png",
"128": "favicon.png"
},
"background": {"page": "/chrome/chrome.html"},
"background": {"page": "/publish/chrome/chrome.html"},
"browser_action": {
"default_icon": "/favicon.png",
"default_popup": "/chrome/popup.html"
"default_popup": "/publish/chrome/popup.html"
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"matches": ["<all_urls>"],
"js": ["/proto.js",
"/lib/base.js",
"/lib/core.js",
"/lib/misc.js",
"/lib/page.js",
"/lib/user.js",
"/chrome/contexts.js"]
"/publish/chrome/contexts.js"
]
}
],
"permissions": [

View File

@ -9,6 +9,8 @@ fieldset.Action>div.output {
fieldset.Action fieldset.plugin {
margin:5px;
background-color:#113c4a;
box-shadow: 4px 4px 10px 4px #626bd0;
}
fieldset.Action fieldset.plugin:hover {
border-color:red;

View File

@ -1,5 +1,8 @@
(function() { const RIVER = "river", STORM = "storm", ACTION = "action"
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can._target.ontouchstart = function(event) {
can.run({}, ["search", "River.onmotion.hidden"])
}
var river = can.Conf(RIVER), storm = can.Conf(STORM)
can.onmotion.clear(can), can.core.Next(msg.Table(), function(value, next) {
value.feature = can.base.Obj(value.feature||value.meta||"{}", {})
@ -30,6 +33,27 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
}, target)
},
})
Volcanos("onengine", {help: "解析引擎", list: [],
engine: function(event, can, msg, pane, cmds, cb) {
var river = can.onengine.river[cmds[0]]
var storm = river && river.storm[cmds[1]]
if (!storm || cmds.length != 2) { return false }
if (storm.index) {
can.misc.Run(event, can, {names: pane._name}, ["action", "command"].concat(storm.index), cb)
} else {
can.core.List(storm.action, function(value) {
msg.Push("name", value.name||"")
msg.Push("help", value.help||"")
msg.Push("inputs", JSON.stringify(value.inputs||[]))
msg.Push("feature", JSON.stringify(value.feature||{}))
msg.Push("index", value.index||"")
msg.Push("args", value.args||"[]")
}), typeof cb == "function" && cb(msg)
}
return true
},
})
Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, list, cb, target) {
can.page.Cache(can.Conf(RIVER)+"."+can.Conf(STORM), can._output, can._output.scrollTop+1)
var river = can.Conf(RIVER, msg.Option(RIVER)), storm = can.Conf(STORM, msg.Option(STORM))

View File

@ -5,7 +5,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
typeof cb == "function" && cb(msg)
},
_title: function(can, msg, target) {
can.core.List(msg.result, function(title) {
can.user.isMobile || can.core.List(msg.result, function(title) {
can.page.Append(can, target, [{view: ["title", "div", title]}])
})
},

View File

@ -11,8 +11,7 @@ fieldset.Header>div.output>div.title {
float:left;
}
fieldset.Header>div.output>div.title:hover {
background-color:red;
border:ridge 2px yellow;
background-color:#2e515f;
}
fieldset.Header>div.output>div.search {
margin-left:20px;
@ -35,7 +34,7 @@ fieldset.Header>div.output>div.state {
float:right;
}
fieldset.Header>div.output>div.state:hover {
background-color:red;
background-color:#2e515f;
}
body.white fieldset.Header {

View File

@ -1,5 +1,13 @@
(function() { const TITLE = "title", TOPIC = "topic", POD = "pod", STATE = "state", USERNAME = "username"
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can._trans = {
"river": "菜单",
"setting": "设置",
"pack": "打包页面",
"white": "白色主题",
"black": "黑色主题",
"logout": "退出",
}
can.onmotion.clear(can)
can.onimport._title(can, msg, target)
can.onimport._state(can, msg, target)
@ -24,10 +32,10 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
}
}, }], }]).input)
var ui = can.page.Append(can, target, can.core.List(can.user.isMobile || can.user.isExtension || can.user.Search(can, POD)? ["River"]: ["pack"], function(item) {
return {view: "item", list: [{type: "input", data: {type: "button", name: item, value: item.toLowerCase()}, onclick: function(event) {
var cb = can.onaction[item]; typeof cb == "function" && (item == "River"? cb(can): cb(event, can, item))
}, }]}
var ui = can.page.Append(can, target, can.core.List(can.user.isMobile || can.user.isExtension || can.user.Search(can, POD)? ["river", "setting"]: ["setting"], function(item) {
return {view: ["menus", "div", item], onclick: function(event) {
var cb = can.onaction[item]; typeof cb == "function" && cb(event, can, item)
}}
}))
},
_state: function(can, msg, target) {
@ -55,7 +63,9 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.user.isWeiXin && can.onimport._weixin(can)
},
_weixin: function(can, msg) { can.run({}, ["action", "wx"], function(msg) {
can.user.toast(can, "weixin")
can.require(["https://res.wx.qq.com/open/js/jweixin-1.6.0.js"], function(can) {
can.user.toast(can, "weixin")
can.user.agent = { __proto__: can.user.agent,
getLocation: function(cb) { wx.getLocation({type: "gcj02", success: function (res) {
typeof cb == "function" && cb({latitude: parseInt(res.latitude*100000), longitude: parseInt(res.longitude*100000) })
@ -81,7 +91,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
},
time: function(can, target) { target.innerHTML = can.base.Time(null, "%w %H:%M:%S")
can.user.Search(can, TOPIC) || can.user.Search(can, POD) || can.user.topic(can, can.base.isNight()? "black": "white")
can._topic || can.user.Search(can, TOPIC) || can.user.Search(can, POD) || can.user.topic(can, can.base.isNight()? "black": "white")
},
})
Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg, list, cb, target) {
@ -102,9 +112,22 @@ Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg,
})
can.user.jumps(can.user.Share(can, args, true))
},
username: function(event, can) { can.user.logout(can) },
username: function(event, can) {
var ui = can.user.carte(event, can, can.onaction, ["logout"])
can.page.Modify(can, ui.first, {style: {top: can._target.offsetHeight}, className: "menu"})
},
logout: function(event, can) {
can.user.logout(can)
},
time: function(event, can) {
can.require(["/plugin/input/date.js"], function(can) {
event.target.value = ""
var ui = can.onfigure.date.onclick(event, can)
can.page.Modify(can, ui.fieldset, {style: {right: 0, top: can._target.offsetHeight, left: ""}})
})
},
pack: function(event, can, key) {
pack: function(event, can) {
can.core.Item(Volcanos.meta.pack, function(key, msg) { delete(msg._event), delete(msg._can) })
var msg = can.request(event, {name: "demo", content: JSON.stringify(Volcanos.meta.pack)})
@ -114,6 +137,15 @@ Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg,
})
},
river: function(event, can) { can.run(event, ["search", "River.onmotion.toggle"]) },
setting: function(event, can) {
var ui = can.user.carte(event, can, can.onaction, ["pack", "white", "black", "toast"])
can.page.Modify(can, ui.first, {style: {top: can._target.offsetHeight}, className: "menu"})
},
black: function(event, can, button) { can.user.topic(can, can._topic = button) },
white: function(event, can, button) { can.user.topic(can, can._topic = button) },
toast: function(event, can, button) { can.user.toast(can, "nice", "hi", 1000000)},
River: function(can) { can.run({}, ["search", "River.onmotion.toggle"]) },
Footer: function(can) { can.run({}, ["search", "River.onmotion.autosize"]) },
})

View File

@ -9,19 +9,14 @@ fieldset.River>div.output {
padding:0;
}
fieldset.River>div.output div.item {
padding-left:6px;
padding:3px 16px;
}
fieldset.River>div.output div.item:hover {
cursor:pointer;
background-color:red;
border:ridge 2px yellow;
background-color:#2e515f;
}
fieldset.River>div.output div.item.select {
background-color:red;
border:ridge 2px yellow;
}
fieldset.River>div.output div.list {
margin-left:20px;
background-color:#2e515f;
}
body.white fieldset.River {
@ -29,19 +24,3 @@ body.white fieldset.River {
background-color:#1f2224;
color:white;
}
body.white fieldset.River>div.output div.item:hover {
background-color:black;
border:solid 2px black;
}
body.white fieldset.River>div.output div.item.select {
background-color:black;
border:solid 2px black;
}
body.white fieldset.River>div.output div.subitem:hover {
background-color:black;
border:solid 2px black;
}
body.white fieldset.River>div.output div.subitem.select {
background-color:black;
border:solid 2px black;
}

View File

@ -10,9 +10,9 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.onaction.storm(event, can, value.hash)
}, function(event) {
// 右键点击
can.user.carte(can, can.ondetail, can.ondetail.list, function(ev, item, meta) {
var ui = can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, item, meta) {
can.ondetail[item](event, can, item, value.hash)
})
}); can.page.Modify(can, ui.first, {style: {left: can._target.offsetWidth}, className: "menu"})
})
if (index == 0 || [value.hash, value.name].indexOf(can._main_river) > -1) { select = view }
@ -21,7 +21,18 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
typeof cb == "function" && cb(msg)
},
})
Volcanos("onaction", {help: "控件交互", list: ["创建", "刷新"], _init: function(can, msg, list, cb, target) {
Volcanos("onengine", {help: "解析引擎", list: [], engine: function(event, can, msg, pane, cmds, cb) {
cmds.length == 0 && can.core.Item(can.onengine.river, function(key, value) {
msg.Push({hash: key, name: value.name})
}); if (cmds.length != 1 && cmds[1] != "tool") { return false }
var river = can.onengine.river[cmds[0]]; if (!river) { return false }
can.core.Item(river.storm, function(key, value) {
msg.Push({hash: key, name: value.name})
}), typeof cb == "function" && cb(msg); return true
},
})
Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg, list, cb, target) {
can.run({}, [], function(msg) {
can.onimport._init(can, msg, list, cb, can._output)
})
@ -38,10 +49,12 @@ Volcanos("onaction", {help: "控件交互", list: ["创建", "刷新"], _init: f
can.onaction.action(event, can, river, storm.hash)
can.user.title(can.user.Search(can, POD) || storm.name)
}, oncontextmenu: function(event) {
can.onaction.action(event, can, river, storm.hash)
can.user.title(can.user.Search(can, POD) || storm.name)
// 右键点击
can.user.carte(can, can.ondetail, ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], function(ev, item, meta) {
var ui = can.user.carte(event, can, can.ondetail, ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], function(ev, item, meta) {
can.ondetail[item](event, can, item, storm.hash, river)
})
}); can.page.Modify(can, ui.first, {style: {left: can._target.offsetWidth}, className: "menu"})
}}
}) }]).first, list.children.length > 0 && list.children[select].click()

View File

@ -31,7 +31,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
var fields = (msg.Option("fields")||"pod,ctx,cmd,type,name,text").split(",")
function search(word, cb) { cmd[1] = word
if (word == "" && can.list[0] && can.list[0].type == "fieldset") {
if (word == "" && can.list && can.list[0] && can.list[0].type == "fieldset") {
can.page.Select(can, document.body, "fieldset.pane.Action fieldset.plugin>legend", function(item) {
if (item.innerHTML == can.list[0].name) {
var cb = can.page.Select(can, item.parentNode, "input.args")[0]
@ -69,7 +69,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.ui = can.page.Append(can, can._output, [
{input: ["word", function(event) { var target = event.target
can.onkeypop.input(event, can, target)
can.onkeypop.input(event, can)
if (event.key == "Escape") {
can.onmotion.hide(can)
}

View File

@ -1,82 +1,78 @@
Volcanos("onfigure", {help: "控件详情", list: [], _merge: function(can, sub) { can.core.Item(sub, function(key, value) {
if (sub.hasOwnProperty(key)) { can.onfigure[key] = value }
}); return true },
Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(event, can, item, target) { target = target || event.target
date: {onclick: function(event, can, item, target) {
// 设置输入
function set(now) {
target.value = can.base.Time(now)
item && item.action == "auto" && can.run({})
}
// 设置输入
function set(now) {
target.value = can.base.Time(now)
item.action == "auto" && can.run({})
// 添加插件
var figure = can.onappend.field(can, document.body, "input date", {})
figure.table = can.page.Append(can, figure.output, [{type: "table"}]).first
can.page.Modify(can, figure.fieldset, {style: {top: event.clientY+10, left: event.clientX}})
can.page.Remove(can, figure.legend)
// 添加控件
var now = target.value? new Date(target.value): new Date()
var control = can.page.AppendAction(can, figure.action, ["今天",
["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)), {view: ["", "br"]},
"关闭", {type: "hr", style: {margin: 0}},
"上一月", ["year"].concat(can.core.List(now.getFullYear() - 20, now.getFullYear() + 20)),
["month"].concat(can.core.List(1, 13)), "下一月", {view: ["", "br"]},
], function(event, value, cmd) {can.stick = true
// 设置时间
switch (cmd) {
case "year": now.setFullYear(parseInt(value)), show(now); return
case "month": now.setMonth(parseInt(value)-1), show(now); return
case "hour": now.setHours(parseInt(value)), set(show(now)); return
case "minute": now.setMinutes(parseInt(value)), set(show(now)); return
case "second": now.setSeconds(parseInt(value)), set(show(now)); return
}
// 添加插件
var figure = can.onappend.field(can, document.body, "input date", {})
figure.table = can.page.Append(can, figure.output, [{type: "table"}]).first
can.page.Modify(can, figure.fieldset, {style: {top: event.clientY+10, left: event.clientX}})
can.page.Remove(can, figure.legend)
// 设置日期
switch (value) {
case "关闭": can.page.Remove(can, figure.fieldset); break
case "今天": now = new Date(), set(show(now)); break
case "随机": now.setDate((Math.random() * 100 - 50) + now.getDate()), set(show(now)); break
case "关闭": can.page.Remove(can, figure.first)
case "前一年": now.setFullYear(now.getFullYear()-1), show(now); break
case "后一年": now.setFullYear(now.getFullYear()+1), show(now); break
case "上一月": now.setMonth(now.getMonth()-1), show(now); break
case "下一月": now.setMonth(now.getMonth()+1), show(now); break
}
})
// 添加控件
var now = target.value? new Date(target.value): new Date();
var control = can.page.AppendAction(can, figure.action, ["今天",
["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)), {view: ["", "br"]},
"关闭", {type: "hr", style: {margin: 0}},
"上一月", ["year"].concat(can.core.List(now.getFullYear() - 20, now.getFullYear() + 20)),
["month"].concat(can.core.List(1, 13)), "下一月", {view: ["", "br"]},
], function(event, value, cmd) {can.stick = true;
// 设置时间
switch (cmd) {
case "year": now.setFullYear(parseInt(value)); show(now); return;
case "month": now.setMonth(parseInt(value)-1); show(now); return;
case "hour": now.setHours(parseInt(value)); set(show(now)); return;
case "minute": now.setMinutes(parseInt(value)); set(show(now)); return;
case "second": now.setSeconds(parseInt(value)); set(show(now)); return;
}
function show(now) {
// 设置控件
control.month.value = now.getMonth()+1
control.year.value = now.getFullYear()
control.hour.value = now.getHours()
control.minute.value = parseInt(now.getMinutes()/5)*5
control.second.value = parseInt(now.getSeconds()/5)*5
// 设置日期
switch (value) {
case "关闭": can.page.Remove(can, figure.fieldset); break;
case "今天": now = new Date(); set(show(now)); break;
case "随机": now.setDate((Math.random() * 100 - 50) + now.getDate()); set(show(now)); break;
case "关闭": can.page.Remove(can, figure.first);
case "前一年": now.setFullYear(now.getFullYear()-1); show(now); break;
case "后一年": now.setFullYear(now.getFullYear()+1); show(now); break;
case "上一月": now.setMonth(now.getMonth()-1); show(now); break;
case "下一月": now.setMonth(now.getMonth()+1); show(now); break;
}
})
// 设置组件
can.page.Appends(can, figure.table, [{type: "tr", list: can.core.List(["日", "一", "二", "三", "四", "五", "六"], function(day) {return {text: [day, "th"]}})}])
var tr; function add(day, type) {if (day.getDay() == 0) {tr = can.page.Append(can, figure.table, [{type: "tr"}]).tr}
can.page.Append(can, tr, [{text: [day.getDate(), "td", can.base.Time(day).split(" ")[0] == can.base.Time(now).split(" ")[0]? "select": type],
dataset: {date: day.getTime()}, click: function(event) {
set(now = new Date(parseInt(target.dataset.date)))
can.page.Remove(can, figure.fieldset)
},
}])
}
function show(now) {
// 设置控件
control.month.value = now.getMonth()+1;
control.year.value = now.getFullYear();
control.hour.value = now.getHours();
control.minute.value = parseInt(now.getMinutes()/5)*5;
control.second.value = parseInt(now.getSeconds()/5)*5;
// 时间区间
var one = new Date(now); one.setDate(1)
var end = new Date(now); end.setMonth(now.getMonth()+1), end.setDate(1)
var head = new Date(one); head.setDate(one.getDate()-one.getDay())
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay())
// 设置组件
can.page.Appends(can, figure.table, [{type: "tr", list: can.core.List(["日", "一", "二", "三", "四", "五", "六"], function(day) {return {text: [day, "th"]}})}])
var tr; function add(day, type) {if (day.getDay() == 0) {tr = can.page.Append(can, figure.table, [{type: "tr"}]).tr}
can.page.Append(can, tr, [{text: [day.getDate(), "td", can.base.Time(day).split(" ")[0] == can.base.Time(now).split(" ")[0]? "select": type],
dataset: {date: day.getTime()}, click: function(event) {
set(now = new Date(parseInt(event.target.dataset.date)))
can.page.Remove(can, figure.fieldset)
},
}])
}
// 时间区间
var one = new Date(now); one.setDate(1);
var end = new Date(now); end.setMonth(now.getMonth()+1); end.setDate(1);
var head = new Date(one); head.setDate(one.getDate()-one.getDay());
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay());
// 时间序列
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) {add(day, "last")}
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")}
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")}
return now
}; set(show(now));
}},
}, ["/plugin/input/date.css"])
// 时间序列
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) {add(day, "last")}
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")}
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")}
return now
}; set(show(now))
return figure
}} }, ["/plugin/input/date.css"])

View File

@ -1,10 +1,19 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) { if (!msg.cmds) { return }
Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) {
var width = can.Conf("width"), height = can.Conf("height")
can.ui = can.page.Appends(can, target, [
{type: "table", list: [{type: "tr", list: [
{type: "td", list: [{view: "project", style: {"max-height": window.innerHeight-480, display: "none"}} ]},
{type: "td", list: [{view: "profile", style: {"max-height": window.innerHeight-480}, list: [
{type: "td", list: [{view: "project", style: {"max-height": height-480, display: "none"}} ]},
{type: "td", list: [{view: "profile", style: {"max-height": height-480}, list: [
{view: ["content", "table"]},
]}], style: {"min-width": parseInt(can.Conf("width"))-120, "max-width": parseInt(can.Conf("width"))-60}},
]}], style: {"min-width": width-120, "max-width": width-60}, _init: function(item) {
can.onlayout.resize(function(width, height) {
width = can.Conf("width", width), height = can.Conf("height", height)
can.page.Modify(can, item, {style: {
"min-width": width-120, "max-width": width-60,
}})
})
}},
]}, ]},
{view: "search", style: {display: "none"}, list: [{view: "action", list: [
{input: ["word", function(event) {
@ -60,7 +69,7 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb,
}, true)
},
project: function(can, path, cb) { can.Option({path: path})
var msg = can.request({}); msg.Option("dir_root", path), msg.Option("dir_deep", "true")
var msg = can.request({}, {dir_root: path, dir_deep: true})
can.run(msg._event, ["action", "dir", "./"], function(msg) { can.ui.project.innerHTML = ""
msg.path && can.Status("文件数", msg.path.length)
can.onappend.tree(can, msg, "path", "/", can.ui.project, function(event, value) {

View File

@ -3,7 +3,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.table = can.onappend.table(can, msg, can.ui.content, "table", function(value, key, index, line) {
return {text: [value, "td"], oncontextmenu: function(event) {
can.user.carte(can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) {
can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) {
var cb = meta[cmd]; cb && cb(event, can, cmd, value, key, index, line)
})
}, ondblclick: function(event) {

View File

@ -54,7 +54,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.Action(key, target.Value(key)||can.Action(key))
}), can.onmotion.show(can, 10, null, target)
}, function(event) {
can.user.carte(can, can.onaction||{}, ["隐藏", "显示", "添加", "删除", "清空"], function(ev, item, meta) {
can.user.carte(event, can, can.onaction||{}, ["隐藏", "显示", "添加", "删除", "清空"], function(ev, item, meta) {
switch (item) {
case "显示":
can.page.Select(can, can.ui.content, "g."+name, function(item) {

View File

@ -93,7 +93,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
}
},
}, ["/plugin/local/wiki/word.css"])
Volcanos("onaction", {help: "控件交互", list: ["演示"],
Volcanos("onaction", {help: "控件交互", list: [],
show: function(can, which) {
can.page.Select(can, can.ui.content, "div.page.show", function(page) {
can.page.ClassList.del(can, page, "show")

View File

@ -224,6 +224,11 @@ Volcanos("onaction", {help: "组件菜单", list: ["编辑", ["view", "横向",
layout.left = 0, layout.top = 40
layout.width = window.innerWidth-40
layout.height = window.innerHeight-60
if (can.user.isMobile) {
if (window.innerWidth > window.innerHeight) {
layout.top = 0
}
}
can.onaction._resize(sub, layout)
break
default:
@ -234,6 +239,11 @@ Volcanos("onaction", {help: "组件菜单", list: ["编辑", ["view", "横向",
}, true)
}
}
if (can.user.isMobile) {
can.core.Timer(100, function() {
sub.run({}, ["some", "最大"])
})
}
})
},

View File

@ -11,23 +11,28 @@ function shy(help, meta, list, cb) {
cb.list = next("object") || []
return cb
}; var _can_name = ""
var Volcanos = shy("火山架", {libs: [], cache: {}}, [], function(name, can, libs, cb) {
var Volcanos = shy("火山架", {cache: {}, libs: [], _target: document.body}, [], function(name, can, libs, cb) {
var meta = arguments.callee.meta, list = arguments.callee.list
if (typeof name == "object") { var Config = name
if (typeof name == "object") { var Config = name; _can_name = ""
meta.libs = Config.libs, meta.volcano = Config.volcano
// 预加载
var Preload = Config.libs; Config.panes.forEach(function(pane) {
Preload = Preload.concat(pane.list = pane.list || ["/pane/"+pane.name+".css", "/pane/"+pane.name+".js"])
}); Preload = Preload.concat(Config.plugin)
// 根模块
meta.volcano = Config.volcano, meta.libs = Config.libs
name = Config.name, can = {_follow: Config.name,
_target: document.body, _width: window.innerWidth, _height: window.innerHeight,
_width: window.innerWidth, _height: window.innerHeight,
}, libs = Preload.concat(Config.volcano), cb = function(can) {
can.onengine._init(can, can.Conf(Config), Config.panes, function(msg) {
can.base.Log(can)
can.base.Log(name, "run", window.can = can)
document.body.onresize = function(event) {
can.onlayout._init(can, can._target, window.innerWidth, window.innerHeight)
}, can.onlayout._init(can, can._target, window.innerWidth, window.innerHeight-8)
}, can._target)
}
}
list.push(can = can || {}), can.__proto__ = {__proto__: Volcanos.meta, _name: name, _load: function(name, cb) {
@ -38,8 +43,8 @@ var Volcanos = shy("火山架", {libs: [], cache: {}}, [], function(name, can, l
// 加载模块
for (var i = 0; i < cache.length; i++) { var sub = cache[i]
if (typeof cb == "function" && cb(can, name, sub)) { continue }
if (can[sub._name] && can[sub._name]._merge && can[sub._name]._merge(can, sub)) { continue }
if (typeof cb == "function" && cb(can, name, sub)) { continue}
if (can[sub._name]) {
for (var k in sub) {
can[sub._name].hasOwnProperty(k) || (can[sub._name][k] = sub[k])
@ -55,29 +60,13 @@ var Volcanos = shy("火山架", {libs: [], cache: {}}, [], function(name, can, l
}
var source = !libs[0].endsWith("/") && (libs[0].indexOf(".") == -1? libs[0]+".js": libs[0]) || libs[0]
var target = source.endsWith(".css")? (can._head||document.head): (can._body||document.body)
if (meta.cache[source]) {
can._load(source, each), can.require(libs.slice(1), cb, each)
return // 加载缓存
if (source.indexOf("/publish") == 0 && can.base && can.user) {
source = can.base.URLMerge(source, "pod", can.user.Search(can, "pod")||"")
}
if (source.endsWith(".css")) { var style = document.createElement("link")
style.rel = "stylesheet", style.type = "text/css"
style.href = source; style.onload = function() {
can._load(source, each), can.require(libs.slice(1), cb, each)
} // 加载样式
target.appendChild(style)
} else if (source.endsWith(".js")) { var script = document.createElement("script")
if (source.indexOf("/publish") == 0 && can.user) {
source += "?pod="+(can.user.Search(can, "pod")||"")
}
script.src = source, script.onload = function() {
can._load(source, each), can.require(libs.slice(1), cb, each)
} // 加载脚本
target.appendChild(script)
}
// 请求模块
function next() { can._load(source, each), can.require(libs.slice(1), cb, each) }
meta.cache[source]? next(): meta._load(source, next)
},
request: function(event, option) { event = event || {}
event._msg = event._msg || can.misc.Message(event, can)
@ -86,17 +75,7 @@ var Volcanos = shy("火山架", {libs: [], cache: {}}, [], function(name, can, l
},
Conf: function(key, value) {
if (key == undefined) { return can._conf }
if (typeof key == "object") { can._conf = key; return can._conf }
can._conf[key] = value == undefined? can._conf[key]: value
if (can._conf[key] == undefined && key.indexOf(".") > 0) {
var p = can._conf, ls = key.split("."); while (p && ls.length > 0) {
p = p[ls[0]], ls = ls.slice(1)
}
return p
}
return can._conf[key]
return can.core.Value(can._conf, key, value)
}, _conf: {},
}
@ -106,4 +85,18 @@ var Volcanos = shy("火山架", {libs: [], cache: {}}, [], function(name, can, l
}
return can.require(libs, cb), can
})
Volcanos.meta._load = function(url, cb) {
switch (url.split("?")[0].split(".").pop().toLowerCase()) {
case "css":
var item = document.createElement("link")
item.rel = "stylesheet", item.type = "text/css"
item.href = url; item.onload = cb
document.head.appendChild(item)
return item
case "js":
var item = document.createElement("script")
item.src = url, item.onload = cb
document.body.appendChild(item)
return item
}
}

View File

@ -1,91 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, body) {
window.onresize = function(event) {
can.onlayout["刷新"](event, can, conf, null, body)
}
},
layout: function(event, can, value, key, body) {var conf = can.Conf()
can.onlayout["刷新"](event, can, conf, value? conf.layout.size[value]: null, body)
},
title: function(event, can, value, key, body) {var conf = can.Conf()
can.user.title(value||conf.title)
},
login: function(event, can, value, key, body) {var conf = can.Conf()
var list = location.pathname.split("/");
can.Login? can.user.login(function(user) {
can.River.Import(event, "update", "river")
}): (
can.Action.Import(event, list[2], "river"),
can.Action.Import(event, "action", "storm")
)
}
})
Volcanos("onaction", {help: "组件交互", list: [],
onkeydown: function(event, can) {var conf = can.Conf()
if (event.target.tagName == "INPUT" || event.target.tagName == "TEXTAREA") {
return
}
if (event.target.getAttribute("contenteditable")) {
return
}
switch (event.key) {
case "j":
can.Report(event, {x: 0, y: conf.scroll.line}, "scroll")
can.Report(event, event.key, "keydown")
break
case "k":
can.Report(event, {x: 0, y: -conf.scroll.line}, "scroll")
can.Report(event, event.key, "keydown")
break
case "Escape":
can.Report(event, event.key, "escape")
break
case "Enter":
can.Report(event, event.key, "enter")
break
case " ":
can.Report(event, event.key, "space")
break
default:
can.Report(event, event.key, "keydown")
}
},
})
Volcanos("onlayout", {help: "组件布局", list: ["刷新"],
"刷新": function(event, can, conf, layout, body) {layout = layout || {};
var height = body.clientHeight-conf.layout.border;
var width = body.clientWidth-conf.layout.border;
can.user.isWindows && (body.style.overflow = "hidden");
layout.head == undefined && (layout.head = can.head.target.clientHeight)
layout.foot == undefined && (layout.foot = can.foot.target.clientHeight)
can.head.Size(event, width, layout.head)
can.foot.Size(event, width, layout.foot)
height -= can.head.target.offsetHeight+can.foot.target.offsetHeight
layout.left != 0 && can.left.target.dataset.width && (layout.left = can.left.target.dataset.width)
layout.right != 0 && can.right.target.dataset.width && (layout.right = can.right.target.dataset.width)
layout.left == undefined && (layout.left = can.left.target.clientWidth)
layout.right == undefined && (layout.right = can.right.target.clientWidth)
can.left.Size(event, layout.left, height)
can.right.Size(event, layout.right, height)
width -= can.left.target.offsetWidth+can.right.target.offsetWidth
layout.bottom == -1 && (layout.bottom = can.user.isMobile? "": height, layout.top = 0, layout.center = 0)
layout.bottom == undefined && (layout.bottom = can.bottom.target.offsetHeight-conf.layout.border)
layout.center == undefined && (layout.center = can.center.target.clientHeight)
layout.top == undefined && (layout.top = can.top.target.clientHeight)
layout.center == 0 && layout.top == 0 && !can.user.isMobile && layout.bottom != -2 && (layout.bottom = height)
can.bottom.Size(event, width, layout.bottom)
can.center.Size(event, width, layout.center)
height -= layout.top==0? height: can.center.target.offsetHeight+can.bottom.target.offsetHeight
can.top.Size(event, width, height)
},
})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,345 +0,0 @@
var can = Volcanos("chat", {
Page: shy("构造网页", function(can, name, conf, cb, body, topic) {
var page = Volcanos(name, {_type: "local", _panes: {}, _views: {}, target: body,
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Import: function(event, value, key) {var cb = page.onimport[key];
typeof cb == "function" && cb(event, page, value, key, body);
},
Report: function(event, value, key) {
// 导入数据
page.Import(event, value, key)
// 分发数据
can.core.Item(page._panes, function(index, item) {
if (key == "favor") {var msg = value;
var cmds = msg.detail, cmd = cmds[0];
if (cmd == item._name || cmd == item.Name()) {cmd = cmds[1], cmds = cmds.slice(1)}
var cb = item.onchoice[cmd];
if (typeof cb == "function") {
cb(event, item, value, cmd, item.target);
return msg.Echo(item._name, " onchoice ", cmd), msg._hand = true;
}
var cb = item.onaction[cmd];
if (typeof cb == "function") {
cb(event, item, value, cmd, item.target);
return msg.Echo(item._name, " onaction ", cmd), msg._hand = true;
}
}
// 下发数据
item.Import && item.Import(event, value, key)
})
},
run: function(event, option, cmds, cb) {can.misc.Run(event, page, option, cmds, cb)},
}, Config.libs.concat([name, "topic/"+topic+".css"]), function(page) {
// 加载配置
page.onimport._init && page.onimport._init(page, page.Conf(conf), body)
can.core.Next(conf.pane, function(item, cb) {
// 加载模块
page._panes[item.name] = page[item.name] = page._views[item.pos] = page[item.pos] = can.Pane(page, item.name, item, cb,
can.page.Select(can, body, "fieldset."+item.name)[0] ||
can.page.AppendField(can, body, item.name+" "+(item.pos||""), item))
}, function() {typeof cb == "function" && cb(page)})
}, conf)
return page
}),
Pane: shy("构造组件", function(can, name, meta, cb, field) {
var river = "", storm = "";
var pane = Volcanos(name, {_type: "local", _plugins: [], _local: {}, target: field,
option: field.querySelector("form.option"),
action: field.querySelector("div.action"),
output: field.querySelector("div.output"),
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Export: function(event, value, key) {var cb = pane.onexport[key];
typeof cb == "function"? cb(event, pane, value, key, field): can.Report(event, value, key)
},
Import: function(event, value, key) {var cb = pane.onimport[key];
// 导入数据
typeof cb == "function" && cb(event, pane, value, key, field);
// 分发数据
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})
},
Action: function(key, value) {var cb = pane.onimport[key];
typeof cb == "function" && cb(event, pane, value, key, field);
return can.page.Select(can, pane.action, "input[name="+key+"],select."+key+",select[name="+key+"]", function(item) {
// 读写控件
value != undefined && (item.value = value), value = item.value
}), value
},
Size: function(event, width, height) {var cb = pane.onimport["size"];
field.style.display = width === 0 || height === 0? "none": "block";
if (width > 0) {
field.style.width = width + "px"
} else if (width == -1) {
field.style.width = document.body.offsetWidth + "px"
} else if (width == -2) {
field.style.width = ""
}
if (height > 0) {
field.style.height = height + "px"
} else if (height == -1) {
field.style.height = document.body.offsetHeight + "px"
} else if (height == -2) {
field.style.height = ""
}
typeof cb == "function" && cb(event, pane, {width: width, height: height}, "size", field)
},
Show: function(event, width, height, offset) {field.style.display = "block";
if (width < 0) {field.style.left = -width / 2 + "px";
field.style.width = (document.body.offsetWidth + width) + "px";
}
if (width > 0) {field.style.width = width + "px";
field.style.left = (document.body.offsetWidth - width) / 2 + "px";
}
if (width === "") {
field.style.width = ""
}
if (height > 0) {field.style.height = height + "px";
field.style.top = (document.body.offsetHeight - height) / 2 + (offset||0) + "px";
}
if (height < 0) {field.style.top = -height / 2 + (offset||0) + "px";
field.style.height = (document.body.offsetHeight + height) + "px";
}
if (height === "") {
field.style.height = ""
}
var cb = pane.onimport["show"];
typeof cb == "function" && cb(event, can, width, "show", pane.output)
return field;
},
Hide: function() {field.style.display = "none"},
run: function(event, cmds, cb) {var msg = pane.Event(event)
can.page.Select(can, pane.action, "input", function(item, index) {
// 控件参数
item.name && item.value && msg.Option(item.name, item.value)
})
can.run(event, pane.option.dataset, cmds, cb)
return msg
},
}, Config.libs.concat(["pane/"+(meta.path||"")+name]), function(pane) {can.Dream(document.head, "pane/"+(meta.path||"")+name+".css")
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
}),
Plugin: shy("构造插件", function(can, name, meta, run, field, cb) {
meta && meta.class && can.page.ClassList.add(can, field, meta.class)
var option = field.querySelector("form.option");
var action = field.querySelector("div.action");
var output = field.querySelector("div.output");
var status = field.querySelector("div.status");
var history = []
var args = can.base.Obj(meta.args, []);
var feature = can.base.Obj(meta.feature);
var exports = can.base.Obj(meta.exports, feature.exports||[]);
var plugin = Volcanos(name, {_type: "local", _local: {}, target: field,
option: option, action: action, output: output,
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Export: function(event, value, key) {var cb = plugin.onexport[key];
typeof cb == "function"? cb(event, plugin, value, key, field): can.Export(event, value, key)
},
Import: function(event, value, key) {var cb = plugin.onimport[key];
// 导入数据
typeof cb == "function" && cb(event, plugin, value, key, plugin.output);
// 下发数据
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) {
// 导入数据
plugin.Import(event, value, key)
for (var i = 0; i < exports.length; i += 3) {
if (exports[i+1] == key) {key = exports[i]
if (exports[i+2]) {var cb = plugin.onexport[exports[i+2]], res;
// 数据转换
value = typeof cb == "function" && ((res = cb(event, plugin, plugin.msg, value, key, index)) != undefined) && res || value;
}
// 上报数据
// 上下循环
// key && can.Import(event, value, key)
can.Action(key, value)
}
}
},
Remove: function(event) {var list = can.page.Select(can, option, "input.temp")
list.length > 0 && list[list.length-1].parentNode.removeChild(list[list.length-1])
},
Append: function(item, cb) {item = item || {type: "text", name: "", className: "args temp"};
var name = item.name || item.value || "args"+plugin.page.Select(can, option, "input.args.temp").length;
var count = plugin.page.Select(can, option, ".args").length, value = "";
args && count < args.length && (value = args[count] || item.value || "");
plugin._local[name] = plugin[name] = can.Inputs(plugin, item, item.display||"input", name, value, cb, option);
},
Select: function(event, target, focus) {
can.page.Select(can, field.parentNode, "fieldset.item.select", function(item) {
can.page.ClassList.del(can, item, "select")
})
can.page.ClassList.add(can, field, "select")
can._plugin = plugin, can.input = target || option.querySelectorAll("input")[1];
focus && can.input.focus();
return true
},
Option: function(key, value) {
value != undefined && option[key] && (option[key].value = value)
return key != undefined? option[key] && option[key].value || "":
plugin.page.Select(can, option, ".args", function(item) {return item.value})
},
Check: function(event, target, cb) {
plugin.page.Select(can, option, ".args", function(item, index, list) {
if (item == target && index < list.length-1) {can._plugin && can._plugin.target == field && list[index+1].focus(); return item}
}).length == 0 && plugin.Runs(event, cb)
},
Last: function(event) {
can.core.List(history.pop() && history.pop(), function(item, index) {
return item.target.value = item.value
}).length > 0 && plugin.Runs(event)
},
Runs: function(event, cb) {
history.push(plugin.page.Select(can, option, ".args", function(item, index, list) {
return {target: item, value: item.value}
}))
can.Export(event, 1, "ncmd")
plugin.Run(event, plugin.Option(), cb)
},
Run: function(event, args, cb, silent) {var show = !silent;
var msg = can.Event(event);
can.page.Select(can, option, ".opts", function(item) {
msg[item] == undefined && item.name && item.value && msg.Option(item.name, item.value)
})
for (var i = args.length-1; i >= 0; i--) {if (args[i] == "") {args = args.slice(0, i)} else {break}}
show && can.core.Timer(1000, function() {show && plugin.user.toast(can.base.Format(args||["running..."]), meta.name, -1)});
run(event, args, function(msg) {if (silent) {return typeof cb == "function" && cb(msg)}
plugin.msg = msg, plugin.Show(feature.display || "table", msg, cb)
show = false, plugin.user.toast();
})
},
Show: function(type, msg, cb) {plugin.msg = msg, msg._plugin_name = name;
msg.Option("title") && can.user.title(msg.Option("title"))
return plugin._output = plugin._local[type] = plugin[type] = can.Output(plugin, feature, type, msg, cb, output, action, option, status)
},
Clone: function(event, cb) {meta.nick = meta.name + can.ID()
meta.msg = plugin.msg
meta.args = can.page.Select(can, plugin.option, ".args", function(item) {return item.value})
can._plugins.push(can.Plugin(can, meta.nick, meta, run,
can.page.AppendField(can, field.parentNode, "item "+meta.name+" "+meta.nick, meta), cb))
},
Delete: function(event) {field.parentNode.removeChild(field)},
}, Config.libs.concat(["plugin/"+(meta.type||feature.active||"state")]), function(plugin) {plugin.Conf(meta);
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):
// 加载控件
can.core.Next(list.length>0? list: [{type: "text"}, {type: "button", value: "执行"}], plugin.Append, function() {
typeof cb == "function" && cb(plugin)
})
// 加载控件
meta.msg && plugin.Show(feature.display || "table", meta.msg)
}, meta)
return field.Check = plugin.Check, plugin
}),
Inputs: shy("构造控件", function(can, item, type, name, value, cb, option) {
var input = Volcanos(name, {_type: "input", _plugin: can, item: item, target: "",
Run: can.Run, Runs: can.Runs,
Import: function(event, value, key, index) {var cb = input.onimport[item.imports];
value = typeof cb == "function" && cb(event, input, value, key, input.target) || value
input.target.value = value;
item.action == "auto"? can.Runs(event): can.Check(event, input.target);
},
Append: function(event, value) {can.Append(null, function(input) {can.Select(event, input.target, true)})},
Clone: function(event, value) {can.Clone(event, function(input) {input.Select(event, null, true)})},
Select: function(event) {can.Select(event, input.target, true)},
run: function(event, cmd, cb, silent) {var msg = can.Event(event);
msg.Option("_action", item.name);
var cbs = typeof input[item.cb] == "function" && input[item.cb]
|| typeof can[item.cb] == "function" && can[item.cb] || can.Check
cbs(event, event.target, cb);
},
}, Config.libs.concat(["plugin/"+type, "plugin/input/"+(item.figure||"")]), function(input) {
var target = input.onimport.init(input, item, name, value, option);
input.target = target, typeof cb == "function" && cb(input);
})
return input
}),
Output: shy("构造组件", function(can, feature, type, msg, cb, target, action, option, status) {
var output = Volcanos(type, {_type: "output", feature: feature, msg: msg,
target: target, action: action,
Plugin: can.Plugin, Inputs: can.Inputs, Output: can.Output,
Run: can.Run, Runs: can.Runs,
Import: function(event, value, key) {var cb = output.onimport && output.onimport[key];
typeof cb == "function" && cb(event, output, value, key, target);
},
Option: function(key, value) {
return key == undefined? can.page.Select(can, can.option, ".args", function(item) {return item.value}):
(can.page.Select(can, can.option, "input[name="+key+"],select[name="+key+"]", function(item) {
value != undefined && (item.value = value), value = item.value
}), value)
},
Action: function(key, value) {
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
},
Status: function(event, value, key) {var cb = output.onstatus[key];
typeof cb == "function" && cb(event, output, value, key, can.page.Select(can, status, "span."+key, function(item) {
value? can.page.ClassList.del(can, item.previousSibling, "hidden"):
can.page.ClassList.add(can, item.previousSibling, "hidden")
return item
})[0]||{})
},
Export: function(event, value, key, index) {var cb = output.onexport[key];
return typeof cb == "function"? cb(event, output, value, key, target): can.Report && can.Report(event, value, key, index)
},
run: function(event, cmd, cb, silent) {var msg = can.Event(event);
cmd = cmd || can.Option(), can.page.Select(can, option, ".args", function(item) {
msg[item.name] == undefined && item.name && item.value && msg.Option(item.name, item.value)
});
can.Run(event, cmd, cb, silent);
},
}, Config.libs.concat([(type.startsWith("/")? "": "plugin/")+type]), function(output) {
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.onfigure && (output.onfigure.sup = output, output.onfigure.target = target)
}, msg)
return output
}),
}, Config.libs.concat(Config.list), function(can) {
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) {
chat.Import({}, can.user.Search(can, "pod")||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")
}, document.body, can.user.Search(can, "topic")||Config.topic)
})

View File

@ -1,16 +0,0 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=0.7,user-scalable=no">
<title>volcanos</title>
<link rel="shortcut icon" type="image/ico" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="style_old.css">
</head>
<body>
<script src="index.js"></script>
<script src="proto_old.js"></script>
<script src="frame_old.js"></script>
</body>

View File

@ -1,45 +0,0 @@
var Config = {iceberg: "/chat/", volcano: "",
libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"],
main: "chat", list: ["chat",
"pane/float/Toast", "pane/float/Carte",
"pane/float/Tutor", "pane/float/Debug",
"pane/float/Login", "pane/float/Favor",
"pane/Header",
"pane/River", "pane/Storm",
"pane/Target", "pane/Source", "pane/Action",
"pane/Ocean", "pane/Steam",
"pane/Footer",
"plugin/state", "plugin/table", "plugin/input",
"plugin/input/date", "plugin/input/key",
], pane: [
{group: "index", name: "Toast", path: "float/", pos: "dialog", duration: 3000},
{group: "index", name: "Carte", path: "float/", pos: "dialog"},
{group: "index", name: "Tutor", path: "float/", pos: "dialog"},
{group: "index", name: "Debug", path: "float/", pos: "dialog"},
{group: "index", name: "Login", path: "float/", pos: "dialog"},
{group: "index", name: "Favor", path: "float/", pos: "dialog"},
{group: "index", name: "Header", pos: "head", state: ["time", "user", "link"]},
{group: "index", name: "River", pos: "left"},
{group: "index", name: "Storm", pos: "right"},
{group: "index", name: "Target", pos: "top"},
{group: "index", name: "Source", pos: "center"},
{group: "index", name: "Action", pos: "bottom"},
{group: "index", name: "Ocean", pos: "dialog", def_name: "meet"},
{group: "index", name: "Steam", pos: "dialog", def_name: "miss"},
{group: "index", name: "Footer", pos: "foot", state: ["ntxt", "ncmd"]},
], title: "volcanos", topic: "black", layout: {def: "工作", list: ["工作", "办公", "聊天"], size: {
"最大": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
"工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0},
"办公": {head: 30, foot: 30, left: 100, right: 100, bottom: -1, center: 0, top: 0},
"聊天": {head: 30, foot: 30, left: 100, right: 100, bottom: 300, center: 40, top: -2},
"最长": {head: 30, foot: 30, left: 0, right: 0, bottom: -2, center: 0, top: 0},
"全屏": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
}, border: 4,
}, scroll: {line: 100},
}

View File

@ -1 +0,0 @@
../lib

View File

@ -1,4 +0,0 @@
fieldset.Action div.output div.item:hover {
background-color:lightblue;
}

View File

@ -1,218 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_begin: function(can) {},
_start: function(can) {
can.page.Select(can, can.action, "input,select", function(input) {
input.value = can.user.Search(can, input.name) || input.value || ""
})
},
init: function(event, can, msg, cmd, field) {can.output.innerHTML = "";
can._local[msg.cmds[0]] = can._local[msg.cmds[0]] || {}
can._local[msg.cmds[0]][msg.cmds[1]] = msg.Table(function(item, index) {if (!item.name) {return}
// 添加插件
var plugin = can[item.name] = can.Plugin(can, item.name, item, function(event, cmds, cbs) {
can.run(event, [item.river, item.storm, item.action].concat(cmds), cbs)
}, can.page.AppendField(can, can.output, "item "+item.name, item))
return can._plugins.push(plugin), plugin
})
},
river: function(event, can, value, cmd, field) {if (value == "update") {return}
can.Conf("temp_river", value)
},
storm: function(event, can, value, cmd, field) {if (value == "update") {return}
// 保存界面
can.page.Cache(can.Conf("river")+"."+can.Conf("storm"), can.output, "some");
if (can.page.Cache(can.Conf("river", can.Conf("temp_river"))+"."+can.Conf("storm", value), can.output)) {
// 恢复界面
return
}
// 刷新界面
can.run(event, [can.Conf("river"), can.Conf("storm")], function(msg) {
can.onimport.init(event, can, msg, cmd, can.output)
})
},
pod: function(event, can, value, cmd, field) {
can.user.title(value)
},
you: function(event, can, value, cmd, field) {
can.user.title(value)
},
layout: function(event, can, value, cmd, field) {value},
scroll: function(event, can, value, cmd, field) {can.layout = value;
can.output.parentElement.scrollBy(value.x, value.y)
},
favor: function(event, can, msg, cmd, field) {if (msg._hand) {return}
var cmds = msg.detail, key = cmds[0];
if (key == can.Name()) {key = cmds[1], cmds = cmds.slice(1)}
// 下发数据
can.core.Item(can._local, function(river, list) {
can.core.Item(list, function(storm, list) {
can.core.List(list, function(sub) {
if (sub._name == key) {
sub.Select(event), msg._hand = true;
msg.Echo(can._name, " ", key)
}
})
})
})
},
})
Volcanos("onaction", {help: "组件交互", list: [
["layout"].concat(Config.layout.list), "清屏", "刷新", "并行","串行",
["action", "正常", "竖排", "编排", "定位", "定形"],
{input: "pod"}, {input: "you"},
{input: "hot"}, {input: "top"},
{input: "grp"}, {input: "lab"},
],
layout: function(event, can, value, cmd, field) {can.Export(event, cmd, value)},
"清屏": function(event, can, msg, cmd, field) {
can.page.Select(can, can.output, "fieldset.item>div.output", function(item) {
item.innerHTML = "";
})
},
"刷新": function(event, can, msg, cmd, field) {
can.page.Select(can, can.output, "fieldset.item>div.output", function(item) {
item.innerHTML = "";
})
can.run(event, [can.Conf("river"), can.Conf("storm")], function(msg) {
can.onimport.init(event, can, msg, cmd, can.output)
})
},
"并行": function(event, can, msg, cmd, field) {
can.page.Select(can, field, "fieldset.item", function(field) {
can.page.Select(can, field, "input[type=button]", function(input, index) {
index == 0 && input.click()
})
})
},
"串行": function(event, can, msg, cmd, field) {
can.core.Next(can.page.Select(can, field, "fieldset.item", function(field) {
return field
}), function(field, cb) {
can.page.Select(can, field, "input[type=button]", function(input, index) {
index == 0 && field.Check(event, input, cb)
})
})
},
"正常": function(event, can, value, cmd, field) {
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.setAttribute("draggable", false)
item.style.position = ""
item.style.cursor = ""
item.style.clear = ""
item.style.left = ""
item.style.top = ""
})
},
"竖排": function(event, can, value, cmd, field) {
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.style.clear = "both"
})
},
"编排": function(event, can, value, cmd, field) {
can.page.Select(can, can.target, "fieldset.item", function(item) {
item.setAttribute("draggable", true)
item.ondragstart = function(event) {can.drag = event.target}
item.ondragover = function(event) {event.preventDefault()}
item.ondrop = function(event) {event.preventDefault()
item.parentNode.insertBefore(can.drag, item)
}
})
},
"定位": function(event, can, value, cmd, field) {
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.style.left = item.offsetLeft + "px"
item.style.top = item.offsetTop + "px"
})
var max, current, begin;
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.style.position = "absolute"
item.onmousedown = function(event) {if (can.Action("action") != "定位") {return}
if (current) {
// 更新位置
current.style.left = begin.left + event.clientX - begin.x + "px"
current.style.top = begin.top + event.clientY - begin.y + "px"
current = null;
return
}
// 记录位置
current = item;
current.style["z-index"] = max = max + 1
begin = {x: event.clientX, y: event.clientY, left: item.offsetLeft, top: item.offsetTop}
};
can.output.onmousemove = item.onmousemove = function(event) {if (!current) {return}
// 移动位置
current.style.left = begin.left + event.clientX - begin.x + "px"
current.style.top = begin.top + event.clientY - begin.y + "px"
}
})
},
"定形": function(event, can, value, cmd, field) {
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.style.top = item.offsetTop + "px"
item.style.left = item.offsetLeft + "px"
item.style.width = item.offsetWidth + "px"
item.style.height = item.offsetHeight + "px"
})
var max, pos, current, begin;
can.page.Select(can, can.output, "fieldset.item", function(item) {
item.style.position = "absolute"
item.onmousedown = function(event) {
if (can.Action("action") != "定形") {return}
if (current) {current = null; return}
// 记录位置
current = item;
current.style["z-index"] = max = max + 1
begin = {
x: event.clientX, y: event.clientY,
left: item.offsetLeft, top: item.offsetTop,
width: item.offsetWidth, height: item.offsetHeight,
}
};
item.onmousemove = function(event) {
if (can.Action("action") != "定形") {return}
var pos = can.page.Prepos(event, item)
if (!current) {return}
can.page.Resize(event, current, begin, pos)
}
})
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["共享", "保存", "刷新"],
"共享": 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.key)
cmd == "提交" && can.Export(event, can.Name(), "share")
return true
})
},
"保存": function(event, can, msg, cmd, field) {
var list = []
can.page.Select(can, field, "fieldset.item", function(item) {var meta = item.Meta
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})
})
list.push(meta.node||"", meta.group, meta.index, meta.help, JSON.stringify(meta.args||[]))
})
can.run(event, [can.Conf("river"), can.Conf("storm"), "save"].concat(list), function(msg) {
can.user.toast("保存成功")
})
},
})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,29 +0,0 @@
fieldset.Footer {
clear:both;
overflow:hidden;
height:32px;
}
fieldset.Footer>div.action {
padding:0;
}
fieldset.Footer>div.output div.title {
float:left;
}
fieldset.Footer>div.output div.magic {
float:right;
margin-top:-6px;
}
fieldset.Footer>div.output div.magic>label {
margin-right:2px;
}
fieldset.Footer>div.output div.magic>input {
background-color:black;
color:lightgreen;;
}
fieldset.Footer>div.output div.state {
float:right;
}
fieldset.Footer>div.output div.state div {
float:right;
}

View File

@ -1,31 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_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(meta.state, function(item) {
return {text: meta[item]||"", className: item, click: function(event) {can.Export(event, meta[item], item)}};
})}])
})
}
},
username: function(event, can, value, cmd, field) {can._init()},
email: function(event, can, value, cmd, field) {
can.ui[cmd].innerHTML = value
},
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: []})

View File

@ -1,32 +0,0 @@
fieldset.Header {
height:32px;
min-width:640px;
clear:both;
}
fieldset.Header>div.action {
padding:0;
}
fieldset.Header>div.output>div.title {
cursor:pointer;
float:left;
}
fieldset.Header>div.output>div.title:hover {
cursor:pointer;
background-color:red;
border:ridge 2px yellow;
}
fieldset.Header>div.output>div.state {
float:right;
}
fieldset.Header>div.output>div.state div.item {
padding:0;
}
fieldset.Header>div.output>div.state>div {
cursor:pointer;
margin-left:5px;
float:right;
}
fieldset.Header>div.output>div.state>div:hover {
background-color:red;
}

View File

@ -1,59 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_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, meta.title, "title")},
}])
})
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.core.Timer({interval: 1000, length: -1}, function(event) {
can.onimport.time(event, can, can.base.Time().split(" ")[1], "time")
})
})
}
},
username: function(event, can, value, cmd, field) {can.Conf("user", value), can._init()},
title: function(event, can, value, cmd, field) {
can.ui[cmd].innerHTML = value
},
time: function(event, can, value, cmd, field) {
can.ui[cmd].innerHTML = value
},
river: function(event, can, value, cmd, field) {if (value == "update") {return}
can.Conf("river", value)
},
storm: function(event, can, value, cmd, field) {if (value == "update") {return}
can.Conf("storm", value)
},
layout: function(event, can, value, cmd, field) {if (value == "update") {return}
can.Conf("layout", value)
},
})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: [],
title: function(event, can, value, cmd, field) {
var args = {river: can.Conf("river"), storm: can.Conf("storm"), layout: can.Conf("layout")}
can.page.Select(can, document.body, "fieldset.Action>div.action input", function(input) {
input.name && input.value && (args[input.name] = input.value)
})
can.user.Search(can, args)
},
user: function(event, can, value, cmd, field) {
if (can.user.confirm("logout?")) {
can.user.Cookie(can, "sessid", "")
can.user.reload()
}
},
})

View File

@ -1,8 +0,0 @@
fieldset.Ocean div.create pre:hover {
background-color:red;
}
fieldset.Ocean div.create pre:hover {
background-color:red;
}

View File

@ -1,55 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output, action, option, field) {output.innerHTML = "";
var ui = can.page.Append(can, field, [{view: ["create"], list: [
{input: "name", value: can.Conf("def_name"), title: "群聊名称"},
{button: ["创建群聊", function(event) {
if (!ui.name.value) {ui.name.focus(); can.user.toast("请输入群名"); return}
var list = can.page.Select(can, ui.list, "tr", function(item, index) {if (index > 0) {
return item.dataset.user
}})
if (list.length == 0) {can.user.toast("请添加组员"); return}
can.run(event, ["spawn", ui.name.value].concat(list), function(msg) {
can.Hide(), can.Export(event, "update", "river");
})
}]}, {name: "list", view: ["list", "table"], list: [
{text: ["2. 已选用户列表", "caption"]},
{row: ["username", "usernode"], sub: "th"},
]},
]}])
can.ui = ui
},
init: function(event, can, msg, key, field) {can.output.innerHTML = ""; can.Show(event, -100, -100);
var table = can.page.Append(can, can.output, "table");
can.page.Appends(can, table, [{text: ["1. 选择用户节点 ->", "caption"]}])
can.page.AppendTable(can, table, msg, ["username", "usernode"], function(event, value, key, index, tr, td) {tr.className = "hidden";
var uis = can.page.Append(can, can.ui.list, [{type: "tr", list: [
{text: [msg["username"][index], "td"]},
{text: [msg["usernode"][index], "td"]},
], dataset: {user: value}, click: function(event) {
tr.className = "normal", can.page.Remove(can, uis.tr)
}}])
})
},
ocean: function(event, can, value, key, field) {
if (value == "create") {can.Show(event);
can.run(event, [], function(msg) {
can.onimport.init(event, can, msg, key, field);
});
}
},
})
Volcanos("onaction", {help: "组件交互", list: ["关闭", "刷新"],
"关闭": function(event, can, meta, key, field) {
can.Hide()
},
"刷新": function(event, can, meta, key, field) {
can.Import(event, "create", "ocean")
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["关闭", "刷新"]})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,13 +0,0 @@
fieldset.River {
float:left;
}
fieldset.River>div.output {
padding:0;
}
fieldset.River>div.output>div.item {
padding-left:6px;
}
fieldset.River>div.output>div.item.select {
background-color:red;
border:ridge 2px yellow;
}

View File

@ -1,79 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
init: function(event, can, msg, cmd, field) {can.output.innerHTML = "";
can.page.AppendItem(can, can.output, msg.Table(), can.user.Search(can, can.Name()), function(event, line, item) {
can.Export(event, line.key, can.Name())
})
},
river: function(event, can, value, cmd, field) {if (value == "update") {
can.run(event, [], function(msg) {
can.onimport.init(event, can, msg, cmd, field)
})
}},
favor: function(event, can, msg, cmd, field) {if (msg._hand) {return}
var cmds = msg.detail, key = cmds[0];
if (key == can.Name()) {key = cmds[1], cmds = cmds.slice(1)}
can.page.Select(can, field, "div.item>span", function(item) {
if (item.innerText == key) {
item.click(), msg._hand = true;
msg.Echo(can._name, " ", key)
}
})
},
})
Volcanos("onaction", {help: "组件交互", list: ["创建", "刷新"],
"创建": function(event, can, meta, cmd, field) {
can.Export(event, "create", "ocean")
},
"刷新": function(event, can, meta, cmd, field) {
can.Import(event, "update", can.Name())
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["创建", "刷新", "宽度"],
"宽度": function(event, can, meta, cmd, field) {
var begin;
function end() {
field.onmousedown = null;
field.onmousemove = null;
field.style.cursor = "";
begin = null;
}
field.style.cursor = "e-resize"
field.onmousedown = function(event) {if (begin) {return end()}
begin = {x: event.clientX, width: field.offsetWidth}
}
field.onmousemove = function(event) {if (!begin) {return}
field.dataset.width = field.style.width = begin.width + event.clientX - begin.x + "px";
can.Export(event, "", "layout");
}
can.user.prompt("输入宽度", function(width) {
field.dataset.width = field.style.width = width + "px"
can.Export(event, "", "layout")
end()
}, field.offsetWidth)
},
})
Volcanos("ondetail", {help: "组件详情", list: ["共享", "重命名", "删除"],
"共享": function(event, can, line, value, cmd, item) {
var msg = can.Event(event);
msg.Option("name", line.name)
msg.Option("text", line.key)
can.Export(event, can.Name(), "share")
},
"重命名": function(event, can, line, value, cmd, item) {
can.user.prompt("输入新名:", function(name) {
can.run(event, [value, "rename", name], function(msg) {
can.Import(event, "update", can.Name())
})
}, line.name)
},
"删除": function(event, can, line, value, cmd, item) {
can.run(event, [value, "remove"], function(msg) {
can.Import(event, "update", can.Name())
})
},
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,10 +0,0 @@
fieldset.Source {
overflow:hidden;
}
fieldset.Source div.action {
padding:0;
}
fieldset.Source div.output {
padding:0;
}

View File

@ -1,7 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: []})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,16 +0,0 @@
fieldset.Steam table.device {
padding:10px;
border:solid 1px green;
margin-left:10px;
float:left;
}
fieldset.Steam div.output tr.select {
background-color:red;
}
fieldset.Steam div.create {
/* clear:both; */
}
fieldset.Steam div.create pre:hover {
background-color:red;
}

View File

@ -1,113 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output, action, option, field) {output.innerHTML = "";
function create(event, cmd) {
if (!ui.name.value) {ui.name.focus(); can.user.toast("请输入群名"); return}
var list = []
can.page.Select(can, ui.list, "tr", function(item, index) {if (index > 0) {
list.push(item.dataset.pod)
list.push(item.dataset.key)
list.push(item.dataset.index)
list.push(item.dataset.help)
}})
var name = ui.name.value;
switch (event.target.value) {
case "创建应用": cmd = "spawn"; break
case "追加应用": cmd = "append", name = can.Conf("storm"); break
}
can.run(event, [can.Conf("river"), cmd, name].concat(list), function(msg) {
can.Hide(), can.Export(event, "update", "storm");
})
}
can.page.AppendAction(can, field, [{type: "text", name: "pod"}])
var device = can.page.Append(can, field, [{"view": ["device", "table"]}]).last
var ui = can.page.Append(can, field, [{view: ["create"], list: [
{input: "name", value: can.Conf("def_name"), title: "应用名称"},
{button: ["创建应用", create]},
{button: ["追加应用", create]},
{name: "list", view: ["list", "table"], list: [
{text: ["3. 已选命令列表", "caption"]},
{row: ["ctx", "cmd", "name", "help"], sub: "th"},
]},
]}])
can.device = device
can.ui = ui
},
init: function(event, can, msg, key) {can.output.innerHTML = ""; can.Show(event, -100, -100);
var table = can.page.Append(can, can.output, "table")
can.page.Append(can, table, [{text: ["1. 选择用户节点 ->", "caption"]}])
can.page.AppendTable(can, table, msg, ["type", "name", "user"], function(event, value, key, index, tr, td) {
can.page.Select(can, table, "tr.select", function(item) {can.page.ClassList.del(can, item, "select")})
can.page.ClassList.add(can, tr, "select")
var node = msg.name[index];
can.run(event, [can.Conf("river"), msg.user[index], node], function(com) {var list = com.Table()
can.page.Appends(can, can.device, [{text: ["2. 选择模块命令 ->", "caption"]}])
can.com = list, can.command = can.page.AppendTable(can, can.device, com, ["key", "index", "name", "help"], function(event, value, key, index, tr, td) {
var line = list[index];
line.pod = node;
var last = can.page.Append(can, can.ui.list, [{
row: [line.key, line.index, line.name, line.help], dataset: line,
click: function(event) {last.parentNode.removeChild(last)},
}]).first
}, function(event, value, key, index, tr, td) {
can.user.carte(event, shy(can.ondetail, can.ondetail.list, function(event, key, meta) {
meta[key](event, can, com, value, key, index, td)
}))
})
})
}), table.querySelector("td").click()
},
steam: function(event, can, value, key, field) {
if (value == "create") {
can.run(event, [can.Conf("river")], function(msg) {
can.onimport.init(event, can, msg, key, field);
});
}
},
river: function(event, can, value, key, field) {if (value == "update") {return}
can.Conf("river", value)
},
storm: function(event, can, value, key, field) {if (value == "update") {return}
can.Conf("storm", value)
},
})
Volcanos("onaction", {help: "组件交互", list: ["关闭", "刷新", {input: ["pod"]}, {input: ["cmd", function(event, can) {
}, function(event, can) {
if (event.key == "Enter") {
can.page.Select(can, can.command, "tr", function(tr, index) {
if (index == 0) {return}
if (!can.page.ClassList.has(can, tr, "hidden")) {
tr.firstChild.click()
event.target.value = ""
}
})
return
}
can.page.Select(can, can.command, "tr", function(tr, index) {
if (index == 0) {return}
if (can.com[index-1].index.indexOf(event.target.value) > -1) {
can.page.ClassList.del(can, tr, "hidden")
} else {
can.page.ClassList.add(can, tr, "hidden")
}
})
}]}],
"关闭": function(event, can, meta, key, field) {
can.Hide()
},
"刷新": function(event, can, meta, key, field) {
can.Import(event, "create", "steam")
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["关闭", "刷新"]})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,10 +0,0 @@
fieldset.Storm {
float:right;
}
fieldset.Storm>div.output {
padding:0;
}
fieldset.Storm>div.output>div.item {
padding-left:6px;
}

View File

@ -1,89 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
init: function(event, can, msg, cmd, field) {can.output.innerHTML = "";
can.page.AppendItem(can, can.output, msg.Table(), can.user.Search(can, can.Name()), function(event, line, item) {
can.Export(event, line.key, can.Name())
})
},
river: function(event, can, value, cmd, field) {if (value == "update") {return}
can.run(event, [can.Conf("river", value)], function(msg) {
can.onimport.init(event, can, msg, cmd, field)
})
},
storm: function(event, can, value, cmd, field) {
if (value == "update") {
can.run(event, [can.Conf("river")], function(msg) {
can.onimport.init(event, can, msg, cmd, field)
})
} else {
can.Conf(can.Name(), value)
}
},
favor: function(event, can, msg, cmd, field) {if (msg._hand) {return}
var cmds = msg.detail, key = cmds[0];
if (key == "river") {key = cmds[1], cmds = cmds.slice(1)}
can.page.Select(can, field, "div.item>span", function(item) {
if (item.innerText == key) {
item.click(), msg._hand = true;
msg.Echo(can._name, " ", key)
}
})
},
})
Volcanos("onaction", {help: "组件交互", list: ["创建", "刷新"],
"创建": function(event, can, meta, cmd, field) {
can.Export(event, "create", "steam")
},
"刷新": function(event, can, meta, cmd, field) {
can.Import(event, "update", can.Name())
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["创建", "刷新", "宽度"],
"宽度": function(event, can, meta, cmd, field) {
var begin;
function end() {
field.onmousedown = null;
field.onmousemove = null;
field.style.cursor = "";
begin = null;
}
field.style.cursor = "w-resize"
field.onmousedown = function(event) {if (begin) {return end()}
begin = {x: event.clientX, width: field.offsetWidth}
}
field.onmousemove = function(event) {if (!begin) {return}
field.dataset.width = field.style.width = begin.width - event.clientX + begin.x + "px";
can.Export(event, "", "layout");
}
can.user.prompt("输入宽度", function(width) {
field.dataset.width = field.style.width = width + "px"
can.Export(event, "", "layout")
end()
}, field.offsetWidth)
},
})
Volcanos("ondetail", {help: "组件详情", list: ["共享", "重命名", "删除"],
"共享": function(event, can, line, value, cmd, item) {can.share || (can.share = {});
var msg = can.Event(event);
msg.Option("name", line.name)
msg.Option("text", line.key)
can.Export(event, can.Name(), "share")
},
"重命名": function(event, can, line, value, cmd, item) {
can.user.prompt("输入新名:", function(name) {
can.run(event, [can.Conf("river"), value, "rename", name], function(msg) {
can.Import(event, "update", can.Name())
})
}, line.name)
},
"删除": function(event, can, line, value, cmd, item) {
can.run(event, [can.Conf("river"), value, "remove"], function(msg) {
can.Import(event, "update", can.Name())
})
},
})
Volcanos("onexport", {help: "导出数据", list: [],
})

View File

@ -1,23 +0,0 @@
fieldset.Target div.output div.item:hover {
background-color:lightgreen;
}
fieldset.Target>div.output>div.item {
padding-top:6px;
clear:both;
}
fieldset.Target>div.output>div.item>div.text {
padding:6px;
float:left;
}
fieldset.Target>div.output>div.item>div.time {
padding-left:5px;
font-size:10px;
color:gray;
}
fieldset.Target>div.output>div.item>div.user {
border-right:solid 1px green;
border-bottom:solid 1px green;
float:left;
padding:6px;
}

View File

@ -1,7 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: []})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,32 +0,0 @@
fieldset.dialog.Carte {
padding:0;
border:solid 2px red;
/* background-color:greenyellow; */
position:absolute;
display:none;
z-index:200;
}
fieldset.dialog.Carte>div.action {
padding:0;
}
fieldset.dialog.Carte>div.output {
padding:0;
}
fieldset.dialog.Carte>div.output button {
display:block;
}
fieldset.dialog.Carte>div.output select {
display:block;
}
fieldset.dialog.Carte>div.output div.layout>div {
float:left;
}
fieldset.dialog.Carte>div.output div.item {
padding:0px 6px;
}
fieldset.dialog.Carte>div.output div.space {
border:solid 1px gray;
margin-top:8px;
clear:both;
}

View File

@ -1,41 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output, action, option, field) {
can.user.carte = function(event, cb, src) {if (!cb || !cb.list || cb.list.length == 0) {return}
output.innerHTML = "", can.page.Append(can, output, can.core.List(cb.list, function(item) {
return {view: ["item"], list: [typeof item == "string"? {text: [item], click: function(event) {
typeof cb == "function" && cb(event, item, cb.meta)
}}: item.args? {text: [item.name], click: function(event) {
can.user.input(event, can, item.args, function(event, cmd, form, list) {
var msg = can.Event(event);
can.core.Item(form, function(key, value) {msg.Option(key, value)})
cmd == "提交" && typeof cb == "function" && cb(event, item.name, cb.meta)
return true
})
}}: {select: [item, function(event) {
typeof cb == "function" && cb(event, event.target.value, cb.meta)
}], value: src[item[0]]||""}]}
}))
can.page.Select(can, output, "select", function(item) {
item.value = src[item.className]||""
})
var pos = {display: "block", left: event.x, top: event.y}
if (document.body.clientWidth - event.x < 60) {
var pos = {display: "block", right: event.x, top: event.y}
}
pos.left += "px"; pos.top += "px";
can.page.Modify(can, field, {style: pos})
event.stopPropagation()
event.preventDefault()
can.Show(event)
}
},
})
Volcanos("onaction", {help: "组件交互", list: [],
onmouseleave: function(event, can) {can.Hide()},
})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,49 +0,0 @@
fieldset.dialog.Debug {
opacity:0.8;
}
fieldset.dialog.Debug tr.hide {
display:none;
}
fieldset.dialog.Debug tr.event {
background-color:red;
}
fieldset.dialog.Debug tr.run {
background-color:lightgreen;
}
fieldset.dialog.Debug tr.wss {
background-color:lightblue;
}
fieldset.dialog.Debug tr.key {
background-color:lightyellow;
}
fieldset.dialog.Debug>div.output {
overflow:auto;
margin-top:50px;
}
fieldset.dialog.Debug>div.output table caption {
position:absolute;
top:50px;
left:20px;
}
fieldset.dialog.Debug>div.output table thead {
position:absolute;
top:72px;
left:18px;
}
fieldset.dialog.Debug>div.output table thead th {
border:solid 1px red;
}
fieldset.dialog.Debug>div.output table caption>span {
margin-right:4px;
}
fieldset.dialog.Debug>div.output table caption>span:hover {
cursor:pointer;
background-color:red;
}
fieldset.dialog.Debug>div.output table th {
min-width:60px;
}
fieldset.dialog.Debug>div.output table td {
min-width:60px;
}

View File

@ -1,7 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: []})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,28 +0,0 @@
fieldset.Favor {
border:solid 2px red;
background-color:rgba(100,100,100,0.8);
position:absolute;
display:none;
z-index:100;
}
fieldset.Favor input.cmd {
color:white;
font-size:16px;
font-weight:bold;
font-family:monospace;
background-color:black;
border:solid 1px white;
padding:4px;
min-width:383px;
}
fieldset.Favor div.output {
color:white;
font-size:16px;
font-family:monospace;
white-space:pre;
max-width:640px;
max-height:240px;
overflow:auto;
}

View File

@ -1,84 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output, action, option, field) {
can.Show(event, 400, 100), can.Hide();
can.target.style.height = ""
can.target.style.width = ""
function res(msg) {
if (msg._hand) {ui.cmd.value = "", output.innerHTML = "";
msg.result && msg.result.length > 0? can.page.Append(can, output, [{text: msg.Result()}]):
can.page.AppendTable(can, output, msg, msg.append);
}
return msg
}
function run(event, cmds) {cmds = can.core.Split(cmds);
var cmd = cmds[0]; if (cmd == "") {return}
can.msg = can.Event(event, {detail: cmds});
var cb = can.onexport[cmd];
typeof cb == "function"? cb(event, can, can.msg, cmds, output): can.Export(event, can.msg, "favor");
return can.msg._hand? res(can.msg): can.run(event, cmds, res, true);
}
var ui = can.page.Append(can, option, [{input: ["cmd", function(event) {
switch (event.key) {
case "Enter": run(event, event.target.value); return
case "Escape": can.Hide(); return
default: if (event.target.value.endsWith("j") && event.key == "k") {
can.page.DelText(event.target, event.target.selectionStart-1, 2)
event.target.value == ""? can.Hide(): run(event, event.target.value)
return
}
}
can.page.oninput(event, can)
return true
}, function(event) {
switch (event.key) {
default: return false
}
event.stopPropagation()
event.preventDefault()
return true
}]}])
},
space: function(event, can, value, cmd, field) {
can.page.Select(can, can.Show(), "input.cmd", function(item) {
item.focus()
})
},
})
Volcanos("onaction", {help: "组件交互", list: ["关闭", "清空", "下载"],
onmousedown: function(event, can) {
if (event.ctrlKey) {can.moving = !can.moving, can.movarg = {
left: can.target.offsetLeft,
top: can.target.offsetTop,
x: event.x, y: event.y,
}}
},
onmousemove: function(event, can) {
if (can.moving) {
can.target.style.top = can.movarg.top + event.y - can.movarg.y + "px"
can.target.style.left = can.movarg.left + event.x - can.movarg.x + "px"
}
},
onmouseup: function(event, can) {
},
"关闭": function(event, can, value, cmd, field) {
can.Hide();
},
"清空": function(event, can, value, cmd, field) {
can.output.innerHTML = ""
},
"下载": function(event, can, value, cmd, field) {
var list = can.msg.Export(can._name);
can.page.Download(can, list[0]+list[1], list[2]);
},
})
Volcanos("onchoice", {help: "组件菜单", list: ["下载", "关闭"]})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: [],
time: function(event, can, msg, cmd, field) {msg.Echo(can.base.Time())},
})

View File

@ -1,12 +0,0 @@
fieldset.Login {
font-size:24px;
z-index:20;
}
fieldset.Login>form.option input {
height:24px;
}
fieldset.Login>form.option button {
font-size:18px;
height:28px;
}

View File

@ -1,72 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output, action, option, field) {
can.user.login = function(cb) {
var cbs = function(res) {
typeof cb == "function" && cb(res)
can.Export({}, res.name, "username")
}
can.misc.WSS(can, "", {node: "active", user: can.user.title()}, function(event, msg, cmd, arg) {
switch (cmd) {
case "space":
can._share = arg[1]
break
case "sessid":
can.user.Cookie(can, "sessid", arg[0]), can.user.toast(""), can.Hide()
cbs({name: msg["user.name"]})
break
}
})
can.user.Cookie("sessid")? can.onaction.check(event, can, cbs, "check", output):
can.onaction.login(event, can, cbs, "login", output)
}
},
share: function(event, can, value, cmd, target) {var msg = can.Event(event)
var list = [];
switch (value) {
case "storm": list.push("river", msg.Conf("river")); break
case "action": list.push("river", msg.Conf("river")), list.push("storm", msg.Conf("storm")); break
}
can.run(event, ["share", value, msg.Option("name"), msg.Option("text")].concat(list), function(msg) {
var p = "/share/" + msg.Result(); can.user.toast({title: msg.Option("name"),
text: [{text: '<a target="_blank" href="'+can.user.Share(can, {path: p}, true)+'">'+p+'</a>'}, {img: p+"/share"}],
width: 300, height: 400, duration: 300000,
})
})
},
})
Volcanos("onaction", {help: "组件交互", list: [],
check: function(event, can, cb, cmd, target) {
can.run(event||{}, ["check"], function(msg) {var user = msg.nickname && msg.nickname[0] || msg.Result()
user? typeof cb == "function" && cb({name: user}): can.onaction.login(event, can, cb, "login", target)
})
},
login: function(event, can, cb, cmd, target) {
var ui = can.page.Appends(can, target, [
{text: ["账号: ", "label"]}, {username: []}, {type: "br"},
{text: ["密码: ", "label"]}, {password: []}, {type: "br"},
{button: ["密码登录", function(event, cmd) {
if (!ui.username.value) {ui.username.focus(); return}
if (!ui.password.value) {ui.password.focus(); return}
can.run(event, ["login", ui.username.value, ui.password.value], function(msg) {
if (msg.result && msg.result.length > 0) {
can.Hide(), can.onaction.check(event, can, cb, "check", target)
return
}
can.user.toast(can, "用户或密码错误")
})
}]},
{button: ["扫码登录", function(event, cmd) {
can.user.toast(can, {title: "请用微信扫码("+can._share+")", list: [{img: [can.user.Share(can, {
path: "/share/"+can._share+"/value",
}, true)]}]})
}]},
{type: "br"},
])
can.Show(event, -1, -1)
},
})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,41 +0,0 @@
fieldset.Toast {
border:solid 2px red;
/* background-color:rgba(100,100,100,0.8); */
position:absolute;
display:none;
z-index:200;
}
fieldset.Toast>div.action {
padding:0 0px;
}
fieldset.Toast>div.output {
padding:0 10px;
text-align:center;
}
fieldset.Toast>div.output>div.title {
font-size:12px;
text-align:center;
/* color:gray; */
}
fieldset.Toast>div.output>div.content {
word-break:break-word;
white-space:pre-wrap;
text-align:center;
margin:0px;
padding:2px;
font-size:16px;
}
fieldset.Toast>div.output table {
/* color:yellow */
}
fieldset.Toast>div.output table th {
/* background:red; */
}
fieldset.Toast>div.output table td {
white-space:pre;
}
fieldset.Toast>div.output>div.tick {
font-size:12px;
/* color:gray; */
}

View File

@ -1,47 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, conf, output) {
can.Show(200, 100, -100)
can.target.style.height = ""
can.target.style.width = ""
var timer;
can.user.toast = function(text, title, duration, action) {if (!text) {return can.Hide()}
text = typeof text == "object"? text: {list: action, text: text, title: title||""}
text.duration = text.duration || conf.duration || 3000
var list = [{text: [text.title||"", "div", "title"]},
typeof text.text == "string"? {text: [text.text||"", "div", "content"]}: {view: "content", list: text.text},
{view: ["form"], list: text.list||[{type: "button", inner: "ok", click: function() {
timer.stop = true
}}]},
{text: [text.tick||"", "div", "tick"]},
]
var toast = can.page.Appends(can, output, list)
var width = text.width||text.text.length*10+100
width = width>800?800:width
can.Show(event, text.width==undefined? width: text.width, text.height==undefined? 80: text.height)
toast.Hide = can.Hide
toast.Show = can.Show
if (text.duration == -1) {return {toast: toast}}
var begin = can.base.Time().split(" ")[1]
timer = can.core.Timer({value: 1000, length: text.duration > 0? text.duration/1000: text.duration}, function(t, i) {
if (i < 10) {return}
if (i > 10000) {return true}
toast.tick.innerHTML = can.base.Duration(i*t) + " after " + begin
console.log(t, i)
}, function() {
can.Hide()
})
timer.toast = toast
return timer
}
},
})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,9 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: []})
Volcanos("onaction", {help: "组件交互", list: []})
Volcanos("onchoice", {help: "组件菜单", list: []})
Volcanos("ondetail", {help: "组件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/index.css">
</head>
<body>
<script src="/proto.js"></script>
<script src="config.js"></script>
<script src="chrome.js"></script>
</body>
<html>

View File

@ -1,155 +0,0 @@
var can = Volcanos("chrome", {
_send: function(msg, cb) {chrome.extension.sendRequest(msg, cb)},
_open: function(url) {chrome.windows.create({url: url})},
run: function(can, msg, cb) {msg = can.Event({}, msg)
msg.Option("sid", can.sid||"")
can.misc.Run({names: "code/chrome/crx", msg: msg}, can, {}, null, cb)
},
open: function(msg, cmd, cb) {
chrome.windows.create({url: cmd[0]})
typeof cb == "function" && cb(msg)
},
wins: function(msg, cmd, cb) {
if (cmd.length == 0) {
// 窗口列表
chrome.windows.getAll(function(wins) {
can.core.List(wins, function(win) {win.wid = win.id
msg.Push(win, ["wid", "state", "left", "top", "width", "height"])
})
typeof cb == "function" && cb(msg)
})
return
}
if (cmd.length > 1) {
// 新建标签
chrome.tabs.create({windowId: parseInt(cmd[0]), url: cmd[1], selected: false}, function() {
can.wins(msg, [cmd[0]], cb)
})
return
}
// 标签列表
chrome.tabs.getAllInWindow(parseInt(cmd[0]), function(tabs) {
can.core.List(tabs, function(tab) {tab.tid = tab.id
msg.Push(tab, ["tid", "active", "width", "height", "index", "title", "url"])
})
typeof cb == "function" && cb(msg)
})
},
tabs: function(msg, cmd, cb) {
if (cmd.length == 0) {
chrome.tabs.getAllInWindow(function(tabs) {
can.core.List(tabs, function(tab) {
msg.Push("id", tab.id)
msg.Push("active", tab.active)
msg.Push("index", tab.index)
msg.Push("title", tab.title)
msg.Push("url", tab.url)
})
typeof cb == "function" && cb(msg)
})
return
}
chrome.tabs[cmd[1]](parseInt(cmd[0]), cb)
},
cookie: function(msg, cmd, cb) {
if (cmd[0] == "modify") {var data = {}; data[cmd[1]] = cmd[2]
chrome.bookmarks.update(cmd[4], data, function() {
typeof cb == "function" && cb(msg)
})
return
} else if (cmd[0] == "delete") {
chrome.bookmarks.remove(cmd[2], function() {
typeof cb == "function" && cb(msg)
})
return
} else if (cmd.length > 2) {
chrome.bookmarks.create({parentId: cmd[0], url: cmd[1], title: cmd[2], index: cmd[3]||0}, cb)
}
chrome.cookies.getAll({name: ""}, function(cs) {
typeof cb == "function" && cb(msg)
})
},
history: function(msg, cmd, cb) {
chrome.tabs.getAllInWindow(function(tabs) {
can.core.List(tabs, function(tab) {
msg.Push("id", tab.id)
msg.Push("active", tab.active)
msg.Push("index", tab.index)
msg.Push("title", tab.title)
msg.Push("url", tab.url)
})
typeof cb == "function" && cb(msg)
})
},
bookmark: function(msg, cmd, cb) {
if (cmd[0] == "modify") {var data = {}; data[cmd[1]] = cmd[2]
chrome.bookmarks.update(cmd[4], data, function() {
typeof cb == "function" && cb(msg)
})
return
} else if (cmd[0] == "delete") {
chrome.bookmarks.remove(cmd[2], function() {
typeof cb == "function" && cb(msg)
})
return
} else if (cmd.length > 2) {
chrome.bookmarks.create({parentId: cmd[0], url: cmd[1], title: cmd[2], index: cmd[3]||0}, cb)
}
chrome.bookmarks.getSubTree(cmd[0]||"0", function(labs) {
for (var i = 0; i < labs.length; i++) {labs[i].pid = labs[i].parentId
msg.Push("time", can.base.Time(labs[i].dateAdded))
msg.Push(labs[i], ["pid", "id", "index", "title", "url"])
labs = labs.concat(labs[i].children||[])
}
typeof cb == "function" && cb(msg)
})
},
}, Config.libs.concat(Config.list), function(can) {can.Conf(Config)
can.user.toast = function(message, title) {chrome.notifications.create(null, {
message: message, title: title||Config.title, iconUrl: "/favicon.ico", type: "basic",
})},
can.misc.WSS(can, "ws://localhost:9020/space/", {node: "chrome", name: chrome.runtime.id}, function(event, msg) {
if (msg.Option("_handle")) {return can.user.toast(msg.result.join(""))}
can.user.toast(msg.detail.join(" "))
switch (msg.detail[0]) {
case "space": can._share = msg.detail[2]; break
case "pwd": msg.Echo("hello world"); break
default: (can[msg.detail[0]]||can.chrome[msg.detail[0]])(msg, msg.detail.slice(1), function(msg) {
msg.Reply(msg)
}); return
}
msg.Reply(msg)
}, function() {can.user.toast("wss connect", "iceberg")})
can.run(can, {cmd: ["login", can.sid||""]}, function(msg) {
can.sid = msg.Result()
})
chrome.history.onVisited.addListener(function(item) {
can.run(can, {cmd: ["history", item.id, item.url, item.title]}, function(msg) {
can.user.toast(item.url, item.title)
})
})
chrome.bookmarks.onCreated.addListener(function(id, item) {
chrome.bookmarks.get(item.parentId, function(root) {
can.run(can, {cmd: ["bookmark", item.id, item.url, item.title, root[0].title]}, function(msg) {
can.user.toast(item.url, item.title)
})
})
})
chrome.extension.onRequest.addListener(function(msg, sender, cb) {
can.run(can, msg, cb)
})
})

View File

@ -1,41 +0,0 @@
var Config = {iceberg: "http://localhost:9020/", volcano: "/",
libs: ["lib/base", "lib/core", "lib/misc", "lib/page", "lib/user"],
main: "chat", list: ["page/chat",
"pane/Toast", "pane/Tutor", "pane/Debug",
"pane/Carte", "pane/Favor", "pane/Login",
"pane/Header",
"pane/Ocean", "pane/River", "pane/Storm", "pane/Steam",
"pane/Target", "pane/Source", "pane/Action",
"pane/Footer",
"plugin/state", "plugin/input", "plugin/table", "plugin/inner",
], pane: [
{group: "index", name: "Toast", pos: "dialog", duration: 3000},
{group: "index", name: "Tutor", pos: "dialog"},
{group: "index", name: "Debug", pos: "dialog"},
{group: "index", name: "Carte", pos: "dialog"},
{group: "index", name: "Favor", pos: "dialog"},
{group: "index", name: "Login", pos: "dialog"},
{group: "index", name: "Header", pos: "head", state: ["time", "user", "link"], title: "github.com/shylinux/context"},
{group: "index", name: "Ocean", pos: "dialog", def_name: "meet"},
{group: "index", name: "River", pos: "left"},
{group: "index", name: "Storm", pos: "right"},
{group: "index", name: "Steam", pos: "dialog", def_name: "miss"},
{group: "index", name: "Target", pos: "top"},
{group: "index", name: "Source", pos: "center"},
{group: "index", name: "Action", pos: "bottom"},
{group: "index", name: "Footer", pos: "foot", state: ["ntxt", "ncmd"], title: '<a href="mailto:shylinux@163.com">shylinux@163.com</a>'},
], title: "范晓旭", layout: {def: "办公", list: ["工作", "办公", "聊天"], size: {
"最大": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
"工作": {head: 30, foot: 30, left: 0, right: 100, bottom: -1, center: 0, top: 0},
"办公": {head: 30, foot: 30, left: 100, right: 100, bottom: -1, center: 0, top: 0},
"聊天": {head: 30, foot: 30, left: 100, right: 100, bottom: 300, center: 40, top: -2},
"全屏": {head: 0, foot: 0, left: 0, right: 0, bottom: -1, center: 0, top: 0},
}, border: 4,
},
}

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/index.css">
</head>
<body style="min-height:400px">
<script src="/proto.js"></script>
<script src="config.js"></script>
<script src="/frame.js"></script>
<!-- <script src="popup.js"></script> -->
</body>
<html>

View File

@ -1,19 +0,0 @@
var can = Volcanos("popup", {
demo: function() {
can.chrome.notice("hi", "hello")
},
}, Config.libs.concat(Config.list), function(can) {can.Conf(Config)
can.page.Append(can, document.body, [{button: ["baidu", function() {
can.chrome.open("https://www.baidu.com")
}]}])
can.page.Append(can, document.body, [{button: ["volcanos", function() {
can.chrome.open("http://localhost:9020")
}]}])
can.page.Append(can, document.body, [{button: ["send", function() {
can.chrome.send({names: "crx", cmds: ["hi"]}, function(msg) {
can.chrome.notice("hi", "hello")
console.log(msg)
})
}]}])
})

View File

@ -1,13 +0,0 @@
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: []})

View File

@ -1,117 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [],
init: shy("添加控件", function(can, item, name, value, option) {
var input = {type: "input", name: 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.value = value || item.value || "";
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 target = can.Dream(option, "input", input)[input.name];
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 = value || item.value || item.values[item.index||0])
item.type == "button" && item.action == "auto" && can.run && can.run({});
return target;
}),
path: function(event, can, value, cmd, target) {
return target.value + (target.value == "" || target.value.endsWith("/")? "": "/") + value
},
})
Volcanos("onfigure", {help: "控件交互", list: []})
Volcanos("onaction", {help: "控件交互", list: [],
onclick: function(event, can) {can.Select(event);
var figure = can.onfigure[can.item.cb] || can.onfigure[can.item.figure]
figure? can.page.AppendFigure(event, can, can.item.figure, can._name) && figure.click(event, can, can.item, can.item.name, event.target, can.figure):
can.item.type == "button" && can.run(event)
},
onchange: function(event, can) {
can.item.type == "select" && can.item.action == "auto" && can.Runs(event)
},
onkeydown: function(event, can) {
if (event.target.tagName == "TEXTAREA") {return}
can.page.oninput(event, can, function(event) {
switch (event.key) {
case "b":
can.Append(event)
return true
case "m":
can.Clone(event)
return true
}
})
switch (event.key) {
case "Enter": can.run(event, []); break
case "Escape": event.target.blur(); break
default:
if (event.target.value.endsWith("j") && event.key == "k") {
can.page.DelText(event.target, event.target.selectionStart-1, 2);
event.target.blur();
break
}
return false
}
event.stopPropagation()
event.preventDefault()
return true
},
onkeyup: function(event, can) {
if (event.target.tagName == "TEXTAREA") {return}
switch (event.key) {
default: return false
}
event.stopPropagation()
event.preventDefault()
return true
},
})
Volcanos("onchoice", {help: "控件菜单", list: ["全选", "复制", "清空"],
"全选": function(event, can, msg, value, target) {
can.target.focus(), can.target.setSelectionRange(0, can.target.value.length);
},
"复制": function(event, can, msg, value, target) {
can.user.toast(can.page.CopyText(can, can.target.value), "复制成功")
},
"清空": function(event, can, msg, value, target) {
can.target.value = "";
},
})
Volcanos("ondetail", {help: "控件详情", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,13 +0,0 @@
Volcanos("onfigure", {help: "控件详情", list: [],
city: {click: function(event, can, value, cmd, target, figure) {
function run() {figure.output.innerHTML = ""
can.Run(event, ["action", "input", can.item.name, target.value], function(msg) {
can.page.AppendTable(can, figure.output, msg, msg.append, function(event, value, key, index, tr, td) {
target.value = value; msg.Option("_refresh") && run()
})
}, true)
}
run()
}},
})

View File

@ -1,73 +0,0 @@
Volcanos("onfigure", {help: "控件详情", list: [],
date: {click: function(event, can, value, cmd, target, figure) {
// 设置输入
target.style.width = "120px"
function set(now) {
target.value = can.base.Time(now);
can.item.action == "auto" && can.run({});
}
// 添加插件
figure.table = can.page.Append(can, figure.output, [{type: "table"}]).first
// 添加控件
can.now = target.value? new Date(target.value): new Date();
var control = can.page.AppendAction(can, figure.action, ["今天", "随机",
["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)), {view: ["", "br"]},
{type: "hr", style: {margin: 0}}, {type: "br"},
"上一月", ["year"].concat(can.core.List(can.now.getFullYear() - 20, can.now.getFullYear() + 20)),
["month"].concat(can.core.List(1, 13)), "下一月", {view: ["", "br"]},
], function(event, value, cmd) {can.stick = true;
// 设置时间
switch (cmd) {
case "year": can.now.setFullYear(parseInt(value)); show(can.now); return;
case "month": can.now.setMonth(parseInt(value)-1); show(can.now); return;
case "hour": can.now.setHours(parseInt(value)); set(show(can.now)); return;
case "minute": can.now.setMinutes(parseInt(value)); set(show(can.now)); return;
case "second": can.now.setSeconds(parseInt(value)); set(show(can.now)); return;
}
// 设置日期
switch (value) {
case "今天": can.now = new Date(); set(show(can.now)); break;
case "随机": can.now.setDate((Math.random() * 100 - 50) + can.now.getDate()); set(show(can.now)); break;
case "关闭": can.page.Remove(can, figure.first); delete(can.figure);
case "前一年": can.now.setFullYear(can.now.getFullYear()-1); show(can.now); break;
case "后一年": can.now.setFullYear(can.now.getFullYear()+1); show(can.now); break;
case "上一月": can.now.setMonth(can.now.getMonth()-1); show(can.now); break;
case "下一月": can.now.setMonth(can.now.getMonth()+1); show(can.now); break;
}
})
function show(now) {
// 设置控件
control.month.value = now.getMonth()+1;
control.year.value = now.getFullYear();
control.hour.value = now.getHours();
control.minute.value = parseInt(now.getMinutes()/5)*5;
control.second.value = parseInt(now.getSeconds()/5)*5;
// 设置组件
can.page.Appends(can, figure.table, [{type: "tr", list: can.core.List(["日", "一", "二", "三", "四", "五", "六"], function(day) {return {text: [day, "th"]}})}])
var tr; function add(day, type) {if (day.getDay() == 0) {tr = can.page.Append(can, figure.table, [{type: "tr"}]).tr}
can.page.Append(can, tr, [{text: [day.getDate(), "td", can.base.Time(day).split(" ")[0] == can.base.Time(now).split(" ")[0]? "select": type],
dataset: {date: day.getTime()}, click: function(event) {set(can.now = new Date(parseInt(event.target.dataset.date)))},
}])
}
// 时间区间
var one = new Date(now); one.setDate(1);
var end = new Date(now); end.setMonth(now.getMonth()+1); end.setDate(1);
var head = new Date(one); head.setDate(one.getDate()-one.getDay());
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay());
// 时间序列
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) {add(day, "last")}
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) {add(day, "main")}
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) {add(day, "next")}
return now
}
set(show(can.now));
}},
})

View File

@ -1,12 +0,0 @@
Volcanos("onfigure", {help: "控件详情", list: [],
key: {click: function(event, can, value, cmd, target, figure) {
function run() {figure.output.innerHTML = ""
can.Run(event, ["action", "input", can.item.name, target.value], function(msg) {
can.page.AppendTable(can, figure.output, msg, msg.append, function(event, value, key, index, tr, td) {
target.value = value; msg.Option("_refresh") && run()
})
}, true)
}
run()
}},
})

Some files were not shown because too many files have changed in this diff Show More