efront 4.11.4 → 4.11.6

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.
@@ -1655,7 +1655,7 @@
1655
1655
  en: "The commands that can be used are:"
1656
1656
 
1657
1657
  - zh-CN: 如要显示更具体的信息,请使用:$1
1658
- en: "To show more messages, used"
1658
+ en: "To show more messages, use $1"
1659
1659
 
1660
1660
  - zh-CN: 是
1661
1661
  en: is
@@ -1,9 +1,5 @@
1
1
  plist.bind(null, '接口管理', "cert", refilm`
2
2
  *域名/hostname input/253
3
- 公钥/private gen/600 ${async function (data) {
4
- var [private_key, public_key] = await acme2.createKeyPair();
5
- data.private = private_key;
6
- data.public = public_key;
7
- }}
8
- -私钥/public text
9
- $证书/cert text`, '/cert/edit');
3
+ 公钥/private text
4
+ 私钥/public text
5
+ 证书/cert text`, '/cert/edit');
@@ -46,6 +46,11 @@
46
46
  border: none;
47
47
  }
48
48
 
49
+ [foot]>a.button {
50
+ float: left;
51
+ }
52
+
53
+
49
54
  loading {
50
55
  z-index: 3;
51
56
  }
@@ -64,6 +69,7 @@
64
69
  </div>
65
70
  <scrollbar y #bar></scrollbar>
66
71
  <div foot>
72
+ <a -repeat="(f,k) in actived.options" -click="f(actived)" -bind="k"></a>
67
73
  <span -bind="actived.message"></span>
68
74
  <button -repeat="(f,k) in actived.actions" -click="f(actived)"><span -bind="k"></span></button>
69
75
  </div>
@@ -166,6 +172,12 @@
166
172
  $账户/kid input
167
173
  *当前服务器的域名/domain/每行一个,不支持泛域名 text
168
174
  `,
