efront 3.5.12 → 3.7.1

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.
Files changed (43) hide show
  1. package/apps/pivot/api.yml +8 -5
  2. package/apps/pivot/auth/login.js +20 -4
  3. package/apps/pivot/home/welcome.html +5 -1
  4. package/apps/pivot/link/list.html +12 -0
  5. package/apps/pivot/link/list.js +25 -0
  6. package/apps/pivot/link/list.less +9 -0
  7. package/apps/pivot/main.js +3 -0
  8. package/apps/pivot/main.less +1 -0
  9. package/apps/pivot/menu.yml +2 -1
  10. package/apps/pivot/token/edit.js +9 -0
  11. package/apps/pivot/token/list.js +13 -0
  12. package/coms/basic/JSAM.js +8 -0
  13. package/coms/basic/loader.js +43 -18
  14. package/coms/basic/refilm_decode.js +2 -2
  15. package/coms/crypt/encode62.js +3 -1
  16. package/coms/frame/edit.html +10 -0
  17. package/coms/frame/edit.js +29 -0
  18. package/coms/frame/edit.less +0 -0
  19. package/coms/frame/list.html +4 -0
  20. package/coms/frame/list.js +64 -0
  21. package/coms/frame/list.less +3 -0
  22. package/coms/zimoli/LoadingArray.ts +3 -0
  23. package/coms/zimoli/data.js +11 -9
  24. package/coms/zimoli/dispatch.js +13 -6
  25. package/coms/zimoli/encode62.js +3 -2
  26. package/coms/zimoli/input.js +0 -6
  27. package/coms/zimoli/input.less +6 -6
  28. package/coms/zimoli/model.js +20 -3
  29. package/coms/zimoli/popup.js +15 -10
  30. package/coms/zimoli/prompt.js +40 -0
  31. package/coms/zimoli/rootElements.js +1 -0
  32. package/coms/zimoli/search.js +15 -0
  33. package/coms/zimoli/select.js +26 -12
  34. package/coms/zimoli/selectList.js +68 -8
  35. package/coms/zimoli/selectList.less +15 -2
  36. package/coms/zimoli/selectListEdit.html +15 -0
  37. package/coms/zimoli/selectListEdit.js +68 -0
  38. package/coms/zimoli/selectListEdit.less +21 -0
  39. package/coms/zimoli/table.html +2 -1
  40. package/coms/zimoli/table.js +1 -1
  41. package/coms/zimoli/zimoli.js +22 -2
  42. package/package.json +1 -1
  43. package/public/efront.js +1 -1
@@ -4,8 +4,10 @@
4
4
  onkeydown(document, function (e) {
5
5
  if (e.which === 27 && rootElements.length) {
6
6
  var r = rootElements.pop();
7
- r.blur();
8
- remove(r);
7
+ if (r) {
8
+ r.blur();
9
+ remove(r);
10
+ }
9
11
  }
10
12
  });
11
13
  var animationStyle = "opacity:0;transform:scale(1.2);transition:.1s opacity ease-out,.2s transform ease-out;";
@@ -162,24 +164,27 @@ var popup_with_mask = function (element, mask = createMask(element)) {
162
164
  return element;
163
165
  };
164
166
  var isypop = function (target) {
167
+ if (!target) return false;
165
168
  var { offsetParent, nextSibling, previousSibling } = target;
166
169
  if (
167
- nextSibling
170
+ nextSibling && nextSibling.tagName === target.tagName
168
171
  && (
169
172
  nextSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
170
173
  || target.offsetLeft - nextSibling.offsetLeft >= nextSibling.offsetWidth / 2
171
174
  )
172
- || previousSibling
175
+ || previousSibling && previousSibling.tagName === target.tagName
173
176
  && (
174
177
  previousSibling.offsetLeft - target.offsetLeft >= target.offsetWidth / 2
175
178
  || target.offsetLeft - previousSibling.offsetLeft >= previousSibling.offsetWidth / 2
176
179
  )
177
180
  ) return true;
178
- if (offsetParent && target.offsetTop / target.offsetHeight < .2 && offsetParent.offsetWidth / target.offsetWidth > 1.5) return true;
181
+ var padding = parseFloat(getComputedStyle(offsetParent).paddingTop) + parseFloat(getComputedStyle(offsetParent).paddingBottom);
182
+ if (offsetParent && target.offsetTop / target.offsetHeight < .2 && (offsetParent.clientWidth - padding) / target.offsetWidth > 1.5) return true;
179
183
 
180
184
  };
