efront 3.17.2 → 3.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pivot/api/edit.js +1 -0
- package/apps/pivot/api/list.js +20 -0
- package/apps/pivot/api.yml +8 -4
- package/apps/pivot/dict/edit.js +1 -0
- package/apps/pivot/dict/list.js +12 -0
- package/apps/pivot/link/chat.js +32 -0
- package/apps/pivot/link/chat.less +5 -0
- package/apps/pivot/link/list.html +6 -3
- package/apps/pivot/link/list.js +23 -2
- package/apps/pivot/link/list.less +10 -2
- package/apps/pivot/menu.yml +4 -1
- package/apps/pivot/proxy/list.js +9 -8
- package/apps/pivot/task/list.js +1 -1
- package/apps/pivot/user/api.html +2 -0
- package/apps/pivot/user/api.js +14 -0
- package/apps/pivot/user/api.less +0 -0
- package/coms/basic/Speed.js +0 -1
- package/coms/basic/assert.js +5 -3
- package/coms/basic/lazy.js +19 -9
- package/coms/basic/lazy_test.js +62 -0
- package/coms/basic/parseURL.js +21 -2
- package/coms/basic/refilm_decode.js +4 -2
- package/coms/frame/chat.html +19 -0
- package/coms/frame/chat.js +60 -0
- package/coms/frame/chat.less +177 -0
- package/coms/frame/design.html +7 -0
- package/coms/frame/design.js +23 -0
- package/coms/frame/design.less +17 -0
- package/coms/frame/dict.js +21 -0
- package/coms/frame/edit.js +1 -1
- package/coms/frame/list.js +1 -1
- package/coms/frame/route.js +1 -0
- package/coms/kugou/song.html +1 -1
- package/coms/kugou/song.js +2 -1
- package/coms/pivot/pedit.js +3 -3
- package/coms/pivot/plist.js +2 -2
- package/coms/zimoli/HexEditor.js +1 -0
- package/coms/zimoli/HexEditor.less +2 -2
- package/coms/zimoli/Item.js +5 -0
- package/coms/zimoli/cloneVisible.js +1 -0
- package/coms/zimoli/container.js +13 -7
- package/coms/zimoli/data.js +26 -12
- package/coms/zimoli/design.html +5 -4
- package/coms/zimoli/design.less +8 -3
- package/coms/zimoli/drag.js +1 -1
- package/coms/zimoli/field.html +1 -1
- package/coms/zimoli/grid.js +69 -19
- package/coms/zimoli/list.js +5 -5
- package/coms/zimoli/menu.js +7 -6
- package/coms/zimoli/menuItem.js +1 -1
- package/coms/zimoli/menuList.js +2 -1
- package/coms/zimoli/model.js +4 -3
- package/coms/zimoli/render.js +70 -32
- package/coms/zimoli/tree.js +1 -1
- package/coms/zimoli/vbox.js +2 -2
- package/coms/zimoli/zimoli.js +12 -2
- package/package.json +1 -1
- package/public/efront.js +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pedit.bind(null, "接口", "api");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
var types = refilm`
|
|
2
|
+
数值/number
|
|
3
|
+
文本/input
|
|
4
|
+
`;
|
|
5
|
+
model.setModels({
|
|
6
|
+
design: frame$dict.bind(null, types),
|
|
7
|
+
});
|
|
8
|
+
return plist.bind(null, '接口管理', "api", refilm`
|
|
9
|
+
*接口路径/path 100
|
|
10
|
+
接口名/name 100
|
|
11
|
+
请求方法/method select [get,post,put,patch,options]
|
|
12
|
+
数据格式/format select [JSON,JSAM,URLencode]
|
|
13
|
+
!参数/fields design ${[
|
|
14
|
+
{
|
|
15
|
+
name: "修改",
|
|
16
|
+
}
|
|
17
|
+
]}
|
|
18
|
+
加密方式/crypt select [timeencode,encode62]
|
|
19
|
+
*是否启用/status radio [不启用,启用]
|
|
20
|
+
`, '/api/edit');
|
package/apps/pivot/api.yml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/ authorization=:
|
|
1
|
+
/ authorization=:
|
|
2
2
|
login: options ::login-:a
|
|
3
3
|
run: options :::run
|
|
4
4
|
share: options ::share-:opt?:path
|
|
@@ -6,15 +6,19 @@
|
|
|
6
6
|
cluster: options ::cluster-:opt?:id
|
|
7
7
|
list: options :::type
|
|
8
8
|
edit: options :::type-:key?:value
|
|
9
|
+
add: options :::type-:key+:value
|
|
9
10
|
params: options ::params-:key
|
|
10
11
|
invoke: options ::invoke-:key?:params
|
|
11
12
|
version: options ::version
|
|
12
13
|
uptime: options ::uptime
|
|
13
14
|
count: options ::count
|
|
14
15
|
bootlog: options ::similar
|
|
15
|
-
|
|
16
|
+
link: options ::link
|
|
17
|
+
care: options ::care-:id
|
|
18
|
+
cast: options ::cast-:id?:msg
|
|
19
|
+
https://www.ip.cn/:
|
|
16
20
|
iplocation: get https://www.ip.cn/api/index?ip=:ip&type=1
|
|
17
21
|
# https://ipchaxun.com/ :
|
|
18
|
-
# iplocation: get:[].info%20label:nth-child(n+2)>span:nth-child(2) :ip/
|
|
22
|
+
# iplocation: get:[].info%20label:nth-child(n+2)>span:nth-child(2) :ip/
|
|
19
23
|
# https://www.ip138.com/:
|
|
20
|
-
# iplocation: get:head>script:nth-last-child(1) iplookup.asp?ip=:ip&action=2
|
|
24
|
+
# iplocation: get:head>script:nth-last-child(1) iplookup.asp?ip=:ip&action=2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pedit.bind(null, "字典", "dict");
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
async function link(id, page) {
|
|
2
|
+
if (!id) {
|
|
3
|
+
id = await data.from("link");
|
|
4
|
+
}
|
|
5
|
+
page.$scope.title = `会话窗口(<span nodrag>${id}</span>)`;
|
|
6
|
+
page.roomid = id;
|
|
7
|
+
var removed = false;
|
|
8
|
+
on("remove")(page, function () {
|
|
9
|
+
removed = true;
|
|
10
|
+
if (xhr.abort) xhr.abort();
|
|
11
|
+
});
|
|
12
|
+
var xhr = null;
|
|
13
|
+
while (true) {
|
|
14
|
+
if (removed) break;
|
|
15
|
+
xhr = data.from("care", { id }, function (data) {
|
|
16
|
+
page.$scope.msglist.push.apply(page.$scope.msglist, data);
|
|
17
|
+
var { msglist } = page.$scope;
|
|
18
|
+
var chat = page.querySelector("chat");
|
|
19
|
+
chat.go(msglist.length ? msglist.length - 1 : 0);
|
|
20
|
+
});
|
|
21
|
+
await xhr;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function main(id) {
|
|
25
|
+
console.log(id)
|
|
26
|
+
var page = frame$chat();
|
|
27
|
+
care(page, 'send', function (msg) {
|
|
28
|
+
data.from("cast", { id: page.roomid, msg });
|
|
29
|
+
});
|
|
30
|
+
link(id, page);
|
|
31
|
+
return page;
|
|
32
|
+
}
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
<a -repeat="(c,i) in clusters" ng-class="{current:i===index.index}" @click="active(i,c)">
|
|
3
3
|
<span -text="c"></span>
|
|
4
4
|
</a>
|
|
5
|
+
自动刷新<swap -model="autoreload"></swap>
|
|
6
|
+
<btn @click="chat()">新建连接</btn>
|
|
5
7
|
</div>
|
|
6
8
|
<lattice -src="c in clients">
|
|
7
9
|
<padding>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
<item @click="chat(c.id)">
|
|
11
|
+
<span -text=c.id></span>
|
|
12
|
+
<span class="time" -text=filterTime(c.optime)></span>
|
|
13
|
+
</item>
|
|
11
14
|
</padding>
|
|
12
15
|
</lattice>
|
package/apps/pivot/link/list.js
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
|
+
var autoreload = true;
|
|
1
2
|
function main() {
|
|
2
3
|
var page = div();
|
|
3
4
|
page.innerHTML = template;
|
|
4
5
|
renderWithDefaults(page, {
|
|
5
|
-
async
|
|
6
|
-
this.clusters = data.
|
|
6
|
+
load: lazy(async function () {
|
|
7
|
+
this.clusters = data.lazyInstance("cluster", { opt: "list" });
|
|
7
8
|
await this.clusters;
|
|
8
9
|
this.active();
|
|
10
|
+
}, -1000),
|
|
11
|
+
chat(id) {
|
|
12
|
+
popup("/link/chat", id);
|
|
13
|
+
},
|
|
14
|
+
get autoreload() {
|
|
15
|
+
return autoreload;
|
|
16
|
+
},
|
|
17
|
+
set autoreload(v) {
|
|
18
|
+
autoreload = v;
|
|
19
|
+
clearInterval(loadid);
|
|
20
|
+
if (autoreload) page.$reload();
|
|
9
21
|
},
|
|
10
22
|
index: data.getInstance("index"),
|
|
11
23
|
clusters: [],
|
|
@@ -20,6 +32,15 @@ function main() {
|
|
|
20
32
|
this.clients = data.from("cluster", { opt: "list", id: clusters[index] });
|
|
21
33
|
},
|
|
22
34
|
});
|
|
35
|
+
var loadid = 0;
|
|
36
|
+
on("append")(page, function () {
|
|
37
|
+
if (autoreload) loadid = setInterval(function () {
|
|
38
|
+
page.$scope.load();
|
|
39
|
+
}, 30);
|
|
40
|
+
});
|
|
41
|
+
on('remove')(page, function () {
|
|
42
|
+
clearInterval(loadid);
|
|
43
|
+
});
|
|
23
44
|
page.$scope.load();
|
|
24
45
|
return page;
|
|
25
46
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
.clusters a {
|
|
2
2
|
display: inline-block;
|
|
3
|
-
margin-right: 20px;
|
|
4
3
|
padding: 0 6px;
|
|
5
4
|
}
|
|
6
|
-
|
|
5
|
+
.clusters>*{
|
|
6
|
+
vertical-align: top;
|
|
7
|
+
margin-right: 12px;
|
|
8
|
+
}
|
|
9
|
+
.clusters{
|
|
10
|
+
padding-left: 6px;
|
|
11
|
+
}
|
|
7
12
|
.time {
|
|
8
13
|
color: #bbb;
|
|
9
14
|
}
|
|
@@ -11,4 +16,7 @@
|
|
|
11
16
|
.button.current {
|
|
12
17
|
background: #28c;
|
|
13
18
|
color: #fff;
|
|
19
|
+
}
|
|
20
|
+
btn{
|
|
21
|
+
padding: 0 16px;
|
|
14
22
|
}
|
package/apps/pivot/menu.yml
CHANGED
|
@@ -4,14 +4,17 @@ WEB:
|
|
|
4
4
|
短链接: /proxy/list
|
|
5
5
|
文件管理: /wow/root
|
|
6
6
|
长连接管理: /link/list
|
|
7
|
+
字典: /dict/list
|
|
8
|
+
接口: /api/list
|
|
7
9
|
任务:
|
|
8
10
|
密钥管理: /token/list
|
|
9
11
|
任务建立: /task/list
|
|
10
12
|
定期执行: /tick/list
|
|
13
|
+
# 服务器: /api/host
|
|
11
14
|
用户:
|
|
12
15
|
账号列表: /user/list
|
|
13
16
|
标签管理: /user/tag/list
|
|
14
17
|
服务器日志:
|
|
15
18
|
访问计数: /log/count
|
|
16
19
|
启动记录: /log/boot
|
|
17
|
-
# 并发记忆: /log/lock
|
|
20
|
+
# 并发记忆: /log/lock
|
package/apps/pivot/proxy/list.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
var fields = refilm`
|
|
2
2
|
*代理路径/url input/20
|
|
3
3
|
真实路径/realpath url/2000
|
|
4
|
-
/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
4
|
+
动作/action select/200 [跳转,转发]
|
|
5
|
+
/ $ ${[{
|
|
6
|
+
name: "访问",
|
|
7
|
+
do(o) {
|
|
8
|
+
var url = o.url;
|
|
9
|
+
if (!/^\//.test(url)) url = "/" + url;
|
|
10
|
+
window.open(url, null);
|
|
11
|
+
}
|
|
12
|
+
}]}`;
|
|
12
13
|
return plist.bind(null, '短链接', "proxy", fields, "/proxy/edit");
|
package/apps/pivot/task/list.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function main() {
|
|
2
|
+
var page = document.createElement('user-api');
|
|
3
|
+
page.innerHTML = template;
|
|
4
|
+
renderWithDefaults(page, {
|
|
5
|
+
apilist: ["查询", "添加", "删除", "登录"].map(a => {
|
|
6
|
+
var [name, path] = a.split(' ');
|
|
7
|
+
return { name };
|
|
8
|
+
}),
|
|
9
|
+
xlist: menu,
|
|
10
|
+
})
|
|
11
|
+
page.$scope.apilist[1].actived = true;
|
|
12
|
+
console.log(page.$scope)
|
|
13
|
+
return page;
|
|
14
|
+
}
|
|
File without changes
|
package/coms/basic/Speed.js
CHANGED
package/coms/basic/assert.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
var dump = function (a) {
|
|
2
|
-
if (a instanceof Object) console.error('对象的属性不符合'), console.log(" ", a);
|
|
1
|
+
var dump = function (a, msg) {
|
|
2
|
+
if (a instanceof Object) console.error('对象的属性不符合'), console.log(msg ? msg + " " : " ", a);
|
|
3
|
+
else if (msg) console.error(msg + ":", a);
|
|
3
4
|
else console.error(a);
|
|
4
5
|
};
|
|
5
6
|
var assert = function (result, expect, log = dump) {
|
|
@@ -48,7 +49,8 @@ var assert = function (result, expect, log = dump) {
|
|
|
48
49
|
}
|
|
49
50
|
if (!res) {
|
|
50
51
|
if (!hasCollect) collect()();
|
|
51
|
-
if (log) log(errors);
|
|
52
|
+
if (typeof log === 'function') log(errors);
|
|
53
|
+
else dump(errors, log);
|
|
52
54
|
}
|
|
53
55
|
return res;
|
|
54
56
|
}
|
package/coms/basic/lazy.js
CHANGED
|
@@ -5,17 +5,28 @@
|
|
|
5
5
|
function lazy(run, time = false) {
|
|
6
6
|
var wait = +time ? setTimeout : requestAnimationFrame;
|
|
7
7
|
var ing, args, that;
|
|
8
|
+
var hire = function () {
|
|
9
|
+
if (time >= 0) {
|
|
10
|
+
if (ing === true) ing = wait(fire, +time / 2);
|
|
11
|
+
else wait(fire, +time / 2), ing = -2;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
wait(fire, -time);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
8
17
|
var fire = function () {
|
|
9
18
|
if (time >= 0) {
|
|
10
19
|
if (ing === true) {
|
|
11
20
|
ing = wait(fire, +time / 2);
|
|
12
21
|
}
|
|
13
|
-
else if (
|
|
14
|
-
wait(fire, +time);
|
|
15
|
-
ing =
|
|
22
|
+
else if (ing > 0) {
|
|
23
|
+
wait(fire, +time / 2);
|
|
24
|
+
ing = -1;
|
|
16
25
|
}
|
|
17
|
-
else if (ing ===
|
|
26
|
+
else if (ing === -1) {
|
|
18
27
|
ing = run.apply(that, args);
|
|
28
|
+
if (ing instanceof Promise) ing.then(hire, hire);
|
|
29
|
+
else ing = false;
|
|
19
30
|
}
|
|
20
31
|
else {
|
|
21
32
|
ing = false;
|
|
@@ -24,13 +35,12 @@ function lazy(run, time = false) {
|
|
|
24
35
|
else {
|
|
25
36
|
if (ing === true) {
|
|
26
37
|
ing = run.apply(that, args);
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
if (ing instanceof Promise) ing.then(hire, hire);
|
|
39
|
+
else ing = wait(fire, -time);
|
|
29
40
|
} else {
|
|
30
41
|
ing = false;
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
|
-
if (ing instanceof Promise) ing.then(fire, fire);
|
|
34
44
|
};
|
|
35
45
|
return function () {
|
|
36
46
|
args = arguments;
|
|
@@ -41,8 +51,8 @@ function lazy(run, time = false) {
|
|
|
41
51
|
}
|
|
42
52
|
else {
|
|
43
53
|
ing = run.apply(that, args);
|
|
44
|
-
if (ing instanceof Promise) ing.then(
|
|
45
|
-
ing = wait(fire, -time);
|
|
54
|
+
if (ing instanceof Promise) ing.then(hire, hire);
|
|
55
|
+
else ing = wait(fire, -time);
|
|
46
56
|
}
|
|
47
57
|
};
|
|
48
58
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
var lazy = require("./lazy");
|
|
2
|
+
var assert = require("./assert");
|
|
3
|
+
async function test(sch, pending, callsch) {
|
|
4
|
+
pending = +pending || 0;
|
|
5
|
+
var wait = t => new Promise(a => setTimeout(a, t));
|
|
6
|
+
var waits = t => wait(t * Math.abs(sch));
|
|
7
|
+
var waite = async (t) => (await waits(t), await wait(pending));
|
|
8
|
+
var count = 0, start = Date.now(), time = start;
|
|
9
|
+
var f = lazy(function () {
|
|
10
|
+
count++;
|
|
11
|
+
var now = Date.now();
|
|
12
|
+
var delta = now - time;
|
|
13
|
+
time = now;
|
|
14
|
+
if (count > 1) assert(delta >= Math.abs(sch), true, '触发间隔' + delta);
|
|
15
|
+
console.log('sch', sch, 'count', count, 'pass', now - start, 'delta', delta, 'pending', pending);
|
|
16
|
+
if (pending) return wait(pending);
|
|
17
|
+
}, sch);
|
|
18
|
+
f();
|
|
19
|
+
f();
|
|
20
|
+
f();
|
|
21
|
+
f();
|
|
22
|
+
f();
|
|
23
|
+
callsch = +callsch || 1;
|
|
24
|
+
var i = setInterval(f, callsch);
|
|
25
|
+
await wait(.5);
|
|
26
|
+
if (sch < 0) assert(count, 1, '周期小于0,一个周期内触发');
|
|
27
|
+
if (sch > 0) assert(count, 0, '周期大于0时,一个周期内不触发');
|
|
28
|
+
await waite(1.5);
|
|
29
|
+
if (sch < 0) assert(count, 2, '周期小于0,不到两个周期内触发');
|
|
30
|
+
await waits(9);
|
|
31
|
+
if (sch > 0 && sch > callsch) assert(count, 0, '周期大于0时,10个周期内不触发');
|
|
32
|
+
clearInterval(i);
|
|
33
|
+
await waits(2);
|
|
34
|
+
if (sch > 0 && sch > callsch) assert(count, 1, '周期大于0时,等待一个多周期后触发');
|
|
35
|
+
await waite(2);
|
|
36
|
+
var saved_count = count;
|
|
37
|
+
await waite(5);
|
|
38
|
+
assert(saved_count, count, '未调用时不触发');
|
|
39
|
+
f();
|
|
40
|
+
await waite(2);
|
|
41
|
+
assert(count, saved_count + 1, '非连续调用时,第一次触发');
|
|
42
|
+
f();
|
|
43
|
+
await waite(2);
|
|
44
|
+
assert(count, saved_count + 2, '非连续调用时,第二次触发');
|
|
45
|
+
f();
|
|
46
|
+
await waite(2);
|
|
47
|
+
assert(count, saved_count + 3, '非连续调用时,第二次触发');
|
|
48
|
+
}
|
|
49
|
+
test(100);
|
|
50
|
+
test(-100);
|
|
51
|
+
test(100, 10);
|
|
52
|
+
test(100, 80);
|
|
53
|
+
test(100, 180);
|
|
54
|
+
test(-100, 10, 11);
|
|
55
|
+
test(-100, 80, 81);
|
|
56
|
+
test(-100, 180, 181);
|
|
57
|
+
test(100, 10, 11);
|
|
58
|
+
test(100, 80, 81);
|
|
59
|
+
test(100, 180, 181);
|
|
60
|
+
// test(-100, 180);
|
|
61
|
+
// test(NaN);
|
|
62
|
+
// test(NaN, 80);
|
package/coms/basic/parseURL.js
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
1
|
+
// 下图来自 https://nodejs.org/dist/latest-v16.x/docs/api/url.html#urlobjectauth
|
|
2
|
+
// ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
3
|
+
// │ href │
|
|
4
|
+
// ├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤
|
|
5
|
+
// │ protocol │ │ auth │ host │ path │ hash │
|
|
6
|
+
// │ │ │ ├─────────────────┬──────┼──────────┬────────────────┤ │
|
|
7
|
+
// │ │ │ │ hostname │ port │ pathname │ search │ │
|
|
8
|
+
// │ │ │ │ │ │ ├─┬──────────────┤ │
|
|
9
|
+
// │ │ │ │ │ │ │ │ query │ │
|
|
10
|
+
// " https: // user : pass @ sub.example.com : 8080 /p/a/t/h ? query=string #hash "
|
|
11
|
+
// │ │ │ │ │ hostname │ port │ │ │ │
|
|
12
|
+
// │ │ │ │ ├─────────────────┴──────┤ │ │ │
|
|
13
|
+
// │ protocol │ │ username │ password │ host │ │ │ │
|
|
14
|
+
// ├──────────┴──┼──────────┴──────────┼────────────────────────┤ │ │ │
|
|
15
|
+
// │ origin │ │ origin │ pathname │ search │ hash │
|
|
16
|
+
// ├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤
|
|
17
|
+
// │ href │
|
|
18
|
+
// └────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
19
|
+
|
|
20
|
+
// -------/// ---------------1---------------------------------///////////////////2-----3--------//////// ------4----2/////5---------------------------------------------------6-----------------------------------------------------------------------------//////////////-7--5///8-------9----------//10--11---10/8/--12----////
|
|
21
|
+
var reg = /^([^\:\/\\\?#\[]+\:(?![^\:\/\\\?\#]*@|[\/\\][^\/\\]))?(?:\/\/|\\\\)?(?:(([^\:\/\\\?#]+)?(?:\:([^\/\\\?#]+))?)@)?(([^\/\\@\?\#\.]*?[^\/\\@\:\?\#\.\d][^\/\\@\:\?\#\.]*?|[^\/\\@\:\?\#\.]+(?:\:[\@\/\\\?#\.]*[^\d\@\:\/\\\?#\.]+|\.[^\/\\@\:\?\#]+?))?(?:(?:\:|^)(\d+))?)(((?:\/|\\|^)[^\?#]*)?(\?([^#]*))?)(#[\s\S]*)?$/;
|
|
3
22
|
function parseURL(url) {
|
|
4
23
|
if (url === undefined || url === null) url = '';
|
|
5
24
|
var [__, protocol, auth, username, password, host, hostname, port, path, pathname, search, query, hash] = reg.exec(url);
|
|
@@ -277,14 +277,15 @@ function parse(piece) {
|
|
|
277
277
|
var reg = /^[\*\+\-\!\-\$&\?\~]|[\*\+\-\!\-\$&\?\~]$/;
|
|
278
278
|
if (!reg.test(a)) return a;
|
|
279
279
|
required = test(/^\*|\*$/, a);
|
|
280
|
-
|
|
280
|
+
if (test(/^[\+]|[\+]$/, a)) inlist = true;
|
|
281
|
+
if (test(/^[\!]|[\!]$/, a)) inlist = false;
|
|
281
282
|
hidden = test(/^\-|\-$/, a);
|
|
282
283
|
readonly = test(/^[\$&]|[\$&]$/, a);
|
|
283
284
|
delete_onempty = test(/^\?|\?$/, a);
|
|
284
285
|
delete_onsubmit = test(/^\~|\~$/, a);
|
|
285
286
|
return a.replace(reg, '');
|
|
286
287
|
};
|
|
287
|
-
|
|
288
|
+
var type1 = is(type);
|
|
288
289
|
if (typeof name === 'string') {
|
|
289
290
|
if (!isContainer) {
|
|
290
291
|
if (!type) {
|
|
@@ -299,6 +300,7 @@ function parse(piece) {
|
|
|
299
300
|
type = last_type;
|
|
300
301
|
}
|
|
301
302
|
} else {
|
|
303
|
+
type = type1;
|
|
302
304
|
last_type = type;
|
|
303
305
|
}
|
|
304
306
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div head>
|
|
2
|
+
<template -src="title">
|
|
3
|
+
</template>
|
|
4
|
+
<close @click="remove()"></close>
|
|
5
|
+
</div>
|
|
6
|
+
<grid body #body>
|
|
7
|
+
<chat -src="m in msglist">
|
|
8
|
+
<padding>
|
|
9
|
+
<msg class="msg"></msg>
|
|
10
|
+
<div style="clear: both;"></div>
|
|
11
|
+
</padding>
|
|
12
|
+
</chat>
|
|
13
|
+
<div textarea @mousedown="this.firstChild.focus()">
|
|
14
|
+
<div @input="resize(body)" @keydown.alt.enter="send()" contenteditable="true" -model="text"></div>
|
|
15
|
+
</div>
|
|
16
|
+
</grid>
|
|
17
|
+
<div foot>
|
|
18
|
+
<btn @click="send();">发送</btn>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
function msg(elem, { m: data }, parentScopes) {
|
|
3
|
+
if (!data) return;
|
|
4
|
+
data = encode62.timedecode(data);
|
|
5
|
+
var m = JSAM.parse(data);
|
|
6
|
+
if (m.sender === parentScopes[parentScopes.length - 1].localid) {
|
|
7
|
+
elem.setAttribute("self", "");
|
|
8
|
+
}
|
|
9
|
+
if (m) switch (m.type) {
|
|
10
|
+
case "html":
|
|
11
|
+
elem.innerHTML = m.content;
|
|
12
|
+
break;
|
|
13
|
+
default:
|
|
14
|
+
elem.innerText = data;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function chat(title = '会话窗口') {
|
|
18
|
+
var page = view();
|
|
19
|
+
page.innerHTML = template;
|
|
20
|
+
drag.on(page.firstChild, page);
|
|
21
|
+
resize.on(page);
|
|
22
|
+
renderWithDefaults(page, {
|
|
23
|
+
chat: list,
|
|
24
|
+
title,
|
|
25
|
+
grid,
|
|
26
|
+
msglist: [],
|
|
27
|
+
text: '',
|
|
28
|
+
localid: Math.random(),
|
|
29
|
+
msg,
|
|
30
|
+
remove() {
|
|
31
|
+
remove(page);
|
|
32
|
+
},
|
|
33
|
+
resize(body) {
|
|
34
|
+
var textarea = body.querySelector("[textarea]");
|
|
35
|
+
var lastElementChild = textarea.lastElementChild;
|
|
36
|
+
var targetHeight = Math.min(textarea.scrollHeight, body.clientHeight * .6, lastElementChild.offsetTop + lastElementChild.offsetHeight);
|
|
37
|
+
if (Math.abs(targetHeight - textarea.clientHeight) < 2) return;
|
|
38
|
+
|
|
39
|
+
body.resizeCell(textarea, 'top', textarea.clientHeight - targetHeight - 2);
|
|
40
|
+
},
|
|
41
|
+
send() {
|
|
42
|
+
if (!this.text) return;
|
|
43
|
+
var data = JSAM.stringify({
|
|
44
|
+
type: 'html',
|
|
45
|
+
sender: this.localid,
|
|
46
|
+
content: this.text,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
data = encode62.timeencode(data);
|
|
50
|
+
if (this.text.length > 2000) {
|
|
51
|
+
alert("信息太长,无法发送!");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
cast(page, "send", data);
|
|
55
|
+
this.body.lastElementChild.focus();
|
|
56
|
+
this.text = '';
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return page;
|
|
60
|
+
}
|