efront 4.5.0 → 4.5.4
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/#/345/233/275/351/231/205/345/214/226.yml +30 -0
- package/apps/pivot/api.yml +1 -0
- package/apps/pivot/cert/edit.js +1 -0
- package/apps/pivot/cert/list.js +9 -0
- package/apps/pivot/cert/main.xht +25 -18
- package/apps/pivot/cert/orders.xht +107 -30
- package/apps/pivot/cert/update.xht +7 -0
- package/coms/basic/cross_.js +2 -1
- package/coms/basic/valid.js +4 -2
- package/coms/compile/Javascript.js +26 -12
- package/coms/frame/edit.html +1 -0
- package/coms/frame/edit.js +3 -2
- package/coms/pivot/acme2.js +134 -29
- package/coms/pivot/pedit.js +13 -5
- package/coms/pivot/plist.js +12 -5
- package/coms/zimoli/button.less +1 -0
- package/coms/zimoli/container.js +8 -1
- package/coms/zimoli/data.js +64 -127
- package/coms/zimoli/list.js +2 -2
- package/coms/zimoli/model.js +20 -3
- package/coms/zimoli/scrollbar.js +2 -0
- package/coms/zimoli/view.js +10 -7
- package/coms/zimoli/view.less +1 -1
- package/coms/zimoli/watch.js +1 -1
- package/docs//347/273/204/344/273/266.xht +0 -1
- package/package.json +2 -3
- package/public/efront.js +1 -2
- package/readme-en.md +0 -2
- package/readme.md +0 -2
package/coms/pivot/acme2.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
var acmebase = `https://acme-v02.api.letsencrypt.org/`;
|
|
2
|
-
// <!-- acmebase=`https://acme-staging-v02.api.letsencrypt.org/` -->
|
|
3
2
|
var data1 = data.enrich(parseYML(`
|
|
4
3
|
${acmebase}:
|
|
5
4
|
directory: get directory
|
|
@@ -21,20 +20,13 @@ var base64url = function (params) {
|
|
|
21
20
|
};
|
|
22
21
|
var accountApi = await data1.getApi('get-account');
|
|
23
22
|
var orderApi = await data1.getApi('get-order');
|
|
24
|
-
|
|
25
|
-
var request = async function (id, params) {
|
|
26
|
-
var api = await data1.getApi(id);
|
|
27
|
-
if (/^(get|head)$/i.test(api.method)) return data1.from(id, params);
|
|
23
|
+
var wrapParams = async function (url, params, usejwk = false) {
|
|
28
24
|
var protected = {
|
|
29
|
-
url
|
|
25
|
+
url
|
|
30
26
|
};
|
|
31
|
-
var rest;
|
|
32
|
-
[protected.url, rest] = data.prepareURL(protected.url, params);
|
|
33
|
-
var restparams = {};
|
|
34
|
-
rest.forEach(k => { restparams[k] = params[k]; delete params[k]; });
|
|
35
27
|
var jwk = await subtle.exportKey("jwk", publicKey);
|
|
36
28
|
protected.alg = jwk.alg;
|
|
37
|
-
if (
|
|
29
|
+
if (usejwk) {
|
|
38
30
|
protected.jwk = {
|
|
39
31
|
e: jwk.e,
|
|
40
32
|
kty: jwk.kty,
|
|
@@ -45,17 +37,124 @@ var request = async function (id, params) {
|
|
|
45
37
|
protected.kid = acme2.kid;
|
|
46
38
|
}
|
|
47
39
|
protected.nonce = await data1.from("new-nonce");
|
|
48
|
-
var payload = isEmpty(params) ? '' : base64url(params);
|
|
49
40
|
protected = base64url(protected);
|
|
41
|
+
var payload = isHandled(params) ? base64url(params) : '';
|
|
50
42
|
var params = {
|
|
51
43
|
protected,
|
|
52
44
|
payload,
|
|
53
45
|
signature: toBase64(new Uint8Array(await subtle.sign({ name: RSASSA_PKCS1_v1_5, saltLength: 32 }, privateKey, new Uint8Array(encodeUTF8([protected, '.', payload].join(''))))), true)
|
|
54
46
|
};
|
|
47
|
+
return params;
|
|
48
|
+
}
|
|
49
|
+
var request = async function (id, params) {
|
|
50
|
+
var api = await data1.getApi(id);
|
|
51
|
+
if (/^(get|head)$/i.test(api.method)) return data1.from(id, params);
|
|
52
|
+
var [url, rest] = data.prepareURL(api.base + api.path, params);
|
|
53
|
+
var restparams = {};
|
|
54
|
+
rest.forEach(k => { restparams[k] = params[k]; delete params[k]; });
|
|
55
|
+
var params = await wrapParams(url, params, /new-account|revert-cert/i.test(id));
|
|
55
56
|
extend(params, restparams);
|
|
56
57
|
var account = await data1.from(id, params);
|
|
57
58
|
return account;
|
|
58
59
|
};
|
|
60
|
+
var ASN1 = function (type) {
|
|
61
|
+
var length = 0;
|
|
62
|
+
var bytesarr = [];
|
|
63
|
+
for (var cx = 1, dx = arguments.length; cx < dx; cx++) {
|
|
64
|
+
var bytes = arguments[cx];
|
|
65
|
+
if (bytes.constructor !== Array) {
|
|
66
|
+
bytes = Array.apply(null, bytes);
|
|
67
|
+
}
|
|
68
|
+
bytesarr.push(bytes);
|
|
69
|
+
length += bytes.length;
|
|
70
|
+
}
|
|
71
|
+
var asn1 = [type];
|
|
72
|
+
if (length === (2 << 8 | 36)) console.log(arguments)
|
|
73
|
+
if (length > 127) {
|
|
74
|
+
var nums = [];
|
|
75
|
+
while (length > 0) {
|
|
76
|
+
nums.unshift(length & 0xff);
|
|
77
|
+
length = length >>> 8;
|
|
78
|
+
}
|
|
79
|
+
asn1.push(0x80 | nums.length, ...nums);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
asn1.push(length);
|
|
83
|
+
}
|
|
84
|
+
asn1 = asn1.concat(...bytesarr);
|
|
85
|
+
return asn1;
|
|
86
|
+
};
|
|
87
|
+
var packUint = function (bytes) {
|
|
88
|
+
if (bytes[0] & 0x80) {
|
|
89
|
+
return ASN1(0x02, [0], bytes);
|
|
90
|
+
}
|
|
91
|
+
return ASN1(0x02, bytes);
|
|
92
|
+
};
|
|
93
|
+
var packBits = function (bytes) {
|
|
94
|
+
return ASN1(0x03, [0x00], bytes);
|
|
95
|
+
};
|
|
96
|
+
var packPublicKey = function (jwk) {
|
|
97
|
+
var n = packUint(fromBase64(jwk.n));
|
|
98
|
+
var e = packUint(fromBase64(jwk.e));
|
|
99
|
+
var p = ASN1(0x30, n, e);
|
|
100
|
+
return ASN1(0x30, ASN1(0x30,
|
|
101
|
+
ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01]),
|
|
102
|
+
ASN1(0x05),
|
|
103
|
+
), packBits(p));
|
|
104
|
+
};
|
|
105
|
+
var packCSR = function (asn1pubkey, domains) {
|
|
106
|
+
return ASN1(0x30,
|
|
107
|
+
packUint([0x00]),
|
|
108
|
+
ASN1(0x30, ASN1(0x31, ASN1(0x30,
|
|
109
|
+
ASN1(0x06, [0x55, 0x04, 0x03]),
|
|
110
|
+
ASN1(0x0c, encodeUTF8(domains[0]))
|
|
111
|
+
))),
|
|
112
|
+
asn1pubkey,
|
|
113
|
+
ASN1(0xa0, ASN1(0x30,
|
|
114
|
+
ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e]),
|
|
115
|
+
ASN1(0x31, ASN1(0x30, ASN1(0x30,
|
|
116
|
+
ASN1(0x06, [0x55, 0x1d, 0x11]),
|
|
117
|
+
ASN1(0x04, ASN1(0x30,
|
|
118
|
+
...domains.map(d => ASN1(0x82, encodeUTF8(d)))
|
|
119
|
+
))
|
|
120
|
+
)))
|
|
121
|
+
))
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var createCSR = async function (domains, private_key) {
|
|
126
|
+
var privateKey = await subtle.importKey("pkcs8", new Uint8Array(fromBase64(private_key)), {
|
|
127
|
+
name: RSASSA_PKCS1_v1_5,
|
|
128
|
+
hash: "SHA-256",
|
|
129
|
+
}, true, ["sign"]);
|
|
130
|
+
var jwk = await subtle.exportKey("jwk", privateKey);
|
|
131
|
+
var pubkey = packPublicKey(jwk);
|
|
132
|
+
var request = packCSR(pubkey, domains);
|
|
133
|
+
var sign = new Uint8Array(await subtle.sign({ name: RSASSA_PKCS1_v1_5, saltLength: 32 }, privateKey, new Uint8Array(request)));
|
|
134
|
+
var sty = ASN1(0x30,
|
|
135
|
+
ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b]),
|
|
136
|
+
ASN1(0x05)
|
|
137
|
+
);
|
|
138
|
+
return ASN1(0x30, request,
|
|
139
|
+
sty,
|
|
140
|
+
packBits(sign)
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
var makeKeyPair = async function (modulusLength = 2048) {
|
|
144
|
+
//https://www.w3.org/TR/WebCryptoAPI/ 第20章 只有RSASSA-PKCS1-v1_5的jwk的alg才是rs256
|
|
145
|
+
var k = await subtle.generateKey({
|
|
146
|
+
name: RSASSA_PKCS1_v1_5,
|
|
147
|
+
modulusLength,
|
|
148
|
+
publicExponent: new Uint8Array([1, 0, 1]),
|
|
149
|
+
hash: "SHA-256",
|
|
150
|
+
}, true, ["sign", "verify"]);
|
|
151
|
+
var { publicKey, privateKey } = k;
|
|
152
|
+
var private_key = await subtle.exportKey("pkcs8", privateKey);
|
|
153
|
+
var public_key = await subtle.exportKey("spki", publicKey);
|
|
154
|
+
private_key = toBase64(new Uint8Array(private_key));
|
|
155
|
+
public_key = toBase64(new Uint8Array(public_key));
|
|
156
|
+
return [private_key, public_key];
|
|
157
|
+
};
|
|
59
158
|
var subtle = this.crypto?.subtle;
|
|
60
159
|
var acme2 = new class {
|
|
61
160
|
email = '';
|
|
@@ -69,19 +168,14 @@ var acme2 = new class {
|
|
|
69
168
|
get enabled() {
|
|
70
169
|
return !!subtle;
|
|
71
170
|
}
|
|
171
|
+
async requestURL(url, params) {
|
|
172
|
+
params = await wrapParams(url, params);
|
|
173
|
+
var res = data.postURL(url, params);
|
|
174
|
+
if (res.loading) res.loading.setRequestHeader("Content-Type", "application/jose+json");
|
|
175
|
+
return res;
|
|
176
|
+
}
|
|
72
177
|
async initUnique() {
|
|
73
|
-
|
|
74
|
-
var k = await subtle.generateKey({
|
|
75
|
-
name: RSASSA_PKCS1_v1_5,
|
|
76
|
-
modulusLength: 4096,
|
|
77
|
-
publicExponent: new Uint8Array([1, 0, 1]),
|
|
78
|
-
hash: "SHA-256",
|
|
79
|
-
}, true, ["sign", "verify"]);
|
|
80
|
-
var { publicKey, privateKey } = k;
|
|
81
|
-
private_key = await subtle.exportKey("pkcs8", privateKey);
|
|
82
|
-
public_key = await subtle.exportKey("spki", publicKey);
|
|
83
|
-
private_key = toBase64(new Uint8Array(private_key));
|
|
84
|
-
public_key = toBase64(new Uint8Array(public_key));
|
|
178
|
+
[private_key, public_key] = await makeKeyPair(4096);
|
|
85
179
|
var unique = [private_key, public_key].join(',');
|
|
86
180
|
await acme2.makeUnique(unique);
|
|
87
181
|
}
|
|
@@ -145,40 +239,51 @@ var acme2 = new class {
|
|
|
145
239
|
this.kid = account;
|
|
146
240
|
var a = data.getUrlParamsForApi(accountApi, account);
|
|
147
241
|
this.aid = a.aid;
|
|
242
|
+
alert('创建成功!', 'success');
|
|
148
243
|
return account;
|
|
149
244
|
}
|
|
150
245
|
async newOrder(params) {
|
|
246
|
+
if (!this.orders) this.orders = [];
|
|
247
|
+
if (this.orders.length > 20) return alert("请删除一些订单后再试!", "error");
|
|
151
248
|
var params = {
|
|
152
249
|
"identifiers": params.domain.trim().split(/[,;+,;\r\n\u2029\u2028\s]+/).map(n => {
|
|
153
|
-
if (/^\d+(\.\d+){3}
|
|
250
|
+
if (/^\d+(\.\d+){3}$/.test(n)) return { type: "ipv4", value: n };
|
|
154
251
|
return { type: "dns", value: n };
|
|
155
252
|
})
|
|
156
253
|
};
|
|
157
254
|
var order = await request("new-order", params);
|
|
158
255
|
this.domain = params.domain;
|
|
159
|
-
|
|
160
|
-
if (
|
|
256
|
+
var i = this.orders.indexOf(order);
|
|
257
|
+
if (i >= 0) this.orders.splice(i, 1);
|
|
258
|
+
this.orders = [order].concat(this.orders);
|
|
161
259
|
return order;
|
|
162
260
|
}
|
|
163
261
|
parseOrder(o) {
|
|
164
262
|
if (typeof o !== 'string') return o;
|
|
165
263
|
var order = data.getUrlParamsForApi(orderApi, o);
|
|
264
|
+
order.url = o;
|
|
166
265
|
order.name = order.oid;
|
|
167
266
|
return order;
|
|
168
267
|
}
|
|
169
268
|
async getOrder(o) {
|
|
170
|
-
var r = await data.
|
|
269
|
+
var r = await data.fromURL(o.url);
|
|
171
270
|
if (r.expires) r.expires = new Date(r.expires);
|
|
172
271
|
return r;
|
|
173
272
|
}
|
|
174
273
|
async thumbprint() {
|
|
175
274
|
var jwk = await subtle.exportKey('jwk', publicKey);
|
|
176
275
|
jwk = `{"e":"${jwk.e}","kty":"${jwk.kty}","n":"${jwk.n}"}`;
|
|
177
|
-
console.log(JSON.parse(jwk))
|
|
178
276
|
var thumb = await subtle.digest("SHA-256", new Uint8Array(encodeUTF8(jwk)));
|
|
179
277
|
thumb = toBase64(new Uint8Array(thumb), true);
|
|
180
278
|
return thumb;
|
|
181
279
|
}
|
|
280
|
+
async createKeyPair() {
|
|
281
|
+
return makeKeyPair(2048);
|
|
282
|
+
}
|
|
283
|
+
async createCSR(domains, private_key) {
|
|
284
|
+
var csr = await createCSR(domains, private_key);
|
|
285
|
+
return toBase64(csr, true);
|
|
286
|
+
}
|
|
182
287
|
async audit(url) {
|
|
183
288
|
return data.fromURL(url);
|
|
184
289
|
}
|
package/coms/pivot/pedit.js
CHANGED
|
@@ -2,21 +2,29 @@ function send(type, key, value, origin) {
|
|
|
2
2
|
return data.from(origin ? "edit" : "add", {
|
|
3
3
|
type,
|
|
4
4
|
key: encode62.timeencode(key),
|
|
5
|
-
value: encode62.timeencode(JSON.stringify(value)),
|
|
6
|
-
}).loading_promise;
|
|
5
|
+
value: isHandled(value) ? encode62.timeencode(JSON.stringify(value)) : '',
|
|
6
|
+
}, e => e ? JSAM.parse(encode62.timedecode(e)) : '').loading_promise;
|
|
7
7
|
}
|
|
8
8
|
function pedit(title, type, params, idkey = params.fields[0].key) {
|
|
9
|
+
var pdata = params.data;
|
|
9
10
|
return frame$edit(title, {
|
|
10
11
|
submit(a, fields) {
|
|
11
12
|
a = submit(fields, a);
|
|
12
|
-
return send(type, a[idkey], a,
|
|
13
|
+
return send(type, a[idkey], a, pdata);
|
|
13
14
|
},
|
|
14
|
-
|
|
15
15
|
}, params);
|
|
16
16
|
}
|
|
17
17
|
pedit.create = function (type, key, value) {
|
|
18
18
|
return send(type, key, value, false);
|
|
19
19
|
}
|
|
20
|
-
pedit.
|
|
20
|
+
var query = pedit.query = function (type, key) {
|
|
21
|
+
return send(type, key, null, true);
|
|
22
|
+
}
|
|
23
|
+
var update = pedit.update = function (type, key, value) {
|
|
21
24
|
return send(type, key, value, true);
|
|
25
|
+
}
|
|
26
|
+
pedit.merge = async function (type, key, params) {
|
|
27
|
+
var data = await query(type, key);
|
|
28
|
+
extendIfNeeded(params, data);
|
|
29
|
+
return update(type, key, params);
|
|
22
30
|
}
|
package/coms/pivot/plist.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
function load(type) {
|
|
2
|
+
return data.from("list", { type }, a => JSAM.parse(encode62.timedecode(a || '')));
|
|
3
|
+
}
|
|
4
|
+
function remove(type, key) {
|
|
5
|
+
return data.from("edit", { type, key: encode62.timeencode(key), value: encode62.timeencode("") }).loading_promise;
|
|
6
|
+
}
|
|
7
|
+
function plist() {
|
|
3
8
|
var title, type, fields, edit_ref, options, idkey, buttons;
|
|
4
9
|
var parse = function (a) {
|
|
5
10
|
switch (typeof a) {
|
|
@@ -33,10 +38,10 @@ function main() {
|
|
|
33
38
|
if (!idkey) idkey = fields[0].key;
|
|
34
39
|
return frame$list(title, {
|
|
35
40
|
load() {
|
|
36
|
-
return
|
|
41
|
+
return load(type);
|
|
37
42
|
},
|
|
38
43
|
remove(o) {
|
|
39
|
-
return
|
|
44
|
+
return remove(type, o[idkey]);
|
|
40
45
|
},
|
|
41
46
|
fields,
|
|
42
47
|
buttons,
|
|
@@ -48,4 +53,6 @@ function main() {
|
|
|
48
53
|
move.setPosition(p, [.5, .5]);
|
|
49
54
|
return p;
|
|
50
55
|
});
|
|
51
|
-
}
|
|
56
|
+
}
|
|
57
|
+
plist.load = load;
|
|
58
|
+
plist.remove = remove;
|
package/coms/zimoli/button.less
CHANGED
package/coms/zimoli/container.js
CHANGED
|
@@ -15,14 +15,21 @@ var change = lazy(async function (src) {
|
|
|
15
15
|
}
|
|
16
16
|
zimoli.global(src, this);
|
|
17
17
|
}
|
|
18
|
-
else if (isString(src) || +src < 0)
|
|
18
|
+
else if (isString(src) || +src < 0) {
|
|
19
|
+
watch(this, 'params', onparams);
|
|
20
|
+
onparams.call(this, this.params);
|
|
21
|
+
}
|
|
19
22
|
});
|
|
20
23
|
var gosrc = function (src) {
|
|
24
|
+
if (!isHandled(this.$src) && !isHandled(src)) return;
|
|
21
25
|
if (src !== this.$src) {
|
|
22
26
|
this.$src = src;
|
|
23
27
|
change.call(this, src);
|
|
24
28
|
}
|
|
25
29
|
};
|
|
30
|
+
var onparams = lazy(function (params) {
|
|
31
|
+
zimoli.go(this.$src, params, this);
|
|
32
|
+
});
|
|
26
33
|
function container(element) {
|
|
27
34
|
var comment = document.createComment('container');
|
|
28
35
|
comment.$struct = element.$struct;
|
package/coms/zimoli/data.js
CHANGED
|
@@ -176,15 +176,15 @@ function getParamsFromUrl(url, s = "?") {
|
|
|
176
176
|
function getUrlParamsForApi(api, url) {
|
|
177
177
|
var r = /([\s\S]*?)/.source;
|
|
178
178
|
var cap = [];
|
|
179
|
-
var
|
|
179
|
+
var reg = api.url.replace(/[\?\#][\s\S]*$/, '')
|
|
180
180
|
.replace(/[\.\*\+\-\[\]\{\}\(\)\\\/\!<\>\^]/g, '\\$&')
|
|
181
181
|
.replace(/\:\w+/g, function (a) {
|
|
182
182
|
cap.push(a.slice(1));
|
|
183
183
|
return r;
|
|
184
184
|
});
|
|
185
|
-
if (/\/$/.test(
|
|
185
|
+
if (/\/$/.test(reg)) reg += "?";
|
|
186
186
|
var params = {};
|
|
187
|
-
url = url.replace(/[\?#]*$/g, function (match) {
|
|
187
|
+
url = url.replace(/[\?#][\s\S]*$/g, function (match) {
|
|
188
188
|
match.split(/[&#\?]+/).forEach(function (s) {
|
|
189
189
|
if (!s) return;
|
|
190
190
|
var [k, v] = s.split("=");
|
|
@@ -192,8 +192,9 @@ function getUrlParamsForApi(api, url) {
|
|
|
192
192
|
});
|
|
193
193
|
return '';
|
|
194
194
|
});
|
|
195
|
-
if (api.base) url = url.slice(api.base.length);
|
|
196
|
-
|
|
195
|
+
if (api.base === url.slice(0, api.base.length)) url = url.slice(api.base.length), reg = new RegExp(`^${reg}$`);
|
|
196
|
+
else reg = new RegExp(reg + '$');
|
|
197
|
+
url.replace(reg, function () {
|
|
197
198
|
var args = arguments;
|
|
198
199
|
cap.forEach(function (a, cx) {
|
|
199
200
|
params[a] = args[cx + 1];
|
|
@@ -302,7 +303,7 @@ function parseConfig(api) {
|
|
|
302
303
|
});
|
|
303
304
|
url.replace(/[\#][\s\S]*$/, '').replace(/([\:\\]\:|\:\w+)/g, function (p) {
|
|
304
305
|
p = p.slice(1);
|
|
305
|
-
if (
|
|
306
|
+
if (p !== ':' && required.indexOf(p) < 0) {
|
|
306
307
|
required.push(p);
|
|
307
308
|
}
|
|
308
309
|
});
|
|
@@ -534,7 +535,7 @@ var privates = {
|
|
|
534
535
|
params = this.repare(api, params);
|
|
535
536
|
return this.loadIgnoreConfig(api.method, url, params, api);
|
|
536
537
|
}
|
|
537
|
-
return Promise.
|
|
538
|
+
return Promise.reject(ABORTED);
|
|
538
539
|
},
|
|
539
540
|
repare(api, params) {
|
|
540
541
|
var { required, autotrim, prepared } = api;
|
|
@@ -601,7 +602,7 @@ var privates = {
|
|
|
601
602
|
var temp = JSON.stringify(params);
|
|
602
603
|
var currentTime = +new Date;
|
|
603
604
|
var loading = promise && promise.loading;
|
|
604
|
-
if (!promise || currentTime - promise.time > 60 || temp !== promise.params || promise.search !== search) {
|
|
605
|
+
if (!promise || currentTime - promise.time > 60 || temp !== promise.params || promise.search !== search || promise.uri !== uri) {
|
|
605
606
|
var promise = new Promise(function (ok, oh) {
|
|
606
607
|
if (headers) {
|
|
607
608
|
headers = seekFromSource(headers, api.base);
|
|
@@ -617,6 +618,7 @@ var privates = {
|
|
|
617
618
|
}
|
|
618
619
|
});
|
|
619
620
|
});
|
|
621
|
+
promise.uri = uri;
|
|
620
622
|
promise.loading = loading;
|
|
621
623
|
promise.search = search;
|
|
622
624
|
promise.params = temp;
|
|
@@ -625,7 +627,11 @@ var privates = {
|
|
|
625
627
|
}
|
|
626
628
|
var p = promise.then(function (response) {
|
|
627
629
|
if (/\*$/.test(coinmethod)) return response;
|
|
628
|
-
var
|
|
630
|
+
var type = loading.getResponseHeader?.("content-type");
|
|
631
|
+
var data = response;
|
|
632
|
+
if (/text\/plain|json|[xyt]ml/i.test(type)) {
|
|
633
|
+
data = parseData(data);
|
|
634
|
+
}
|
|
629
635
|
var checked = error_check(data);
|
|
630
636
|
var apiMap = api && api.root;
|
|
631
637
|
var trans = api ? api.transpile : getTranspile(url);
|
|
@@ -678,6 +684,7 @@ var loadInstance = function (storage, id) {
|
|
|
678
684
|
};
|
|
679
685
|
|
|
680
686
|
function responseCrash(e, data) {
|
|
687
|
+
if (e === ABORTED || e === OUTDATE) return;
|
|
681
688
|
data.is_errored = true;
|
|
682
689
|
data.is_loading = false;
|
|
683
690
|
data.error_message = getErrorMessage(e);
|
|
@@ -734,8 +741,9 @@ var unbindInstance = function (instanceId, callback) {
|
|
|
734
741
|
};
|
|
735
742
|
var OUTDATE = new Error(i18n`请求被覆盖`);
|
|
736
743
|
var ABORTED = new Error(i18n`请求已取消`);
|
|
737
|
-
var
|
|
738
|
-
|
|
744
|
+
var oncatch = function (e) {
|
|
745
|
+
if (e === OUTDATE || e === ABORTED) return;
|
|
746
|
+
throw e;
|
|
739
747
|
};
|
|
740
748
|
var data = {
|
|
741
749
|
prepareURL,
|
|
@@ -853,86 +861,57 @@ var data = {
|
|
|
853
861
|
});
|
|
854
862
|
},
|
|
855
863
|
fromApi(api, params, parse) {
|
|
856
|
-
var id = parse instanceof Function ? getInstanceId() : 0;
|
|
857
864
|
var p = privates.fromApi(api, params);
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
response.loading = null;
|
|
866
|
-
if (id) {
|
|
867
|
-
data = parse(data);
|
|
868
|
-
this.setInstance(id, data, false);
|
|
869
|
-
this.removeInstance(id);
|
|
870
|
-
} else {
|
|
871
|
-
this.setInstance(url, data);
|
|
872
|
-
}
|
|
873
|
-
this.responseLoaded(response);
|
|
874
|
-
return data;
|
|
875
|
-
});
|
|
876
|
-
p.catch((e) => {
|
|
877
|
-
this.responseCrash(e, response);
|
|
878
|
-
});
|
|
879
|
-
return response;
|
|
880
|
-
|
|
865
|
+
p.id = api.id;
|
|
866
|
+
return this.createResponse(p, parse);
|
|
867
|
+
},
|
|
868
|
+
postURL(url, data, parse) {
|
|
869
|
+
var p = privates.loadIgnoreConfig("post", url, data);
|
|
870
|
+
p.id = "post " + url;
|
|
871
|
+
return this.createResponse(p, parse);
|
|
881
872
|
},
|
|
882
873
|
fromURL(url, parse) {
|
|
883
|
-
var id = parse instanceof Function ? getInstanceId() : 0;
|
|
884
874
|
var p = privates.loadIgnoreConfig('get', url);
|
|
875
|
+
p.id = "get " + url;
|
|
876
|
+
return this.createResponse(p, parse);
|
|
877
|
+
},
|
|
878
|
+
createResponse(p, parse) {
|
|
879
|
+
var id = parse instanceof Function ? getInstanceId() : 0;
|
|
885
880
|
if (id) this.removeInstance(id);
|
|
886
|
-
var
|
|
881
|
+
var pid = p.id;
|
|
882
|
+
var response = this.getInstance(id || pid);
|
|
887
883
|
if (!isObject(response)) response = new LoadingArray;
|
|
888
884
|
this.responseLoading(response);
|
|
889
885
|
response.loading = p.loading;
|
|
890
|
-
|
|
886
|
+
response.loading_promise = p;
|
|
887
|
+
p = p.then((data) => {
|
|
891
888
|
response.loading = null;
|
|
892
889
|
if (id) {
|
|
893
890
|
data = parse(data);
|
|
894
891
|
this.setInstance(id, data, false);
|
|
895
892
|
this.removeInstance(id);
|
|
896
893
|
} else {
|
|
897
|
-
this.setInstance(
|
|
894
|
+
this.setInstance(pid, data);
|
|
898
895
|
}
|
|
899
896
|
this.responseLoaded(response);
|
|
900
897
|
return data;
|
|
901
|
-
})
|
|
902
|
-
p.catch((e) => {
|
|
898
|
+
}, (e) => {
|
|
903
899
|
this.responseCrash(e, response);
|
|
904
|
-
})
|
|
905
|
-
|
|
900
|
+
})
|
|
901
|
+
if (parse) response.loading_promise = p;
|
|
906
902
|
return response;
|
|
907
903
|
},
|
|
908
904
|
asyncInstance(sid, params, parse) {
|
|
909
905
|
// 不同参数的请求互不影响
|
|
910
906
|
if (typeof sid !== "string") throw new Error(i18n`serviceId 只能是字符串`);
|
|
911
|
-
var
|
|
912
|
-
if (id) this.removeInstance(id);
|
|
913
|
-
var response = this.getInstance(id || sid);
|
|
914
|
-
if (!isObject(response)) response = new LoadingArray;
|
|
915
|
-
this.responseLoading(response);
|
|
916
|
-
var p = response.loading_promise = privates.getApi(sid).then((api) => {
|
|
907
|
+
var p = privates.getApi(sid).then((api) => {
|
|
917
908
|
params = privates.pack(sid, params);
|
|
918
909
|
var p = privates.fromApi(api, params);
|
|
919
|
-
response.loading = p.loading;
|
|
910
|
+
p.loading = response.loading = p.loading;
|
|
920
911
|
return p;
|
|
921
|
-
})
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
data = parse instanceof Function ? parse(data) : data;
|
|
925
|
-
this.setInstance(id, data, false);
|
|
926
|
-
this.removeInstance(id);
|
|
927
|
-
} else {
|
|
928
|
-
this.setInstance(sid, data);
|
|
929
|
-
}
|
|
930
|
-
this.responseLoaded(response);
|
|
931
|
-
return data;
|
|
932
|
-
});
|
|
933
|
-
p.catch((e) => {
|
|
934
|
-
this.responseCrash(e, response);
|
|
935
|
-
});
|
|
912
|
+
}, oncatch);
|
|
913
|
+
p.id = sid;
|
|
914
|
+
var response = this.createResponse(p, parse);
|
|
936
915
|
return response;
|
|
937
916
|
},
|
|
938
917
|
|
|
@@ -957,77 +936,35 @@ var data = {
|
|
|
957
936
|
});
|
|
958
937
|
var id = "." + sid;
|
|
959
938
|
var instance = this.getInstance(id);
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
var params = promise1.params;
|
|
965
|
-
if (shallowEqual(params1, params)) {
|
|
966
|
-
return instance;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
this.responseLoading(instance);
|
|
970
|
-
promise1 = instance.loading_promise = new Promise(function (ok) {
|
|
971
|
-
if (!instance.loading) {
|
|
972
|
-
instance.loading = false;
|
|
973
|
-
}
|
|
974
|
-
setTimeout(ok, timeout);
|
|
939
|
+
var loading_promise = instance && instance.loading_promise;
|
|
940
|
+
var p = Promise.resolve().then(function () {
|
|
941
|
+
if (loading_promise) return wait(timeout);
|
|
942
|
+
return wait(60);
|
|
975
943
|
}).then(function () {
|
|
976
|
-
if (
|
|
944
|
+
if (p !== instance.loading_promise) throw OUTDATE;
|
|
977
945
|
return privates.getApi(sid);
|
|
978
946
|
}).then((api) => {
|
|
979
|
-
if (
|
|
947
|
+
if (p !== instance.loading_promise) throw OUTDATE;
|
|
948
|
+
if ("params" in instance && shallowEqual(instance.params, params1)) throw ABORTED;
|
|
949
|
+
instance.params = params1;
|
|
980
950
|
if (instance.loading) {
|
|
981
951
|
instance.loading.abort();
|
|
982
952
|
}
|
|
983
|
-
var
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
var base = api.base;
|
|
987
|
-
if (base) url = base + api.path;
|
|
988
|
-
var { method, uri, params, selector } = privates.prepare(api.method, url, params2);
|
|
989
|
-
var promise = new Promise(function (ok, oh) {
|
|
990
|
-
var headers = api.headers;
|
|
991
|
-
if (headers) {
|
|
992
|
-
headers = seekFromSource(headers, api.base);
|
|
993
|
-
}
|
|
994
|
-
instance.loading = cross(method, uri, headers).send(params).done(xhr => {
|
|
995
|
-
if (instance.loading !== xhr) return oh(ABORTED);
|
|
996
|
-
instance.loading = null;
|
|
997
|
-
ok(xhr.responseText || xhr.response);
|
|
998
|
-
}).error(xhr => {
|
|
999
|
-
if (instance.loading !== xhr) return oh(ABORTED);
|
|
1000
|
-
instance.loading = null;
|
|
1001
|
-
try {
|
|
1002
|
-
var e = getErrorMessage(parseData(xhr.response || xhr.responseText || xhr.statusText || xhr.status));
|
|
1003
|
-
oh({ status: xhr.status, error: e, api, params: params2, toString: getErrorMessage })
|
|
1004
|
-
} catch (error) {
|
|
1005
|
-
oh(error);
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
}).then(function (response) {
|
|
1009
|
-
return transpile(seekResponse(parseData(response), selector), api.transpile, api.root);
|
|
1010
|
-
});
|
|
1011
|
-
return promise;
|
|
953
|
+
var r = privates.fromApi(api, params1);
|
|
954
|
+
instance.loading = r.loading;
|
|
955
|
+
return r;
|
|
1012
956
|
}).then((data) => {
|
|
1013
|
-
if (instance.loading_promise !==
|
|
1014
|
-
if (
|
|
1015
|
-
data = parse instanceof Function ? parse(data) : data;
|
|
1016
|
-
this.setInstance(id, data, false);
|
|
1017
|
-
} else {
|
|
1018
|
-
this.setInstance(sid, data);
|
|
1019
|
-
}
|
|
1020
|
-
this.responseLoaded(instance);
|
|
957
|
+
if (instance.loading_promise !== p) throw ABORTED;
|
|
958
|
+
if (isFunction(parse)) data = parse(data);
|
|
1021
959
|
return data;
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
|
|
960
|
+
}, oncatch);
|
|
961
|
+
p.id = id;
|
|
962
|
+
var instance = this.createResponse(p);
|
|
963
|
+
p.catch(function () { }).then(() => {
|
|
964
|
+
return wait(timeout);
|
|
965
|
+
}).then(() => {
|
|
966
|
+
if (instance.loading_promise === p) delete instance.loading_promise;
|
|
1025
967
|
});
|
|
1026
|
-
promise1.params = params;
|
|
1027
|
-
promise1.catch((e) => {
|
|
1028
|
-
this.responseCrash(e, instance);
|
|
1029
|
-
});
|
|
1030
|
-
|
|
1031
968
|
return instance;
|
|
1032
969
|
},
|
|
1033
970
|
/**
|
package/coms/zimoli/list.js
CHANGED
|
@@ -463,9 +463,9 @@ function ylist(container, generator, $Y) {
|
|
|
463
463
|
* @param {Element|null} focused
|
|
464
464
|
* @param {boolean} animate
|
|
465
465
|
*/
|
|
466
|
-
list.setFocus = function (focused, animate) {
|
|
466
|
+
list.setFocus = function (focused, animate = true) {
|
|
467
467
|
if (isElement(focused) && (focused.hasAttribute("disabled") || focused.hasAttribute("line"))) return;
|
|
468
|
-
if (
|
|
468
|
+
if (focused === (focused | 0)) {
|
|
469
469
|
var index = focused;
|
|
470
470
|
focused = list.getIndexedElement(index);
|
|
471
471
|
if (!focused) {
|