efront 3.20.17 → 3.21.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.
@@ -1,20 +1,43 @@
1
1
  data.loadConfig("api.yml");
2
2
  user.loginPath = '/auth/login';
3
+ var login_queue = [], reject_queue = [];
3
4
  cross.addReform(async function ({ status, url, headers }, reform, reject) {
4
5
  if (status === 401) {
6
+ var xhr = this;
7
+ var abort = xhr.abort;
8
+ xhr.abort = function () {
9
+ removeFromList(login_queue, reform);
10
+ removeFromList(reject_queue, reject);
11
+ if (!login_queue.length) remove(reject_queue.splice(0, 1)[0]);
12
+ abort.call(this);
13
+ };
14
+
15
+ if (login_queue.length) {
16
+ login_queue.push(reform);
17
+ reject_queue.push(reject);
18
+ return false;
19
+ }
5
20
  var base = data.getInstance("base").base;
6
21
  var { protocol, host } = parseURL(url);
7
22
  var base1 = protocol + "//" + host + "/";
8
23
  if (base !== base1) {
9
24
  data.setSource(base1, null);
10
25
  }
26
+ login_queue.push(reform);
11
27
  var page = await popup("/auth/login", base1);
28
+ if (!login_queue.length) return;
29
+ reject_queue.push(page, reject);
12
30
  care(page, "login", function (info) {
13
31
  data.setSource(base1, info);
14
32
  headers.authorization = info;
15
- reform();
33
+ login_queue.splice(0, login_queue.length).forEach(q => q());
34
+ reject_queue.splice(0, reject_queue.length);
35
+ });
36
+ on("remove")(page, function () {
37
+ login_queue.splice(0, login_queue.length);
38
+ if (reject_queue[0] === this) reject_queue.shift();
39
+ reject_queue.splice(0, reject_queue.length).forEach(r => r());
16
40
  });
17
- on("remove")(page, reject);
18
41
  return false;
19
42
  }
20
43
  })
