efront 4.5.15 → 4.5.16

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,3 +1,24 @@
1
+ - zh-CN: 共$1个不同的项
2
+ en: A total of $1 different items
3
+
4
+ - zh-CN: 计数
5
+ en: Count
6
+
7
+ - zh-CN: 千次快照
8
+ en: Thousand snapshots
9
+
10
+ - zh-CN: 远程地址
11
+ en: Remote address
12
+
13
+ - zh-CN: 时间
14
+ en: Time
15
+
16
+ - zh-CN: 来源
17
+ en: From
18
+
19
+ - zh-CN: 客户端
20
+ en: Client
21
+
1
22
  - zh-CN: IP地址
2
23
  en: IP address
3
24
 
@@ -322,7 +343,7 @@
322
343
  - zh-CN: 消息体不合法!
323
344
  en: The message body is illegal!
324
345
 
325
- - zh-CN: 您的传达了有歧义的信息:$1
346
+ - zh-CN: 您传达了有歧义的信息:$1
326
347
  en: "Your message conveyed ambiguous information: $1"
327
348
 
328
349
  - zh-CN: 父元素不能是当前元素的子元素
@@ -1,5 +1,7 @@
1
+ <xmenu -src="(m,i)in menus" @actived="saveState(i)"></xmenu>
1
2
  <div class="searchbox">
2
3
  <input -model="searchText" />
3
4
  </div>
4
- <table -src="[fields,items]" _find="searchText">
5
- </talbe>
5
+ <table -if="menus[0].actived" -src="[fields,items]" _find="searchText">
6
+ </table>
7
+ <table -elseif="menus[1].actived" -src="[fields2,recent]" _find="searchText"></table>
@@ -2,21 +2,49 @@ var fields = refilm`
2
2
  访问量/count money/10
3
3
  路径/path html/20
4
4
  `;