175
+ options: {
176
+ async 从证书列表同步() {
177
+ var a = await plist.load('cert', 'hostname');
178
+ formdata.domain = a.map(a => a.hostname).join('\r\n');
179
+ }
180
+ },
169
181
  actions: {
170
182
  async 创建订单(actived) {
171
183
  var params = submit(actived.fields, formdata);
@@ -1,23 +1,30 @@
1
- plist.bind(null, '任务管理', "task", refilm`
1
+ model.setEditor('jscode', function (element) {
2
+ element = 茨菰$编辑框(null);
3
+ element.contentEditable = !element.readonly;
4
+ element.type = 'js';
5
+ return element;
6
+ });
7
+ model.setReader('jscode', "text");
8
+ return plist.bind(null, '任务管理', "task", refilm`
2
9
  *任务ID/key 100
3
10
  *任务名/name 100
4
11
  *是否启用/status radio 不启用,启用
5
- 任务代码/code text
12
+ 任务代码/code jscode
6
13
  / $ ${[
7
- {
8
- when(o) {
9
- return o.status === 1;
14
+ {
15
+ when(o) {
16
+ return o.status === 1;
17
+ },
18
+ name: "执行", do(o) {
19
+ popup("/task/invoke", o);
20
+ }
10
21
  },
11
- name: "执行", do(o) {
12
- popup("/task/invoke", o);
13
- }
14
- },
15
- {
16
- when(o) {
17
- return o.status === 1;
22
+ {
23
+ when(o) {
24
+ return o.status === 1;
25
+ },
26
+ name: "同步", do(o) {
27
+ popup("/task/rsync", o);
28
+ }
18
29
  },
19
- name: "同步", do(o) {
20
- popup("/task/rsync", o);
21
- }
22
- },
23
- ]}`, '/task/edit');
30
+ ]}`, '/task/edit');
@@ -96,9 +96,9 @@ var readFile = function (names, then) {
96
96
  }
97
97
  };
98
98
  if (!names.length) return then();
99
- names.forEach(function (name) {
99
+ for (var name of names) {
100
100
  readFile(name, callback);
101
- });
101
+ }
102
102
  return;
103
103
  }
104
104
  var name = names;
@@ -155,7 +155,8 @@ var readFile = function (names, then) {
155
155
  }
156
156
  if (loadingTree[key]) {
157
157
  loadingTree[key].error = e;
158
- loadingTree[key].forEach(a => a(e));
158
+ var loading = loadingTree[key];
159
+ for (var a of loading) a(e);
159
160
  }
160
161
  };
161
162
  var tryload = function () {
@@ -183,7 +184,7 @@ var killCircle = function () {
183
184
  if (!(loadedModules[k] instanceof Array)) continue;
184
185
  var args = loadedModules[k].args;
185
186
  if (!(args instanceof Array)) continue;
186
- args.forEach(arg => {
187
+ for (var arg of args) {
187
188
  if (!penddings[arg]) {
188
189
  penddings[arg] = [];
189
190
  }
@@ -191,7 +192,7 @@ var killCircle = function () {
191
192
  penddings[arg][k] = true;
192
193
  penddings[arg].push(key);
193
194
  }
194
- })
195
+ }
195
196
  circle.push(key);
196
197
  module_keys.push(k);
197
198
  }
@@ -212,10 +213,10 @@ var killCircle = function () {
212
213
  if (savedLength === circle.length) {
213
214
  break;
214
215
  }
215
- circle.forEach(function (c) {
216
+ for (var c of circle) {
216
217
  var args = penddings[c];
217
218
  penddings[c] = args.filter(a => !deleted[a]);
218
- });
219
+ }
219
220
  }
220
221
  if (circle.length > 0) {
221
222
  circle = circle.sort((a, b) => {
@@ -235,13 +236,11 @@ var killCircle = function () {
235
236
  ));
236
237
  } else {
237
238
  var tree = {};
238
- module_keys.forEach(function (k) {
239
+ for (var k of module_keys) {
239
240
  var loading = tree[k] = loadedModules[k];
240
241
  loadedModules[k] = loading.mod;
241
- });
242
- module_keys.forEach(function (k) {
243
- flushTree(tree, k);
244
- });
242
+ }
243
+ for (var k of module_keys) flushTree(tree, k);
245
244
  }
246
245
  };
247
246
  // -->
@@ -331,9 +330,9 @@ var loadModule = function (url, then, prebuilds = {}) {
331
330
  } else {
332
331
  loadedModules[key].args = mod.args;
333
332
  loadedModules[key].mod = mod;
334
- args.forEach(function (moduleName) {
333
+ for (var moduleName of args) {
335
334
  loadModule(moduleName, response, prebuilds);
336
- });
335
+ }
337
336
  }
338
337
  };
339
338
  readFile(url, saveModule);
@@ -132,7 +132,8 @@ var create = function (a, dst) {
132
132
  var arr = a.split(',');
133
133
  var rest = [];
134
134
  for (var cx = 0, dx = arr.length; cx < dx; cx++) {
135
- var [k, v] = arr[cx].split(':');
135
+ var s = arr[cx].split(":");
136
+ var k = s[0], v = s[1];
136
137
  if (v === undefined) {
137
138
  rest.push(k);
138
139
  } else {
@@ -21,10 +21,10 @@ var parseCookieFromText = function (cookie) {
21
21
  return [pair, info];
22
22
  };
23
23
 
24
- class Cookie {
25
- cookiesMap = {};
24
+ function Cookie() {
25
+ this.cookiesMap = {};
26
26
  }
27
- var CookieProto = Cookie.prototype;
27
+ var CookieProto = Cookie.prototype = new Cookie;
28
28
  CookieProto.addCookie = function addCookie(cookie_text, originDomain = "") {
29
29
  var { cookiesMap } = this;
30
30
  originDomain = getDomainPath(originDomain);
@@ -59,7 +59,7 @@ CookieProto.addCookie = function addCookie(cookie_text, originDomain = "") {
59
59
  }
60
60
  }
61
61
  }
62
- }
62
+ };
63
63
 
64
64
  CookieProto.getCookies = function getCookies(domainPath) {
65
65
  var { cookiesMap } = this;
@@ -91,7 +91,7 @@ CookieProto.getCookies = function getCookies(domainPath) {
91
91
  splited[0] = domain;
92
92
  } while (domain.length);
93
93
  return serialize(cookieObject, ";");
94
- }
94
+ };
95
95
 
96
96
  CookieProto.delCookies = function delCookies(domainPath) {
97
97
  var { cookiesMap } = this;
@@ -99,7 +99,7 @@ CookieProto.delCookies = function delCookies(domainPath) {
99
99
  var splited = domainPath.split("/");
100
100
  var domain = splited[0];
101
101
  delete cookiesMap[domain];
102
- }
102
+ };
103
103
  function getDomainPath(url) {
104
104
  var { host, pathname } = parseURL(url);
105
105
  if (pathname) return host + pathname;
@@ -115,10 +115,10 @@ CookieProto.linkCookie = function linkCookie(from, to) {
115
115
  }
116
116
  cookiesMap[to] = cookiesMap[from] = extend({}, cookiesMap[to], cookiesMap[from]);
117
117
  return to;
118
- }
118
+ };
119
119
  CookieProto.copyCookie = function copyCookie(from, to) {
120
120
  var { cookiesMap } = this;
121
- from = getDomainPath(from).replace(/\/$,'/, '');
121
+ from = getDomainPath(from).replace(/\/$/, '');
122
122
  to = getDomainPath(to).replace(/\/$/, '');
123
123
  if (from in cookiesMap) {
124
124
  cookiesMap[to] = JSON.parse(JSON.stringify(cookiesMap[from]));
@@ -126,7 +126,7 @@ CookieProto.copyCookie = function copyCookie(from, to) {
126
126
  else {
127
127
  delete cookiesMap[to];
128
128
  }
129
- }
129
+ };
130
130
  var defaultCookie = new Cookie;
131
131
  defaultCookie.new = () => new Cookie;
132
132
  return defaultCookie;
@@ -443,7 +443,7 @@ function createApiMap(data) {
443
443
  var items1 = data;
444
444
  for (var key in items1) {
445
445
  var keeys = key.split(/\s+/);
446
- var [base] = keeys.filter(a => reg.test(a));
446
+ var base = keeys.filter(a => reg.test(a))[0];
447
447
  if (!base) {
448
448
  var headersIndex = 0;
449
449
  } else {
@@ -14,9 +14,11 @@ var getLanguageIndexFromName = function (language) {
14
14
  if (isFinite(language)) return language;
15
15
  if (language in languageMap) return languageMap[language];
16
16
  language = String(language).toLowerCase();
17
- for (var l of language.split(",").slice(0, 12)) {
17
+ var ls = language.split(",").slice(0, 12);
18
+ for (var l of ls) {
18
19
  for (var k in languageMap) {
19
- for (var kk of k.toLowerCase().split("-")) {
20
+ var ks = k.toLowerCase().split("-");
21
+ for (var kk of ks) {
20
22
  if (l.indexOf(kk) >= 0) return languageMap[k];
21
23
  }
22
24
  }
@@ -1,4 +1,7 @@
1
- var hasOwnProperty = Object.prototype.hasOwnProperty;
1
+ var hasOwnProperty = {}.__proto__ === Object ? function (k) {
2
+ var proto = this.__proto__;
3
+ return k in this && (!proto || !(k in proto));
4
+ } : Object.prototype.hasOwnProperty;
2
5
  var setPrototypeOf = Object.setPrototypeOf;
3
6
  a: if (!setPrototypeOf) {
4
7
  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
@@ -133,4 +133,6 @@ testStar(`var a=class {a=1\r\nasync * a(){
133
133
  for(var n of names) {
134
134
  yield n;
135
135
  }
136
- }}`, {});
136
+ }}`, {});
137
+
138
+ assert(scanner2(`#`)[0].type, common.STAMP)
@@ -94,6 +94,7 @@ class Program {
94
94
  scriptTags = [];
95
95
  ignoreTags = ["STYLE", "SCRIPT"];
96
96
  comments = [
97
+ ["#!", /(?=[\r\n\u2028\u2029])/],
97
98
  ["//", /(?=[\r\n\u2028\u2029])/],
98
99
  ["/*", "*/"],
99
100
  [/<!--/, /--!?>/],
@@ -808,7 +809,7 @@ class Program {
808
809
  save(VALUE);
809
810
  continue;
810
811
  }
811
- if (express_reg.test(m)) {
812
+ if (!stamp_reg.test(m) && express_reg.test(m)) {
812
813
  if (last && last.type === STRAP && funcstrap_reg.test(last.text));
813
814
  else queue.inExpress = true;
814
815
  save(EXPRESS);
@@ -942,7 +943,7 @@ class Program {
942
943
  this.comment_entry = this.createRegExp(this.comments.map(m => m[0]));
943
944
  var stamps = this.stamps.join("");
944
945
  stamps = this.compile(stamps);
945
- this.stamp_reg = new RegExp(`^[${stamps}]+$`);
946
+ var stamp_reg = new RegExp(`^[${stamps}]+$`);
946
947
  var tokens = {};
947
948
  var quote_map = {};
948
949
  this.quote_map = quote_map;
@@ -1013,7 +1014,7 @@ class Program {
1013
1014
  this.space_reg = new RegExp(`^[${spaces}]+$`, flagUnicode);
1014
1015
  this.space_exp = new RegExp(`[${spaces}]+`, flagUnicode);
1015
1016
  var quotes_entries = this.createRegExp(this.comments.concat(this.quotes).map(q => q[0]), true).source;
1016
- var powers = Object.keys(this.powermap).filter(k => k.length > 1 && this.stamp_reg.test(k));
1017
+ var powers = Object.keys(this.powermap).filter(k => k.length > 1 && stamp_reg.test(k));
1017
1018
  var powers_entries = this.createRegExp(this.tags.map(t => t[0]).concat(powers), true).source;
1018
1019
  var entries_reg = new RegExp(`^(${powers_entries}|${quotes_entries}|${scopes})$`, this.nocase ? 'iu' : '');
1019
1020
  stamps = this.compile(this.stamps.filter(s => !entries_reg.test(s)).join(''));
@@ -1021,6 +1022,10 @@ class Program {
1021
1022
  var numbers = number_reg.source.replace(/^\^|\$$/g, "");
1022
1023
  this.digit_reg = new RegExp(/^[+\-]?/.source + numbers, number_reg.flags);
1023
1024
  this.entry_reg = new RegExp([`[${spaces}]+|${quotes_entries}|[${scopes}]|${numbers}[^${tokens}]*|${express}|${powers_entries}|[${stamps}]`], "gi" + flagUnicode);
1025
+ var stamps = this.stamps.slice();
1026
+ for (var k in this.powermap) if (k.length === 1 && stamps.indexOf(k) < 0) stamps.push(k);
1027
+ stamps.push.apply(stamps, powers);
1028
+ this.stamp_reg = new RegExp(`^(${stamps.map(this.compile).join('|')})$`);
1024
1029
  }
1025
1030
  }
1026
1031
  module.exports = Program;
@@ -8,7 +8,7 @@ var powermap = {
8
8
  '>>,>>>,<<'/* 7 */, '+,-'/* 8 */, '*,/,%'/* 9 */, '**'/* 10 */,
9
9
  '++,--'/* 11 */,
10
10
  "typeof,await,yield,new,delete,void,..."/*12*/,
11
- '!,~'/* 13 */,
11
+ '!,~,#'/* 13 */,
12
12
  "::,?.,->,."/*14*/,
13
13
  ].forEach((pp, i) => {
14
14
  pp.split(",").forEach(p => {
@@ -1,3 +1,25 @@
1
- &{
1
+ & {
2
2
  position: absolute;
3
+
4
+ .model {
5
+ font-family: 仿宋, 宋体, Consolas, "Courier New", monospace;
6
+
7
+ &[type=gen],
8
+ &[type=text] {
9
+ display: block;
10
+ font-size: 12px;
11
+ line-height: 12px;
12
+ }
13
+
14
+ textarea {
15
+ font-family: Consolas, 仿宋, sans-serif;
16
+ }
17
+ }
18
+
19
+ white-space: pre-wrap;
20
+
21
+ [body],
22
+ .body {
23
+ font-family: 宋体;
24
+ }
3
25
  }
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
2
3
  var _create = function (commFactory, className, _invoke) {
3
4
  if (!className) return commFactory;
4
5
  if (commFactory instanceof Promise) {
@@ -23,7 +24,7 @@ var _create = function (commFactory, className, _invoke) {
23
24
  if (release) release = _invoke(release, className, _invoke);
24
25
  return release;
25
26
  };
26
- if ({}.hasOwnProperty.call(commFactory, 'toString')) {
27
+ if (hasOwnProperty.call(commFactory, 'toString')) {
27
28
  result.toString = function () {
28
29
  return _invoke(commFactory.toString(), className, _invoke);
29
30
  };
@@ -1,21 +1,63 @@
1
- function main() {
2
- var elem = optionbar.apply(null, arguments);
3
- var scope = {};
4
- if (!elem.childNodes.length) care(elem, function (p) {
5
- var [f, data] = p;
6
- elem.innerHTML = field;
7
- render(elem, scope = {
8
- model,
9
- data,
10
- error: null,
11
- field: f,
12
- container,
13
- readonly: !!this.readonly
14
- });
15
- elem.oldValue = data[f.key];
16
- elem.setAttribute("field", f.key);
17
- }, false);
1
+ var reshape = function () {
2
+ var [head, body, foot] = getTypedChildren(this, ['head', 'body', 'foot']);
3
+ var isInlineBlock = body && /^inline/i.test(getComputedStyle(body).display);
4
+ if (head && body) {
5
+ var left = head.offsetWidth + 1;
6
+ if (isInlineBlock && left < body.offsetWidth >> 2) {
7
+ css(head, {
8
+ marginRight: fromOffset(-left),
9
+ marginBottom: ''
10
+ });
11
+ css(body, {
12
+ paddingLeft: left,
13
+ paddingTop: ""
14
+ });
15
+ }
16
+ else {
17
+ var top = head.offsetHeight + 1;
18
+ css(head, {
19
+ marginRight: '',
20
+ marginBottom: fromOffset(-top),
21
+ });
22
+ css(body, {
23
+ paddingLeft: '',
24
+ paddingTop: top
25
+ })
26
+ }
27
+ }
28
+ if (!body) body = head;
29
+ if (foot && body) {
30
+ var right = foot.offsetWidth + 1;
31
+ if (isInlineBlock && right < body.offsetWidth >> 2) {
32
+ css(foot, {
33
+ marginTop: '',
34
+ marginLeft: fromOffset(-right)
35
+ });
36
+ css(body, {
37
+ paddingBottom: '',
38
+ paddingRight: fromOffset(right),
39
+ })
40
+ }
41
+ else {
42
+ var bottom = foot.offsetHeight + 1;
43
+ css(foot, {
44
+ marginTop: fromOffset(-bottom),
45
+ marginLeft: '',
46
+ });
47
+ css(body, {
48
+ paddingRight: '',
49
+ paddingBottom: fromOffset(bottom)
50
+ });
51
+ }
52
+ }
53
+ };
54
+
55
+ function main(elem) {
56
+ if (!isElement(elem)) elem = document.createElement('field');
57
+ elem.reshape = reshape;
58
+ resizingList.set(elem, () => elem.reshape());
18
59
  elem.setAttribute("field", '');
60
+ var scope = {};
19
61
  elem.$renders = [function () {
20
62
  if (!(this.src instanceof Array)) return;
21
63
  var [f, data] = this.src;
@@ -48,5 +90,28 @@ function main() {
48
90
  this.oldValue = data[f.key];
49
91
  }]
50
92
  elem.removeAttribute("tabindex");
93
+
94
+ if (!elem.childNodes.length) care(elem, function (p) {
95
+ var [f, data] = p;
96
+ elem.innerHTML = field;
97
+ render(elem, scope = {
98
+ model,
99
+ data,
100
+ error: null,
101
+ field: f,
102
+ container,
103
+ readonly: !!this.readonly
104
+ });
105
+ elem.oldValue = data[f.key];
106
+ elem.setAttribute("field", f.key);
107
+ elem.reshape();
108
+ }, false);
109
+ else {
110
+ var [head, body, foot] = getTypedChildren(elem, ["head", 'body', 'foot']);
111
+ if (head) addClass(head, "head");
112
+ if (body) addClass(body, "body");
113
+ if (foot) addClass(foot, "foot");
114
+ elem.$renders.push(reshape);
115
+ }
51
116
  return elem;
52
117
  }
@@ -1,44 +1,61 @@
1
1
  & {
2
2
  height: auto;
3
3
  box-shadow: none !important;
4
+ display: block;
5
+ line-height: 22px;
6
+ border-bottom: 1px;
7
+ }
4
8
 
5
- >model:first-child {
6
- padding: 6px 10px;
7
- display: block;
8
- }
9
-
10
- model {
11
- display: inline;
12
- }
9
+ >.head,
10
+ >.foot {
11
+ padding: 10px 16px;
12
+ vertical-align: top;
13
+ display: inline-block;
14
+ position: absolute;
15
+ }
13
16
 
14
- >.head {
15
- vertical-align: top;
17
+ >model:first-child {
18
+ padding: 6px 10px;
19
+ display: block;
20
+ }
16
21
 
17
- .image {
18
- margin: 10px 0;
19
- }
20
- }
22
+ model {
23
+ display: inline;
24
+ }
21
25
 
22
- >.body {
23
- .image {
24
- margin: 10px 0;
25
- }
26
+ >.head {
26
27
 
27
- text-align: left;
28
+ .image {
29
+ margin: 10px 0;
28
30
  }
31
+ }
29
32
 
30
- >.track {
31
- display: none;
32
- box-shadow: none;
33
+ >.body {
34
+ .image {
35
+ margin: 10px 0;
33
36
  }
34
37
 
35
- >.foot {
36
- span {
37
- vertical-align: middle;
38
- }
38
+ vertical-align: top;
39
+ padding: 10px 20px;
40
+ height: 100%;
41
+ border-bottom: 1px solid #0001;
42
+ display: inline-block;
43
+ width: 100%;
44
+ text-align: left;
45
+ }
46
+
47
+ >.track {
48
+ display: none;
49
+ box-shadow: none;
50
+ }
51
+
52
+ >.foot {
53
+ span {
54
+ vertical-align: middle;
39
55
  }
40
56
  }
41
57
 
58
+
42
59
  .input {
43
60
  width: 100%;
44
61
  }
@@ -18,6 +18,6 @@ if (preventCache && navigator) {
18
18
  } else {
19
19
  search = "=" + mark_time.toString(36);
20
20
  }
21
- if (!/Safari|Firefox|Sciter|Baiduspider|PetalBot|Googlebot|Odin/.test(navigator.userAgent)) location.replace(location.pathname + "?" + search);
21
+ if (navigator.userAgent && !/Safari|Firefox|Sciter|Baiduspider|PetalBot|Googlebot|Odin/.test(navigator.userAgent)) location.replace(location.pathname + "?" + search);
22
22
  }
23
23
  }
@@ -0,0 +1,26 @@
1
+ function hasType(target, type) {
2
+ // 记得小时候,不论是苍蝇还是蚊子,飞起来都是有声音的。最近看到的一种像蚊子一样小的飞虫,喜欢像苍蝇一样趴在食物上,飞起来却听不到声音。
3
+ // 是我的听力下降了?还是外界太过嘈杂?还是飞虫拍打翅膀的频率超出了我的听觉范围?还是飞行可以不产生声音?
4
+ return target.hasAttribute(type) || hasClass(target, type);
5
+ }
6
+
7
+ return function (element, types) {
8
+ var marked = 0;
9
+ for (var k in types) {
10
+ for (var c of element.children) {
11
+ if (hasType(c, types[k])) {
12
+ types[k] = c;
13
+ marked++;
14
+ }
15
+ }
16
+ }
17
+ if (!marked && isArray(types)) {
18
+ var children = element.children;
19
+ if (children.length) {
20
+ for (var cx = 0, dx = types.length; cx < dx; cx++) {
21
+ types[cx] = children[cx];
22
+ }
23
+ }
24
+ }
25
+ return types;
26
+ }
@@ -409,6 +409,14 @@ function main(elem) {
409
409
  }
410
410
  markEditer(constructors);
411
411
  markReader(readonly_types);
412
+ var pick = function (constructors, f) {
413
+ var path = [];
414
+ while (typeof f === 'string' && path.indexOf(f) < 0) {
415
+ path.push(f);
416
+ f = constructors[f];
417
+ }
418
+ return f;
419
+ };
412
420
  extend(main, {
413
421
  setEditors(map) {
414
422
  extend(constructors, map);
@@ -423,12 +431,14 @@ extend(main, {
423
431
  this.setReadors(map);
424
432
  },
425
433
  setEditor(key, func) {
434
+ if (typeof func === 'function') func.isediter = true;
435
+ else func = pick(constructors, func);
426
436
  constructors[key] = func;
427
- func.isediter = true;
428
437
  },
429
438
  setReador(key, func) {
439
+ if (typeof func === 'function') func.isreader = true;
440
+ else func = pick(readonly_types, func);
430
441
  readonly_types[key] = func;
431
- func.isreader = true;
432
442
  },
433
443
  setModel(key, func) {
434
444
  this.setEditor(key, func);