181
185
  var isxpop = arriswise(isypop, arguments);
182
186
  var popup_as_extra = function (element, target, style) {
187
+ element.target = target;
183
188
  if (style) {
184
189
  if (/^[vy]/i.test(style)) {
185
190
  popup_as_yextra(element, target, style);
@@ -195,9 +200,9 @@ var popup_as_extra = function (element, target, style) {
195
200
  popup_as_yextra(element, target, style);
196
201
  } else if (isxpop(target)) {
197
202
  popup_as_xextra(element, target, style);
198
- } else if (isypop(target.parentNode)) {
203
+ } else if (isypop(target.offsetParent)) {
199
204
  popup_as_yextra(element, target, style);
200
- } else if (isxpop(target.parentNode)) {
205
+ } else if (isxpop(target.offsetParent)) {
201
206
  popup_as_xextra(element, target, style);
202
207
  } else {
203
208
  if (/inline|cell/i.test(getComputedStyle(target).display)) {
@@ -266,10 +271,10 @@ var _as_yextra = function (global, innerWidth, innerHeight, element, target, poi
266
271
  }
267
272
 
268
273
  css(element, `min-width:auto;`);
269
- var aimedWidth = element.offsetWidth;
274
+ var aimedWidth = getScreenPosition(element).width;
270
275
  //如果宽度不足其附着元素的宽度
271
- if (aimedWidth < target.offsetWidth) {
272
- aimedWidth = target.offsetWidth;
276
+ if (aimedWidth < position.width) {
277
+ aimedWidth = position.width;
273
278
  }
274
279
 
275
280
  //如果宽度超出可视区,调整宽度
@@ -0,0 +1,40 @@
1
+ function prompt(msg = "请输入", check) {
2
+ var ipt = input();
3
+ var oked, ohed;
4
+ var oks = [], ohs = [];
5
+ var fire = function () {
6
+ if (!oked && !ohed) return;
7
+ if (oked) oks.forEach(o => o(ipt.value));
8
+ if (ohed) ohs.forEach(o => o(ipt.value));
9
+ oks.splice(0, oks.length);
10
+ ohs.splice(0, ohs.length);
11
+ };
12
+ var c = confirm(msg, ipt, ["确认", "取消"], function (_) {
13
+ if (oked || ohed) return;
14
+ if (_ === "确认") {
15
+ if (check && check(ipt.value) === false) return false;
16
+ oked = true;
17
+ } else {
18
+ ohed = true;
19
+ }
20
+ fire();
21
+ });
22
+ on('append')(ipt, function () {
23
+ setTimeout(function () {
24
+ ipt.focus();
25
+ });
26
+ })
27
+ on("mousedown")(c, e => e.target !== ipt && e.preventDefault() | ipt.focus());
28
+ on("keydown.enter")(c, function () {
29
+ if (check && check(ipt.value) === false) return;
30
+ oked = true;
31
+ remove(c);
32
+ fire();
33
+ });
34
+ c.then = function (ok, oh) {
35
+ oks.push(ok);
36
+ ohs.push(oh);
37
+ fire();
38
+ };
39
+ return c;
40
+ }
@@ -25,6 +25,7 @@ rootElements.pop = function (elem) {
25
25
  if (cx < 0) {
26
26
  cx = rootElements.length - 1;
27
27
  }
28
+ if (isFunction(rootElements[cx].onback) && rootElements[cx].onback() === false) return;
28
29
  return rootElements.splice(cx, 1)[0];
29
30
  };
30
31
  rootElements.mount = function (elem) {
@@ -0,0 +1,15 @@
1
+ function search(seartext, options) {
2
+ if (options instanceof Array) {
3
+ var hasFullmatch = false;
4
+ var a = options.map(o => {
5
+ if (o.name === seartext) hasFullmatch = true;
6
+ var [power, m] = mark.power(o.name, seartext);
7
+ return { power, name: m, value: o.value };
8
+ }).filter(a => a.power > 0);
9
+ a.sort(function (a, b) {
10
+ return b.power - a.power;
11
+ });
12
+ a.hasFullmatch = hasFullmatch;
13
+ return a;
14
+ }
15
+ }
@@ -2,21 +2,22 @@ var saved_list;
2
2
  var _remove = function () {
3
3
  var removing_list = saved_list;
4
4
  if (removing_list) {
5
- var target = this;
6
- setTimeout(function () {
5
+ setTimeout(function run() {
7
6
  if (removing_list !== saved_list) return remove(removing_list);
8
7
  var { activeElement } = document;
9
- if (!getTargetIn(removing_list, activeElement)) {
8
+ a: if (!getTargetIn(removing_list, activeElement)) {
9
+ var extras = [].concat(removing_list.with);
10
+ for (var e of extras) {
11
+ if (getTargetIn(e, activeElement)) break a;
12
+ }
10
13
  remove(removing_list);
11
14
  if (removing_list === saved_list) saved_list = null;
12
- } else {
13
- once('blur')(activeElement, function () {
14
- setTimeout(function () {
15
- if (document.activeElement === target) return;
16
- _remove();
17
- });
18
- });
15
+ return;
19
16
  }
17
+ once('blur')(activeElement, function () {
18
+ if (!isMounted(this)) return removing_list.target.focus();
19
+ run();
20
+ });
20
21
  });
21
22
  }
22
23
  };
@@ -48,10 +49,23 @@ function select(target, list, removeOnSelect, direction) {
48
49
  onblur(target, removeByBlur);
49
50
  if (/select/i.test(target.tagName)) {
50
51
  onmousedown(target, preventDefault);
52
+ care(target, 'add-option', function (a) {
53
+ var o = document.createElement('option');
54
+ o.value = a.value || a;
55
+ o.innerHTML = a.name || a;
56
+ this.appendChild(o);
57
+ });
58
+ care(target, 'set-options', function (options) {
59
+ this.innerHTML = options.map(o => `<option value="${o.value}">${o.name}</option>`).join("");
60
+ });
61
+ on('focus')(target, preventDefault);
51
62
  }
52
63
  var onlistchange = function () {
53
64
  if (target.multiple) {
54
65
  } else {
66
+ if (!savedOptions) {
67
+ target.innerHTML = `<option selected value="${this.value}">${this.name || this.value}</option>`
68
+ }
55
69
  target.value = this.value;
56
70
  dispatch(target, "change");
57
71
  }
@@ -114,9 +128,9 @@ function select(target, list, removeOnSelect, direction) {
114
128
  var allOptions = [].concat.apply([], target.querySelectorAll("option"));
115
129
  if (deepEqual.shallow(allOptions, savedOptions)) return;
116
130
  savedOptions = allOptions;
117
- list = selectList(allOptions, target.multiple);
131
+ list = selectList(allOptions, target.multiple, target.editable);
118
132
  if (!target.multiple) {
119
- onclick(list, _remove);
133
+ onclick(list, onlistclick);
120
134
  }
121
135
  bindEvent();
122
136
  };
@@ -6,6 +6,7 @@ var singleClick = function () {
6
6
  node.activeNode = this;
7
7
  if (node.value === this.value) return;
8
8
  node.value = this.value;
9
+ node.name = this.name;
9
10
  dispatch(node, "change");
10
11
  };
11
12
  var multipleClick = function () {
@@ -21,21 +22,27 @@ var multipleClick = function () {
21
22
  }
22
23
  dispatch(node, "change");
23
24
  };
24
- function main(children, multiple) {
25
+
26
+ function main(children, multiple, addable) {
25
27
  var list = div();
26
28
  list.value = multiple ? [] : "";
27
29
  var firstValue = false;
28
30
  var clicker = multiple ? multipleClick : singleClick;
29
- var hasIcon = false, iconed = '';
30
- appendChild(list, [].map.call(children, function (option) {
31
- var item = div();
32
- item.innerHTML = option.innerHTML;
33
- var icon = option.getAttribute("icon");
31
+ var itemMap = Object.create(null);
32
+ function createItem(option) {
33
+ var key = option.key || option.value;
34
+ if (key in itemMap) return itemMap[key];
35
+ var item = itemMap[option.value] = document.createElement('div');
36
+
37
+ item.setAttribute("item", '');
38
+ item.innerHTML = option.innerHTML || option.name;
39
+ item.name = option.name || option.innerHTML;
40
+ var icon = option.getAttribute ? option.getAttribute("icon") : option.icon;
34
41
  if (icon) {
35
42
  hasIcon = true;
36
43
  css(item, { backgroundImage: `url('${icon}')` });
37
44
  }
38
- item.value = option.value;
45
+ item.value = key;
39
46
  if (option.selected) {
40
47
  iconed = icon;
41
48
  if (multiple) {
@@ -54,10 +61,63 @@ function main(children, multiple) {
54
61
  onclick(item, clicker);
55
62
  }
56
63
  return item;
57
- }));
64
+
65
+ }
66
+ var hasIcon = false, iconed = '';
67
+ appendChild(list, [].map.call(children, createItem));
68
+ if (addable) {
69
+ var adder = document.createElement("div");;
70
+ adder.innerHTML = "<a>添加</a><a>管理</a>";
71
+ button(adder.firstChild);
72
+ button(adder.children[1]);
73
+ on("click")(adder, async function (event) {
74
+ event.preventDefault();
75
+ var target = getTargetIn(this, event.target, false);
76
+ switch (target) {
77
+ case this.children[0]:
78
+ var a = prompt("请输入", a => {
79
+ if (a in itemMap) {
80
+ alert(`选项 ${a} 已存在!`);
81
+ return false;
82
+ }
83
+ });
84
+ list.with = a;
85
+ on('remove')(a, function () {
86
+ list.with = null;
87
+ });
88
+ a = await a;
89
+ if (a in itemMap) return false;
90
+ cast(list.target, "add-option", a);
91
+ children.push({ name: a, key: a });
92
+ list.insertBefore(createItem({
93
+ name: a,
94
+ value: a,
95
+ }), adder);
96
+ break;
97
+ case this.children[1]:
98
+ var options = [].slice.call(list.children, 0, list.children.length - 1);
99
+ var edit = selectListEdit(options.slice(0));
100
+
101
+ list.with = edit;
102
+ on("remove")(edit, function () {
103
+ list.with = null;
104
+ remove([].slice.call(list.children, 0, list.children.length - 1));
105
+ children.splice(0, children.length);
106
+ children.push.apply(children, edit.$scope.options.map(o => ({ key: o.key || o.value, name: o.name || o.innerHTML })))
107
+ appendChild.before(adder, edit.$scope.options.map(createItem));
108
+ cast(list.target, 'set-options', edit.$scope.options);
109
+ });
110
+ popup(edit, [.5, .5]);
111
+ break;
112
+ }
113
+ })
114
+ adder.setAttribute("adder", '');
115
+ list.appendChild(adder)
116
+ }
58
117
  if (hasIcon) {
59
118
  list.setAttribute('iconed', '');
60
119
  }
61
120
  list.icon = iconed;
121
+ on('mousedown')(list, e => e.preventDefault());
62
122
  return list;
63
123
  }
@@ -2,9 +2,11 @@
2
2
  max-width: 100%;
3
3
  background-color: #fff;
4
4
  line-height: 30px;
5
- box-shadow: 0 0 20px -6px rgba(0, 0, 0, .3);
5
+ box-shadow: 0 0 20px -6px rgba(0, 0, 0, .1);
6
+ box-sizing: border-box;
7
+ border: 1px solid #0003;
6
8
 
7
- >div {
9
+ >[item] {
8
10
  cursor: default;
9
11
  padding: 0 16px;
10
12
 
@@ -49,4 +51,15 @@
49
51
  background-position-y: 50%;
50
52
  background-position-x: 8px;
51
53
  }
54
+ }
55
+
56
+ >[adder] {
57
+ padding: 0 16px;
58
+ text-align: right;
59
+
60
+ a {
61
+ cursor: pointer;
62
+ vertical-align: top;
63
+ margin-left: 10px;
64
+ }
52
65
  }
@@ -0,0 +1,15 @@
1
+ <div head>管理选项</div>
2
+ <div body>
3
+ <div>
4
+ <input placeholder="搜索或添加" v-model="search" @keydown.enter="add()" /><a @click="add()"
5
+ -if="search&&!filtered.hasFullmatch">添加</a>
6
+ </div>
7
+ <div class="item" -repeat="o in (search?filtered:options)">
8
+ <span -html=o.name></span>
9
+ <a type="danger" @click="del(o)">删除</a>
10
+ </div>
11
+ </div>
12
+ <div foot>
13
+ <btn @click="save()">确定</btn>
14
+ <btn type="white" @click="remove()">取消</btn>
15
+ </div>
@@ -0,0 +1,68 @@
1
+ function main(options) {
2
+ var page = view();
3
+ page.innerHTML = template;
4
+ on("submit")(page, e => e.preventDefault());
5
+ render(page, {
6
+ options, a: button, input, _search: '',
7
+ add() {
8
+ var a = this._search;
9
+ a = a.trim();
10
+ if (!a) return;
11
+ if (this.filtered.hasFullmatch) return;
12
+ options.push({ name: a, value: a });
13
+ this.research();
14
+ },
15
+ del(o) {
16
+ for (var cx = 0, dx = options.length; cx < dx; cx++) {
17
+ if (options[cx].value === o.value) {
18
+ var i = cx;
19
+ break;
20
+ }
21
+ }
22
+ if (i >= 0) options.splice(i, 1);
23
+ console.log(i)
24
+ this.research();
25
+ },
26
+ get search() {
27
+ return this._search;
28
+ },
29
+ research() {
30
+ var v = this._search;
31
+ if (v) {
32
+ this.filtered = search(v, options);
33
+ }
34
+ },
35
+ set search(v) {
36
+ this._search = v;
37
+ if (v) {
38
+ this.research();
39
+ }
40
+ },
41
+ btn: button,
42
+ remove() {
43
+ remove(page);
44
+ },
45
+ save() {
46
+ remove(page);
47
+ },
48
+ filtered: []
49
+ });
50
+ drag.on(page.firstChild, page);
51
+ on("append")(page, function () {
52
+ setTimeout(function () {
53
+ page.querySelector("input").focus();
54
+ });
55
+ });
56
+ on("mousedown")(page, e => {
57
+ if (e.target !== page.querySelector("input")) {
58
+ e.preventDefault();
59
+ }
60
+ });
61
+ page.onback = function () {
62
+ if (page.$scope.search) {
63
+ page.$scope.search = '';
64
+ return false;
65
+ }
66
+ };
67
+ return page;
68
+ }
@@ -0,0 +1,21 @@
1
+ & {
2
+ position: absolute;
3
+ user-select: none;
4
+ }
5
+
6
+ [body]>div {
7
+ padding: 6px 10px;
8
+ background: #fff;
9
+
10
+ >* {
11
+ line-height: 28px;
12
+ vertical-align: top;
13
+ margin-right: 20px;
14
+ }
15
+
16
+ &.item {
17
+ &:nth-of-type(n+2) {
18
+ border-top: 1px solid #0003;
19
+ }
20
+ }
21
+ }
@@ -8,7 +8,8 @@
8
8
  <tr>
9
9
  <td -repeat="f in fields">
10
10
  <span -if="f.key" -text="d[f.key]"></span>
11
- <a on-click="o.do(d)" -if="f.options" _type="o.type" -repeat="o in f.options">
11
+ <a on-click="o.do(d)" -if="f.options" _type="o.type instanceof Function?o.type(d):o.type"
12
+ -repeat="o in f.options">
12
13
  <span -text="o.name instanceof Function?o.name(d):o.name"></span>
13
14
  </a>
14
15
  </td>
@@ -91,7 +91,7 @@ var adaptTarget = function (event) {
91
91
  }
92
92
  if (target) target = getFirstSingleColCell(this, target.colend);
93
93
  if (target) {
94
- if (position.right >= getSelection(this).right - 7) {
94
+ if (position.right >= getScreenPosition(this).right - 7) {
95
95
  target = this;
96
96
  return;
97
97
  }
@@ -249,11 +249,31 @@ function prepare(pgpath, ok) {
249
249
  return _with_elements;
250
250
  };
251
251
  state.path = function (url) {
252
- if (isString(url) && /^[^\\\/]/.test(url)) {
252
+ if (isString(url) && /^\.+[\\\/]/.test(url)) {
253
+ url = url.replace(/^\.[\\\/]/, '');
253
254
  url = pgpath.replace(/[^\/]*$/, url);
255
+ var ps = url.split(/[\\\/]/);
256
+ var ds = [];
257
+ for (var p of ps) {
258
+ if (p === "..") {
259
+ ds.pop();
260
+ }
261
+ else if (p !== ".") {
262
+ ds.push(p);
263
+ }
264
+ }
265
+ url = ds.join('/');
254
266
  }
255
267
  return url;
256
- }
268
+ };
269
+ state.popup = function (a) {
270
+ a = state.path(a);
271
+ return popup.apply(this, [a].concat([].slice.call(arguments, 1)));
272
+ };
273
+ state.init = function (a) {
274
+ a = state.path(a);
275
+ return init.apply(this, [a].concat([].slice.call(arguments, 1)));
276
+ };
257
277
  state.go = function (url, args, _history_name) {
258
278
  // if (arguments.length === 1 && isFinite(url)) return window_history.go(url | 0);
259
279
  var to = function (_url, args, _history_name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efront",
3
- "version": "3.5.12",
3
+ "version": "3.7.1",
4
4
  "description": "一个开发工具,开放源代码,自带组件库和编译环境,可以用来开发web组件,web应用或nodejs模块,或做为已有代码的加密工具,也可以做为静态页面服务器或跨域中转服务器使用",
5
5
  "main": "public/efront.js",
6
6
  "directories": {