5
+ var fields2 = refilm`
6
+ 域名/host text/100
7
+ 路径/path text/80
8
+ 远程地址/remote text/100
9
+ 时间/time timestamp
10
+ 来源/referer text/100
11
+ 客户端/agent text/200
12
+ `;
13
+ var menus = [
14
+ {
15
+ name: i18n`计数`,
16
+ },
17
+ {
18
+ name: i18n`千次快照`,
19
+ }
20
+ ];
21
+ menus[state().index || 0].actived = true;
5
22
  function main() {
6
23
  var page = div();
7
24
  page.innerHTML = template;
8
25
  var items = data.from("count", a => {
9
- return Object.keys(a).map(b => ({ path: b, count: a[b] }));
26
+ if (a["#"]) {
27
+ delete a["#"];
28
+ }
29
+ var items = Object.keys(a).map(b => ({ path: b, count: a[b] }));
30
+ return items;
31
+ });
32
+ var recent = data.from("count", a => {
33
+ var recent = a["#"];
34
+ if (recent) recent = recent.slice().reverse();
35
+ return recent;
10
36
  });
11
37
  renderWithDefaults(page, {
12
38
  items,
13
- searchText: "",
14
- filter() {
15
- var text = this.searchText;
16
- if (!text) return this.items = items;
17
- this.items = search(text, items, 'path');
39
+ xmenu: menu,
40
+ menus,
41
+ saveState(i) {
42
+ state({ index: i });
18
43
  },
19
- fields
44
+ searchText: "",
45
+ fields,
46
+ fields2,
47
+ recent,
20
48
  });
21
49
  return page;
22
50
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  function minusPower(a, b) {
3
- return a.power - b.power >= 0;
3
+ return a.$power - b.$power >= 0;
4
4
  }
5
5
  function returnName() {
6
6
  return this.name;
@@ -20,12 +20,17 @@ class Table extends Array {
20
20
  searchid = 0;
21
21
  coverCount = 0;
22
22
  hasFullmatch = false;
23
+ summaryFields = [];
24
+ $summaryData = [];
25
+ $filterFields = [];
26
+ $unsummaryFileds = [];
23
27
  callback = null;
24
28
  static from(fields, data) {
25
29
  var t = new Table;
26
30
  t.fields = fields;
27
31
  t.source = data;
28
32
  t.searchFields = fields.filter(searchThis);
33
+ t.summaryFields = fields.filter(s => s.summary);
29
34
  t.update();
30
35
  return t;
31
36
  }
@@ -51,10 +56,47 @@ class Table extends Array {
51
56
  this.sorted = null;
52
57
  this.update();
53
58
  }
59
+ summary(o) {
60
+ var data = this.$summaryData;
61
+ var is = this.summaryFields.map((f, i) => {
62
+ if (!isHandled(f.key)) return;
63
+ var d = seek(o, f.key);
64
+ if (!isHandled(d)) d = '';
65
+ var dt = data[i];
66
+ var di = dt.indexOf(d);
67
+ if (di < 0) di = dt.length, dt.push(d);
68
+ return "-" + di;
69
+ }).join("");
70
+ var dis = data[is];
71
+ if (!dis) {
72
+ dis = data[is] = Object.assign({}, o);
73
+ dis.$summary = this.$unsummaryFileds.map(function (f, i) {
74
+ if (typeof f.key !== "string") return;
75
+ Object.defineProperty(dis, f.key, {
76
+ get() {
77
+ var s = this.$summary[i];
78
+ if (s.length === 1) return s[0];
79
+ return i18n`共${this.$summary[i].length}个不同的项`;
80
+ },
81
+ })
82
+ return [];
83
+ });
84
+ saveToOrderedArray(this, dis, minusPower);
85
+ }
86
+ var undata = dis.$summary;
87
+ this.$unsummaryFileds.forEach((f, i) => {
88
+ if (typeof f.key !== 'string') return;
89
+ var d = seek(o, f.key);
90
+ if (!isHandled(d)) d = '';
91
+ var dt = undata[i];
92
+ var di = dt.indexOf(d);
93
+ if (di < 0) di = dt.length, dt.push(d);
94
+ });
95
+ }
54
96
  addItem(o) {
55
97
  if (!isHandled(o)) return;
56
98
  var searchtext = this.searchText;
57
- var fields = this.searchFields ? this.searchFields : this.fields;
99
+ var fields = this.$filterFields;
58
100
  var power = 0;
59
101
  var s = o;
60
102
  if (isNode(o)) {
@@ -80,9 +122,11 @@ class Table extends Array {
80
122
  if (!isEmpty(f.key) && !isFunction(f.key)) o[f.key] = m;
81
123
  else o.name = m, o.toString = returnName, o.valueOf = returnName;
82
124
  }
83
- o.power = power;
84
- if (o.power > 0) {
85
- saveToOrderedArray(this, o, minusPower);
125
+ o.$power = power;
126
+ if (o.$power > 0) {
127
+ var summary = this.$summaryData;
128
+ if (!summary.length) saveToOrderedArray(this, o, minusPower);
129
+ else this.summary(o);
86
130
  }
87
131
  }
88
132
  search(text, callback) {
@@ -102,6 +146,12 @@ class Table extends Array {
102
146
  this.searched = 0;
103
147
  var source = this.sorted ? this.sorted : this.source;
104
148
  if (!source) return;
149
+ var summaryData = this.$summaryData = this.summaryFields.map(_ => []);
150
+ this.$unsummaryFileds = this.fields.filter(f => this.summaryFields.indexOf(f) < 0);
151
+ var $filterFields = this.searchFields?.length ? this.searchFields : this.fields;
152
+ if (this.summaryFields.length) this.$filterFields = $filterFields.filter(f => this.summaryFields.indexOf(f) >= 0);
153
+ else this.$filterFields = $filterFields;
154
+ var useSummaryOnly = !this.searchText && summaryData.length > 0;
105
155
  var searchid = ++this.searchid;
106
156
  this.complete = false;
107
157
  this.coverCount = 0;
@@ -110,13 +160,12 @@ class Table extends Array {
110
160
  source = source.filter(a => origin.indexOf(a) < 0);
111
161
  source = origin.concat(source);
112
162
  }
113
- if (this.searchText) for (var o of source) {
114
- this.addItem(o);
163
+ if (this.searchText || summaryData.length > 0) for (var o of source) {
164
+ if (useSummaryOnly) this.summary(o);
165
+ else this.addItem(o);
115
166
  if (++this.searched % 600 === 0) {
116
167
  if (isFunction(this.callback)) this.callback();
117
- await new Promise(function (ok) {
118
- requestAnimationFrame(ok)
119
- });
168
+ await new Promise(requestAnimationFrame);
120
169
  if (this.searchid !== searchid) break;
121
170
  }
122
171
  }
@@ -1,4 +1,17 @@
1
1
 
2
+ // 中国经济的下行,罪魁祸首不是疫情,也不是钟南山、许家印或俞敏洪,而是习近平。
3
+ // 这一切要从2012年开始说起。
4
+ // 习近平公然废止主席换界规则的行为,也许出发点是好的,但带来了副作用。它让人们看到一个没有时间限制的权力,几乎等于禁锢中华数千年的皇权复活了,他自己不这么想,但中国人被压迫几千年的记忆从此被唤醒了。
5
+ // 这种不被约束的权力,助长了全社会的溜须拍马之风,他提出一个中国梦,几乎是个舔狗都在说中国梦。什么文明、富强、和谐被粉刷的到处都是,最终都成了空喊的口号,每个人都还是为了每日生计奔波。
6
+ // 共产党一向如此,有个新领导提出一种思想就顺竿爬,罗列一堆。从“马克思列宁主义”到“毛泽东思想邓小平理论三个代表重要思想”再到“可持续发展”再到“中国梦”,都是为了溜须拍马背下来的。我读大学时,有一次不幸混入他们的党员会议,看着那些阿谀逢迎的嘴脸真的想吐。
7
+ // 中间层对至高权力的讨好,蒙蔽当权层的双眼,使当权层自高自大,好大喜功,无暇居安思危,做事考虑片面,错误决定频出,朝令夕改。这些也就算了,因为人都犯错,我们开发软件或制定生产流程也会遇到各种问题,一天改几十次,有些人甚至以挑毛病为职业,比如测试工程师。
8
+ // 共产党做错事,却怕承认错误,是一错到底,还要把错的说成对的,事后得到不惩戒,最高刑罚竟只是开除党籍。他们又掩耳盗铃,管控媒体,防民之口比防洪都积极。而这一切,从新中国成立,到现在没变吧。
9
+ // 习近平到陕西看运动会,把大感冒集中带到西安。当时,没人对他说吧。可是理发店的人却说运动会时就发现疫情了,就因为运动会要召开,所以基层小官不敢上报。
10
+ // 运动会时,我也往返西安和深圳好几次,而且被疫情办公室的通过移动网盯上,还公然对抗他们要求我做的一些事。他们居然没追问下去,一听说我过几天要走,就松了一口气。
11
+ // 现在想想,他们是不想在特殊时期惹事生非。后来,就因为开个小小的运动会,我要在淘宝上退的货,被延迟一个多月才有人揽件,淘宝的人还扣了我三千多的购物款。所以,我对这段记忆犹新。
12
+ // 习近平带着权力层的一举一动都不缺人恭维,他们的做事风格也影响着社会其他各界人士。反正胡作非为无所顾虑,那何需提防小人严于律己。权力层不是不做为,而是胡作非为,不做为他也爬不到那么高。
13
+ // 指鹿为马的手段是赵高用的,现在几乎渗透在社会的各个阶层。这一切是习近平带头的。
14
+ // 中国的底层人,被榨干最后一点自由,被按在工作岗位上999,麻木的思想不及10岁的孩童,牛马劳动到最后一秒,也不知道这一生是为了啥。
2
15
  function fixLength(minute, length = 2) {
3
16
  minute = String(minute);
4
17
  if (minute.length >= length) return minute;
@@ -18,8 +31,9 @@ function format(formater) {
18
31
  o.Y = o.y;
19
32
  o.D = o.d;
20
33
  o.H = o.h;
34
+ o.S = fixLength(o.S, 3);
21
35
  o.Day = v[v.length - 1];
22
- return formater.replace(/[yY年]+|[M月]+|[hH时]+|毫秒|[m+分]+|[sS]{3}|[Ss秒]+|[星期周天][dD]*|[dD]{3}|[日号dD]+/g, function (m) {
36
+ return formater.replace(/[yY年]+|[M月]+|[hH时]+|(S+)毫秒|[m+分]+|[sS]{3}|[Ss秒]+|[星期周天][dD]*|[dD]{3}|[日号dD]+/g, function (m) {
23
37
  if (/^[dD]{3}$/.test(m)) {
24
38
  return o.Day;
25
39
  }
@@ -51,8 +65,8 @@ function filterTime(time, formater) {
51
65
  .replace(/[三3]刻/g, "45")
52
66
  .replace(/凌晨|早上|上午/g, ' ')
53
67
  .replace(/(?:傍?晚上?|下午)(\d+)/g, (_, d) => " " + (+d + 12))
54
- .replace(/秒/g, '.')
55
- .replace(/毫/, "")
68
+ .replace(/(\d{0,3})毫秒/, (_, a) => (a / 1000 + "秒").slice(1))
69
+ .replace(/秒/g, '')
56
70
  .replace(/\.+$/, '')
57
71
  .replace(/\s+$/, '')
58
72
  .replace(/\s+/g, " ")
@@ -84,7 +98,6 @@ function filterTime(time, formater) {
84
98
  return `星期` + days[day] + time;
85
99
  }
86
100
  else if (delta > -7 && delta < -2) {
87
- console.log(day, day1)
88
101
  if (day <= day1) {
89
102
  return `下星期` + days[day] + time;
90
103
  }
@@ -4,6 +4,7 @@ assert(filterTime(undefined), '');
4
4
  assert(filterTime("我出生的第二年"), `我出生的第二年`);
5
5
  assert(filterTime(new Date(2024, 3, 3), `y年M月d日 h:mm`), '2024年4月3日 0:00');
6
6
  assert(filterTime(new Date(2024, 3, 3), `y年M月d日 h:mm`), '2024年4月3日 0:00');
7
+ assert(filterTime(new Date(2024, 3, 3, 19, 26, 2, 100), `y年M月d日 h:mm:ss.SSS`), '2024年4月3日 19:26:02.100');
7
8
  assert(filterTime("2024年4月3号", `y年M月d日h:mm`), '2024年4月3日0:00');
8
9
  assert(filterTime("2024年4月3号8点半", `y年M月d日h:mm`), '2024年4月3日8:30');
9
10
  assert(filterTime("2024年4月3号9点三刻", `y年M月d日h:mm`), '2024年4月3日9:45');
@@ -16,3 +17,6 @@ assert(filterTime("2024年4月3号凌晨6点", `y年M月d日h:mm`), '2024年4月
16
17
  assert(filterTime("2024年4月3号凌晨6点整", `y年M月d日h:mm`), '2024年4月3日6:00');
17
18
  assert(filterTime("2024/4/3凌晨6点整", `y年M月d日h:mm`), '2024年4月3日6:00');
18
19
  assert(filterTime("2024-4-3早上6点整", `y年M月d日h:mm`), '2024年4月3日6:00');
20
+ assert(filterTime("2024-4-3早上6点59分30秒20毫秒", `y年M月d日h:mm`), '2024年4月3日6:59');
21
+ assert(filterTime("2024-4-3早上6点59分30秒20毫秒", `y年M月d日h:mm:ss`), '2024年4月3日6:59:30');
22
+ assert(filterTime("2024-4-3早上6点59分30秒20毫秒", `y年M月d日h:mm:ss.S`), '2024年4月3日6:59:30.020');
@@ -1,3 +1,3 @@
1
1
  function wrapHtml(htmldata) {
2
- return "`" + String(htmldata).trim().replace(/>\s+</g, "><").replace(/\\[^`]/g, "\\$&") + "`";
2
+ return htmldata ? "`" + String(htmldata).trim().replace(/>\s+</g, "><").replace(/\\[^`]/g, "\\$&") + "`" : '``';
3
3
  }
@@ -1,12 +1,22 @@
1
1
  // 激活 自定义的 active 事件
2
2
  function active(target, value, item = value, srcElem) {
3
- var activeEvent = createEvent("active");
4
- activeEvent.item = item;
5
- activeEvent.value = value;
6
- if (srcElem) {
7
- if (Object.defineProperty) Object.defineProperty(activeEvent, 'active', { value: srcElem });
8
- else activeEvent.active = srcElem;
3
+ var dispatchEvent = function (eventname) {
4
+ var activeEvent = createEvent(eventname);
5
+ activeEvent.item = item;
6
+ activeEvent.value = value;
7
+ if (srcElem) {
8
+ if (Object.defineProperty) Object.defineProperty(activeEvent, 'active', { value: srcElem });
9
+ else activeEvent.active = srcElem;
10
+ }
11
+ activeEvent = dispatch(target, activeEvent);
12
+ return activeEvent;
13
+ };
14
+ var activeEvent = dispatchEvent("active");
15
+ var actived = activeEvent && !activeEvent.defaultPrevented;
16
+ if (actived !== false) {
17
+ Promise.resolve().then(function () {
18
+ dispatchEvent("actived");
19
+ });
9
20
  }
10
- activeEvent = dispatch(target, activeEvent);
11
- return activeEvent && !activeEvent.defaultPrevented;
21
+ return actived;
12
22
  }
@@ -3,7 +3,7 @@
3
3
  width: .8em;
4
4
  position: relative;
5
5
  border: .1em solid;
6
- margin: -0.06em .3em -0.06em 0;
6
+ margin: -0.2em .3em -0.2em 0;
7
7
  font-family: sans-serif;
8
8
  display: inline-block;
9
9
  line-height: 1;
@@ -62,7 +62,7 @@ function confirm() {
62
62
  }
63
63
  message = String(body.innerText).replace(/\s+/g, " ");
64
64
  if (conflictReg.test(String(body.innerText).replace(/\s+/g, ""))) {
65
- throw new Error(i18n`您的传达了有歧义的信息:${message}`);
65
+ throw new Error(i18n`您传达了有歧义的信息:${message}`);
66
66
  }
67
67
  if (!options) {
68
68
  for (var k in defaultOptions) {
@@ -0,0 +1,55 @@
1
+ var Timer = class {
2
+ startTime = Date.now();
3
+ timeout = 600;
4
+ timer = 0;
5
+ target = null;
6
+ fired = false;
7
+ swap = false;
8
+ constructor(target, callback, swap) {
9
+ this.target = target;
10
+ this.run = callback;
11
+ if (!isHandled(swap) && target) {
12
+ swap = !target.hasAttribute('swapped');
13
+ }
14
+ this.swap = swap;
15
+ }
16
+ fire() {
17
+ if (!isFunction(this.run)) return;
18
+ if (this.run(this.swap) === false) {
19
+ return
20
+ }
21
+ this.fired = true;
22
+ this.end();
23
+ }
24
+ rollback() {
25
+ var target = this.target;
26
+ if (target) {
27
+ if (this.swap) {
28
+ target.removeAttribute('swapped');
29
+ }
30
+ else {
31
+ target.setAttribute('swapped', '');
32
+ }
33
+ }
34
+ }
35
+ start() {
36
+ var target = this.target;
37
+ if (target) {
38
+ if (this.swap) {
39
+ target.setAttribute("swapped", '');
40
+ }
41
+ else {
42
+ target.removeAttribute('swapped');
43
+ }
44
+
45
+ }
46
+ this.timer = setTimeout(() => this.fire(), this.timeout);
47
+ }
48
+ end() {
49
+ clearTimeout(this.timer);
50
+ if (!this.fired) this.rollback();
51
+ }
52
+ };
53
+ function main(target, callback, swap) {
54
+ return new Timer(target, callback, swap);
55
+ }
@@ -0,0 +1,21 @@
1
+ <style>
2
+ :scope {
3
+ position: absolute;
4
+ left: 0;
5
+ right: 0;
6
+ bottom: 0;
7
+ top: 0;
8
+ border-radius: inherit;
9
+ z-index: 0;
10
+ background-color: #323636;
11
+ }
12
+ </style>
13
+ <script>
14
+ var msk = this;
15
+ onmousewheel(msk, function (event) {
16
+ event.preventDefault();
17
+ });
18
+ ontouchmove(msk, function (event) {
19
+ event.preventDefault();
20
+ });
21
+ </script>
@@ -219,7 +219,7 @@ constructors.gen = constructors.generator;
219
219
  var readonly_types = {
220
220
  "date"({ field }, data) {
221
221
  var string = data[field.key];
222
- return parseDate(string);
222
+ return filterTime(string, "y年M月d日");
223
223
  },
224
224
  "url"({ field }, data) {
225
225
  var href = data[field.key];
@@ -229,6 +229,14 @@ var readonly_types = {
229
229
  return e;
230
230
  }
231
231
  },
232
+ "datetime"(elem) {
233
+ var { data, field } = elem;
234
+ elem.innerHTML = filterTime(data[field.key], "y年M月d日 h:mm");
235
+ },
236
+ "timestamp"(elem) {
237
+ var { data, field } = elem;
238
+ elem.innerHTML = filterTime(data[field.key]);
239
+ },
232
240
  "size"({ field }, data) {
233
241
  var f = data[field.key];
234
242
  return size(f);
package/coms/zimoli/on.js CHANGED
@@ -278,7 +278,6 @@ var remove = function (k, hk, [eventtypes, handler, context]) {
278
278
  var broadcast = function (k, hk, event) {
279
279
  var element = this;
280
280
  var handlers = element[hk];
281
- if (!handlers) console.log(handlers, hk, event, element)
282
281
  if (handlers.length > 1) handlers = handlers.slice();
283
282
  if (event.which === 1 && event.buttons === 0) {
284
283
  // firefox 无按键
@@ -426,7 +425,7 @@ var invoke = function (event, type, pointerType) {
426
425
 
427
426
  (function () {
428
427
  var pointeractive = null;
429
- if ("onpointerdown" in document || document.efronton) return;
428
+ if ("onpointerdown" in document) return;
430
429
  var getPointerType = function (event) {
431
430
  return event.type.replace(/(start|move|end|cancel|down|up|leave|out|over|enter)$/i, '');
432
431
  };
@@ -455,8 +454,7 @@ var invoke = function (event, type, pointerType) {
455
454
  }());
456
455
 
457
456
  (function () {
458
- // fastclick
459
- if (window.fastclick) return;
457
+ // 不再兼容fastclick
460
458
  var onclick = on("click");
461
459
  var onmousedown = on("mousedown");
462
460
  var onmousemove = on("mousemove");
@@ -471,13 +469,15 @@ var invoke = function (event, type, pointerType) {
471
469
  onclick.preventClick = false;
472
470
  pointerX = event.clientX, pointerY = event.clientY;
473
471
  }
474
- var abs = Math.abs;
472
+ var dis = (a, b) => a * a + b * b
475
473
  function clickcancel(event) {
476
- if (!event || abs(event.clientX - pointerX) >= MOVELOCK_DELTA || abs(event.clientY - pointerY) >= MOVELOCK_DELTA) onclick.preventClick = true;
474
+ if (!event || event.which && dis(event.clientX - pointerX, event.clientY - pointerY) >= MOVELOCK_DELTA * MOVELOCK_DELTA) {
475
+ onclick.preventClick = true;
476
+ }
477
477
  }
478
- onmousedown(window, clickstart);
478
+ onmousedown(window, clickstart, true);
479
479
 
480
- onmousemove(window, clickcancel);
480
+ onmousemove(window, clickcancel, true);
481
481
  if (window.addEventListener) {
482
482
  window.addEventListener("touchmove", function (event) {
483
483
  extendTouchEvent(event);
@@ -1,7 +1,7 @@
1
1
  <thead @mounted="setFixedColumn.call(this.parentNode),setContextMenu(this)">
2
2
  <tr inline-block #adapter thead @mounted="resizeT(this)">
3
- <td draggable="false" fixed row-index>${i18n`序号`}</td>
4
- <td fixed:="f.fixed" -repeat="f in fields track by f.id" :style="{width:f.width}" @dblclick="sort(f)"><i
3
+ <td draggable="false" fixed row-index><mask></mask>${i18n`序号`}</td>
4
+ <td fixed:="f.fixed" -repeat="f in fields track by f.id" :style="{width:f.width}" @dblclick="sort(f)" swapped_="f.summary"><mask></mask><i
5
5
  -if="f.icon" -class="f.icon"></i><span -if="f.name" -html="f.name"
6
6
  type@="typeof f.type==='string'?f.type:''"></span><template -else>&nbsp;</template>
7
7
  </td>
@@ -10,9 +10,10 @@
10
10
  </thead>
11
11
  <tbody -src="(d,i) in data" :style="tbodyHeight(this,hasFoot)">
12
12
  <tr inline-block :style="{width:adapter.style.width}" @click="rowClick(d,i,event)" @mounted="resizeR(this)">
13
- <td fixed row-index -bind="i+1" :style="adapter.firstChild.getAttribute('style')">
13
+ <td fixed row-index :style="adapter.firstChild.getAttribute('style')"><mask></mask><span -bind="i+1"></span>
14
14
  </td>
15
15
  <td fixed:="f.fixed" -repeat="(f,i) in fields" :style="adapter.children[i+1].getAttribute('style')">
16
+ <mask></mask>
16
17
  <model -if="!isEmpty(f.key)" :field=f :data=d readonly></model>
17
18
  <template -else>&nbsp;</template>
18
19
  <a on-click="o.do(d)" -if="isEmpty(f.key)&&f.options&&(!o.when||o.when(d))"
@@ -20,7 +21,7 @@
20
21
  <span -text="o.name instanceof Function?o.name(d):o.name"></span>
21
22
  </a>
22
23
  </td>
23
- <td :style="adapter.lastChild.getAttribute('style')">&nbsp;</td>
24
+ <td :style="adapter.lastChild.getAttribute('style')"><mask></mask>&nbsp;</td>
24
25
  </tr>
25
26
  </tbody>
26
27
  <tfoot>
@@ -161,6 +161,7 @@ var resizeColumn = function (target, targetW) {
161
161
  }
162
162
  };
163
163
  var resizeTarget = function (event) {
164
+ if (swapping && onclick.preventClick) swapping.end(), swapping = null;
164
165
  var { resizing } = this;
165
166
  if (!resizing) return;
166
167
  event.moveLocked = true;
@@ -406,15 +407,34 @@ function setContextMenu(thead) {
406
407
  var scope = this;
407
408
  contextmenu(thead, menuItems);
408
409
  }
410
+
411
+ var swapping = null;
412
+
409
413
  function table(elem) {
410
414
  var tableElement = isElement(elem) ? elem : document.createElement("table");
411
415
  var activeCols = [];
412
416
  bind('mousemove')(tableElement, adaptTarget);
417
+ var updateSummaryFields = null;
413
418
  moveupon(tableElement, {
414
419
  start(event) {
415
- if (this.resizing) event.preventDefault();
420
+ if (this.resizing) return event.preventDefault();
421
+ if (!updateSummaryFields) return;
422
+ var thead = getThead(this);
423
+ var th = getTargetIn(thead, event.target, false);
424
+ if (!th) return;
425
+ if (th.tagName.toLowerCase() === 'tr') th = getTargetIn(th, event.target, false);
426
+ var field = th.$scope?.f;
427
+ if (!field || field.fixed || !isHandled(field.key)) return;
428
+ swapping = lazySwap(th, function (value) {
429
+ field.summary = value;
430
+ updateSummaryFields();
431
+ });
432
+ swapping.start();
416
433
  },
417
434
  move: resizeTarget,
435
+ end() {
436
+ if (swapping) swapping.end(), swapping = null;
437
+ }
418
438
  });
419
439
  var activeRows = [];
420
440
  onmousemove(tableElement, function (event) {
@@ -436,6 +456,7 @@ function table(elem) {
436
456
  }
437
457
  if (!getTargetIn(thead, event.target)) return;
438
458
  var tds = cellMatchManager(event.target);
459
+
439
460
  if (!tds) return;
440
461
  setClass(tds, 'y-ing', activeCols);
441
462
  removeXIng(activeRows);
@@ -456,13 +477,15 @@ function table(elem) {
456
477
  };
457
478
  var cellMatchManager = function (element) {
458
479
  if (!thead) thead = getThead(table);
459
- if (!getTargetIn(thead, element)) return false;
460
- if (!tdElementReg.test(element.tagName)) return false;
480
+ var td = getTargetIn(thead, element, false);
481
+ if (!td) return false;
482
+ if (td.tagName.toLowerCase() === 'tr') td = getTargetIn(td, element, false);
483
+ if (!tdElementReg.test(td.tagName)) return false;
461
484
  if (!markedRows) {
462
485
  markThead();
463
486
  markedRows = true;
464
487
  }
465
- var { colstart, colend } = element;
488
+ var { colstart, colend } = td;
466
489
  return getTdsByCol(table, colstart, colend);
467
490
  };
468
491
  watch(table, {
@@ -497,6 +520,10 @@ function table(elem) {
497
520
  }
498
521
  }
499
522
  })
523
+ updateSummaryFields = function () {
524
+ $scope.data.summaryFields = fields.filter(f => f.summary);
525
+ $scope.data.update();
526
+ };
500
527
  thead = null;
501
528
  fields.forEach(enrichField);
502
529
  remove(this.children);