@@ -291,9 +291,9 @@ function parse(string, preload) {
291
291
  module.exports = {
292
292
  stringify,
293
293
  parse(data, preload) {
294
- if (!/^\s*([\[\{]|\[\s*\]|\{\s*\})$/.test(data)) return parse(data, preload);
294
+ if (/^\s*[^\{\[\s]|^\s*(?:\[\s*\]|\{\s*\}|)\s*$/.test(data)) return parse(data, preload);
295
295
  if (/^\s*\{[\d\,\:\s]*\}\s*,/.test(data)) return parse(data, preload);
296
296
  if (/^\s*\[[\d\,\:\s]*\]\s*,/.test(data)) return parse(data, preload);
297
- return JSON.parse(data, preload);
297
+ return JSON.parse(data);
298
298
  }
299
299
  };
@@ -100,9 +100,31 @@ function getDomainPath(url) {
100
100
  return host;
101
101
  }
102
102
 
103
+ function linkCookie(from, to) {
104
+ from = getDomainPath(from).replace(/\/$/, '');
105
+ to = getDomainPath(to).replace(/\/$/, '');
106
+ if (cookiesMap[from]) {
107
+ cookiesMap[to] = cookiesMap[from];
108
+ }
109
+ cookiesMap[to] = cookiesMap[from] = extend({}, cookiesMap[to], cookiesMap[from]);
110
+ return to;
111
+ }
112
+ function copyCookie(from, to) {
113
+ from = getDomainPath(from).replace(/\/$,'/, '');
114
+ to = getDomainPath(to).replace(/\/$/, '');
115
+ if (from in cookiesMap) {
116
+ cookiesMap[to] = JSON.parse(JSON.stringify(cookiesMap[from]));
117
+ }
118
+ else {
119
+ delete cookiesMap[to];
120
+ }
121
+ }
122
+
103
123
  return {
104
124
  cookiesMap,
105
125
  addCookie,
106
126
  getCookies,
107
127
  delCookies,
128
+ linkCookie,
129
+ copyCookie
108
130
  }
@@ -75,6 +75,8 @@ function cross_(jsonp, digest = noop, method, url, headers) {
75
75
  }
76
76
  var loaded, errored;
77
77
  var onload = function (data) {
78
+ if (!~requests.indexOf(_xhr)) return;
79
+ removeFromList(requests, _xhr);
78
80
  if (xhr.decoder) {
79
81
  data = xhr.decoder(data);
80
82
  }
@@ -83,18 +85,21 @@ function cross_(jsonp, digest = noop, method, url, headers) {
83
85
  digest();
84
86
  };
85
87
  var onerror1 = function (e) {
88
+ if (!~requests.indexOf(_xhr)) return;
89
+ removeFromList(requests, _xhr);
86
90
  errored = e || "未知错误!";
87
91
  flush();
88
92
  digest();
89
93
  };
90
94
  var onerror = async function (e) {
91
95
  if (e.type === 'error') {
92
- removeFromList(requests, e.target);
93
96
  e = { response: "无法访问服务器", toString: toResponse };
94
97
  }
95
98
  for (var r of reforms) {
96
- var r = await reform(r, { method, url, status: xhr.status, headers: _headers }, fire, onerror1, e);
97
- if (r === false) return;
99
+ var r = await reform.call(xhr, r, { method, url, status: xhr.status, headers: _headers }, fire, onerror1, e);
100
+ if (r === false) {
101
+ return;
102
+ }
98
103
  }
99
104
  onerror1(e);
100
105
  };
@@ -129,11 +134,10 @@ function cross_(jsonp, digest = noop, method, url, headers) {
129
134
  var nocross = notCross(url, isencrypt);
130
135
  if (nocross) isencrypt = false;
131
136
  var callback = async function () {
132
- removeFromList(requests, xhr);
133
- var exposeHeaders = !nocross && xhr.getResponseHeader("access-control-expose-headers");
134
- var exposeMap = {};
135
- if (exposeHeaders) exposeHeaders.split(",").forEach(h => exposeMap[h.toLowerCase()] = true);
136
137
  if (xhr.getResponseHeader) {
138
+ var exposeHeaders = (!nocross || !location_href) && xhr.getResponseHeader("access-control-expose-headers");
139
+ var exposeMap = {};
140
+ if (exposeHeaders) exposeHeaders.split(",").forEach(h => exposeMap[h.toLowerCase()] = true);
137
141
  var exposekey = nocross ? "set-cookie" : "efront-cookie";
138
142
  if (exposeMap[exposekey]) {
139
143
  var cookie = xhr.getResponseHeader(exposekey);
@@ -149,12 +153,16 @@ function cross_(jsonp, digest = noop, method, url, headers) {
149
153
  }
150
154
 
151
155
  }
156
+ if (exposeMap["strict-transport-security"] || exposeMap["efront-transport-security"]) {
157
+ if (!/^https\:\/\/|^s\/\//.test(url)) console.warn("请使用https访问如下路径:" + url);
158
+ }
152
159
  }
153
160
  if (isencrypt && xhr.response) {
154
161
  try {
155
162
  xhr = {
156
163
  status: xhr.status,
157
164
  response: encode62.safedecode(xhr.response || xhr.responseText, xhr.encrypt),
165
+ getResponseHeader: xhr.getResponseHeader && xhr.getResponseHeader.bind(xhr)
158
166
  };
159
167
  xhr.responseText = xhr.response;
160
168
  }
@@ -243,7 +251,9 @@ function cross_(jsonp, digest = noop, method, url, headers) {
243
251
  }
244
252
  };
245
253
  var fire = async function () {
254
+ if (!~requests.indexOf(xhr)) return;
246
255
  var code = await xhr.encrypt;
256
+ if (!~requests.indexOf(xhr)) return;
247
257
  xhr.encrypt = code;
248
258
  var isform = /^f/i.test(method);
249
259
  if (isform) {
@@ -280,7 +290,7 @@ function cross_(jsonp, digest = noop, method, url, headers) {
280
290
  xhr.open(method, getCrossUrl(url, _headers, isencrypt && code));
281
291
  }
282
292
  if (is_gb2312) xhr.overrideMimeType("text/plain; charset=gb2312");
283
- delete realHeaders.Cookie;
293
+ if (location_href) delete realHeaders.Cookie;
284
294
  Object.keys(realHeaders).forEach(key => setRequestHeader.call(xhr, key, realHeaders[key]));
285
295
  if (!isEmpty(datas)) send.call(xhr, !isencrypt ? datas : encode62.safeencode(datas, code));
286
296
  else send.call(xhr);
@@ -330,6 +340,7 @@ function cross_(jsonp, digest = noop, method, url, headers) {
330
340
  return getCookies(originDomain);
331
341
  };
332
342
  requests.push(xhr);
343
+ var _xhr = xhr;
333
344
  return xhr;
334
345
  }
335
346
  function addDirect(a) {
@@ -356,7 +367,7 @@ var requests = [];
356
367
  var reforms = [];
357
368
  function reform(r, info, fire, cancel, e) {
358
369
  var fired = false;
359
- return r(info, function () {
370
+ return r.call(this, info, function () {
360
371
  if (fired) return;
361
372
  fired = true;
362
373
  fire();
@@ -1,9 +1,16 @@
1
1
  function chooseFile(accept, multiple, extra) {
2
2
  var form = document.createElement("form");
3
- form.innerHTML = `<input ${extra ? extra + " " : ''}type='file'${accept ? ` accept="${accept}"` : ''}${multiple ? ' multiple' : ''} />`;
3
+ form.innerHTML = `<input tabindex=0 ${extra ? extra + " " : ''}type='file'${accept ? ` accept="${accept}"` : ''}${multiple ? ' multiple' : ''} />`;
4
4
  var [input] = form.children;
5
- var result = new Promise(function (ok) {
5
+ var result = new Promise(function (ok, oh) {
6
6
  if (/msie\s+[2-9]/i.test(navigator.userAgent)) return alert("无法在当前浏览器操作!");
7
+ input.onfocus = function () {
8
+ // focus 事件比change事件早40-80毫秒
9
+ if (opened && document.hasFocus()) {
10
+ remove(input);
11
+ setTimeout(oh, 210);
12
+ }
13
+ };
7
14
  on("change")(input, function () {
8
15
  if (!this.files) {
9
16
  var value = this.value;
@@ -27,8 +34,14 @@ function chooseFile(accept, multiple, extra) {
27
34
  }
28
35
  });
29
36
  });
30
- setTimeout(function(){
37
+ var opened = false;
38
+ input.tabIndex = 0;
39
+ css(input, 'opacity:0;pointer-events:none;position:absolute;position:fixed;top:-200px;left:0;')
40
+ appendChild(document.body, input);
41
+ requestAnimationFrame(function () {
42
+ input.focus();
31
43
  input.click();
44
+ opened = true;
32
45
  });
33
46
  return result;
34
47
  }
@@ -1,6 +1,6 @@
1
1
  var { cookiesMap, saveCookie } = cookie;
2
2
  var saveCookie = lazy(function () {
3
- sessionStorage.setItem(cookieItemsInSessionStorageKey, JSON.stringify(cookiesMap));
3
+ sessionStorage.setItem(cookieItemsInSessionStorageKey, JSAM.stringify(cookiesMap));
4
4
  }, 20);
5
5
  var { efrontURI, cross_host = efrontURI } = this;
6
6
  var location_href = parseURL(location.href);
@@ -11,7 +11,7 @@ var cookieItemsInSessionStorageKey = "--zimoli-coms-cross";
11
11
  var cookiesData = sessionStorage.getItem(cookieItemsInSessionStorageKey);
12
12
  if (cookiesData) {
13
13
  try {
14
- extend(cookiesMap, JSON.parse(cookiesData));
14
+ extend(cookiesMap, JSAM.parse(cookiesData));
15
15
  } catch (e) {
16
16
  console.warn("加载cookie出错!");
17
17
  }
@@ -5,15 +5,25 @@ var number = function (event) {
5
5
  var { value, type } = ipt;
6
6
  if (keyCode === 13 || keyCode === 18 || keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40 || keyCode === 8 || keyCode === 46 || keyCode === 9) {
7
7
  }
8
- else if (keyCode >= 49 && keyCode <= 57 || keyCode >= 96 && keyCode <= 105) {
9
- } else if (keyCode === 110 || keyCode === 190) {
8
+ else if (keyCode >= 48 && keyCode <= 57 || keyCode >= 96 && keyCode <= 105) {
9
+ if (this.value) {
10
+ if (this.fixed && this.value.replace(/^[^\.]+/, '').length > this.fixed ||
11
+ this.limit && this.value.length >= this.limit && !/\./.test(this.value)) {
12
+ event.preventDefault();
13
+ }
14
+ if(/^[+-]?0$/.test(this.value)){
15
+ event.preventDefault();
16
+ }
17
+ }
18
+ }
19
+ else if (keyCode === 110 || keyCode === 190) {
10
20
  if (/^int/i.test(type)) {
11
21
  event.preventDefault();
12
22
  } else if (/\./i.test(value) || !value || /^[\-\+]$/.test(value)) {
13
23
  event.preventDefault();
14
24
  }
15
25
  } else if (keyCode === 189 || keyCode === 187) {// 负号 正号
16
- if (value || /^natural|positive/i.test(type)) {
26
+ if (value || this.positive) {
17
27
  event.preventDefault();
18
28
  }
19
29
  } else {
@@ -31,11 +41,32 @@ var number = function (event) {
31
41
  }
32
42
  }
33
43
  };
44
+ var positiveReg = /^\+|^positive\-?|\-?positive$|\+$/i;
45
+ var negativeReg = /^\-|^negative\-?|\-?negative$|\-$/i;
46
+ var numberLimit = /\:(\d+)?(?:\.(\d+))?$/;
47
+ /**
48
+ * @param {HTMLInputElement} element
49
+ */
34
50
  function input(element) {
35
51
  if (element && /input/i.test(element.tagName)) {
36
52
  var type = element.getAttribute("type");
37
53
  if (type) {
38
54
  var format;
55
+ var m = numberLimit.exec(type);
56
+ if (m) {
57
+ type = type.replace(numberLimit, '');
58
+ var [, limit, fixed] = m;
59
+ if (limit) element.limit = +limit;
60
+ if (fixed) element.fixed = +fixed;
61
+ }
62
+ if (positiveReg.test(type)) {
63
+ type = type.replace(positiveReg, '');
64
+ this.positive = true;
65
+ }
66
+ if (negativeReg.test(type)) {
67
+ type = type.replace(negativeReg, '');
68
+ this.negative = true;
69
+ }
39
70
  switch (type.toLowerCase()) {
40
71
  case "date":
41
72
  format = "年月日";
@@ -56,15 +87,22 @@ function input(element) {
56
87
  this.value = new Date(value).toLocaleString(undefined, { hour12: false });
57
88
  };
58
89
  break;
90
+ case "price":
91
+ if (!+element.positive) element.positive = true;
59
92
  case "money":
93
+ if (!element.fixed) element.fixed = 2;
94
+ on("keydown")(element, number);
95
+ break;
96
+ case "natural":
97
+ if (!+element.positive) element.positive = true;
60
98
  case "int":
61
99
  case "integer":
62
- case "integer":
63
100
  case "number":
64
101
  case "num":
65
- case "natural":
66
102
  on("keydown")(element, number);
67
103
  break;
104
+ default:
105
+ if (element.limit && !(element.maxLength > 0)) element.maxLength = element.limit;
68
106
  }
69
107
  }
70
108
  return element;
@@ -36,8 +36,6 @@ var renderModel = function (field, data) {
36
36
  });
37
37
  };
38
38
  var constructors = {
39
- input,
40
- raw: input,
41
39
  swap(e) {
42
40
  var { field } = e;
43
41
  e = swap(e);
@@ -58,6 +56,12 @@ var constructors = {
58
56
  row: textarea,
59
57
  password,
60
58
  text: textarea,
59
+ number(e) {
60
+ var ipt = document.createElement('input');
61
+ ipt.setAttribute('type', e.field.type);
62
+ input(ipt);
63
+ return ipt;
64
+ },
61
65
  date() {
62
66
  var elem = document.createElement("input");
63
67
  elem.type = "date";
@@ -140,6 +144,7 @@ var constructors = {
140
144
 
141
145
  }
142
146
  };
147
+ constructors.price = constructors.money = constructors.number;
143
148
  var readonly_types = {
144
149
  "date"({ field }, data) {
145
150
  var string = data[field.key];
@@ -204,6 +209,7 @@ function main(elem) {
204
209
  elem.setAttribute("type", field_type);
205
210
  }
206
211
  remove(elem.children);
212
+ if (isString(field_type)) field_type = field_type.replace(/\:[\d+\.]+$/, '');
207
213
  if (readonly || field.readonly) {
208
214
  if (field_type === "function") {
209
215
  field_editor(elem);
@@ -244,8 +250,11 @@ function main(elem) {
244
250
  }
245
251
  } else {
246
252
  var create = field_type === "function" ? field_editor : constructors[field_type];
247
- var ipt = create ? create(elem, field_ref) : field.key ? input() : null;
248
-
253
+ var ipt = create ? create(elem, field_ref) : field.key ? input(function () {
254
+ var input = document.createElement('input');
255
+ input.setAttribute('type', field.type);
256
+ return input;
257
+ }()) : null;
249
258
  if (ipt) {
250
259
  if (ipt !== elem) appendChild(elem, ipt);
251
260
  if (!ipt.$scope) {
@@ -867,9 +867,9 @@ function render(element, scope, parentScopes, lazy = true) {
867
867
  var digest = lazy(refresh, -{});
868
868
  render.digest = render.apply = render.refresh = digest;
869
869
  render.parseRepeat = parseRepeat;
870
- var eventsBinders = "fullscreenchange,load,change,click,paste,resize,keydown,keypress,keyup,input,drop".split(",").map(k => on(k));
870
+ var eventsBinders = "fullscreenchange,resize,load,change,click,paste,resize,keydown,keypress,keyup,input,drop".split(",").map(k => on(k));
871
871
  var userChanged = false;
872
- eventsBinders.splice(0, 2).forEach(on => on(window, digest));
872
+ eventsBinders.splice(0, 3).forEach(on => on(window, digest));
873
873
  var changeListener = function () {
874
874
  if (userChanged) {
875
875
  userChanged = false;
@@ -112,6 +112,7 @@ function select(target, list, removeOnSelect, direction) {
112
112
  if (isNode(list)) {
113
113
  var initList = function () {
114
114
  bindEvent();
115
+ list.value = target.value;
115
116
  initList = function () { };
116
117
  };
117
118
  var setIcon = function () {
@@ -123,8 +124,10 @@ function select(target, list, removeOnSelect, direction) {
123
124
  var initList2 = function (src) {
124
125
  src.forEach(s => {
125
126
  optionsMap[s.key] = s;
127
+ s.selected = s.key === target.value;
126
128
  });
127
129
  list = selectList(generator, src, !!target.multiple, !!target.editable);
130
+ list.value = target.value;
128
131
  if (!target.multiple) {
129
132
  onclick(list, onlistclick);
130
133
  }
@@ -137,6 +140,8 @@ function select(target, list, removeOnSelect, direction) {
137
140
  var s = optionsMap[v];
138
141
  this.innerHTML = `<option selected value="${v}">${s ? s.name : ''}</option>`;
139
142
  this.value = v;
143
+ if (s) s.selected = true;
144
+ if (list) list.value = v;
140
145
  };
141
146
  care(target, initList2);
142
147
  var initList = function () {
@@ -74,17 +74,15 @@ function main() {
74
74
  css(item, { backgroundImage: `url('${icon}')` });
75
75
  }
76
76
  item.value = key;
77
- if (option.selected) {
77
+ if (item.value === page.value) {
78
78
  iconed = icon;
79
- if (multiple) {
80
- item.setAttribute("selected", "");
81
- page.value.push(key);
82
- }
83
- else {
84
- item.setAttribute("selected", "");
85
- page.activeNode = item;
86
- page.value = key
87
- }
79
+ item.setAttribute("selected", "");
80
+ page.activeNode = item;
81
+ page.value = key
82
+ }
83
+ else if (multiple && option.selected) {
84
+ item.setAttribute("selected", "");
85
+ page.value.push(key);
88
86
  }
89
87
  if (option.disabled) {
90
88
  item.setAttribute('disabled', '');
@@ -107,7 +105,7 @@ function main() {
107
105
  if (i < 0 || i >= children.length) return;
108
106
  return createItem(generator ? generator(i) : children[i]);
109
107
  });
110
- once("append")(page, function () {
108
+ once("mounted")(page, function () {
111
109
  var index = 0;
112
110
  for (var cx = 0, dx = children.length; cx < dx; cx++)if (children[cx].selected) index = cx;
113
111
  page.clean();