@plcmp/pl-virtual-scroll 1.0.5 → 1.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plcmp/pl-virtual-scroll",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Component for lazy list render.",
5
5
  "main": "pl-virtual-scroll.js",
6
6
  "repository": {
@@ -64,7 +64,7 @@ class PlVirtualScroll extends PlElement {
64
64
 
65
65
  this.canvas = this.canvas ?? this.$.vsCanvas;
66
66
  this.canvas.parentNode.addEventListener('scroll', e => this.onScroll(e));
67
- let tplEl = [...this.childNodes].find(n => n.nodeType === document.COMMENT_NODE && n.textContent.startsWith('tpl:'));
67
+ const tplEl = [...this.childNodes].find(n => n.nodeType === document.COMMENT_NODE && n.textContent.startsWith('tpl:'));
68
68
  this.sTpl = tplEl?._tpl;
69
69
  this._hctx = tplEl?._hctx;
70
70
  }
@@ -72,27 +72,31 @@ class PlVirtualScroll extends PlElement {
72
72
  _dataChanged(data, old, /** DataMutation */ mutation) {
73
73
  // set microtask, element may be not inserted in dom tree yet,
74
74
  // but we need to know viewport height to render
75
- let [, index, ...rest] = normalizePath(mutation.path);
75
+ const [, index, ...rest] = normalizePath(mutation.path);
76
76
  switch (mutation.action) {
77
77
  case 'upd':
78
78
  if (mutation.path === 'items' && Array.isArray(mutation.value) && Array.isArray(mutation.oldValue)) {
79
79
  this.phyPool.forEach((i) => {
80
- if (i.index !== null && i.index < this.items.length) {
81
- if (this.items[i.index] instanceof PlaceHolder) this.items.load?.(this.items[i.index]);
82
-
83
- i.ctx.replace(this.items[i.index]);
84
- i.ctx.applyEffects(undefined);
85
- i.ctx._ti.applyBinds();
86
- } else if (i.index >= this.items.length) {
87
- i.index = null;
80
+ if (i.index !== null) {
81
+ if (i.index < this.items.length) {
82
+ if (this.items[i.index] instanceof PlaceHolder) this.items.load?.(this.items[i.index]);
83
+
84
+ i.ctx.replace(this.items[i.index]);
85
+ i.ctx.applyEffects(undefined);
86
+ i.ctx._ti.applyBinds();
87
+ } else {
88
+ i.index = null;
89
+ i.offset = -10000;
90
+ fixOffset(i);
91
+ }
88
92
  }
89
93
  });
90
94
  }
91
95
 
92
96
  if (index !== undefined && +index >= 0) {
93
- let el = this.phyPool.find(i => i.index === +index);
97
+ const el = this.phyPool.find(i => i.index === +index);
94
98
  if (el && rest.length > 0) {
95
- let path = [this.as, ...rest].join('.');
99
+ const path = [this.as, ...rest].join('.');
96
100
  el.ctx.applyEffects({ ...mutation, path });
97
101
  if (this.items[el.index] instanceof PlaceHolder) this.items.load?.(this.items[el.index]);
98
102
  }
@@ -102,32 +106,34 @@ class PlVirtualScroll extends PlElement {
102
106
  break;
103
107
 
104
108
  case 'splice': {
105
- let { index: spliceIndex } = mutation;
106
- // if mutation is not root try to apply effects to children (need when pushing to array inside array)
107
- if (rest.length > 0) {
108
- let path = [this.as, ...rest].join('.');
109
- this.phyPool[index].ctx.applyEffects({...mutation, path});
110
- } else {
111
- this.phyPool.forEach((i) => {
112
- if (i.index !== null && i.index >= spliceIndex && i.index < this.items.length) {
113
- if (this.items[i.index] instanceof PlaceHolder) this.items.load?.(this.items[i.index]);
114
-
115
- i.ctx.replace(this.items[i.index]);
116
- i.ctx.applyEffects(undefined);
117
- i.ctx._ti.applyBinds();
118
- } else if (i.index >= this.items.length) {
119
- i.index = null;
120
- i.offset = -10000;
121
- fixOffset(i);
122
- }
123
- });
124
- }
109
+ const { index: spliceIndex } = mutation;
110
+ if (Number(spliceIndex) >= 0) {
111
+ // if mutation is not root try to apply effects to children (need when pushing to array inside array)
112
+ if (rest.length > 0) {
113
+ const path = [this.as, ...rest].join('.');
114
+ this.phyPool[index].ctx.applyEffects({ ...mutation, path });
115
+ } else {
116
+ this.phyPool.forEach((i) => {
117
+ if (i.index !== null && i.index >= spliceIndex && i.index < this.items.length) {
118
+ if (this.items[i.index] instanceof PlaceHolder) this.items.load?.(this.items[i.index]);
119
+
120
+ i.ctx.replace(this.items[i.index]);
121
+ i.ctx.applyEffects(undefined);
122
+ i.ctx._ti.applyBinds();
123
+ } else if (i.index >= this.items.length) {
124
+ i.index = null;
125
+ i.offset = -10000;
126
+ fixOffset(i);
127
+ }
128
+ });
129
+ }
125
130
 
126
- // TODO: add more Heuristic to scroll list if visible elements that not changed? like insert rows before
127
- // visible area
131
+ // TODO: add more Heuristic to scroll list if visible elements that not changed? like insert rows before
132
+ // visible area
128
133
 
129
- // refresh all PHY if they can be affected
130
- setTimeout(() => this.render(), 0);
134
+ // refresh all PHY if they can be affected
135
+ setTimeout(() => this.render(), 0);
136
+ }
131
137
 
132
138
  break;
133
139
  }
@@ -136,7 +142,7 @@ class PlVirtualScroll extends PlElement {
136
142
 
137
143
  render() {
138
144
  const canvas = this.canvas;
139
- let visibleStart = canvas.parentNode.scrollTop,
145
+ const visibleStart = canvas.parentNode.scrollTop,
140
146
  height = canvas.parentNode.offsetHeight,
141
147
  visibleEnd = visibleStart + height,
142
148
  // render cant complete on too small window, set minimal shadow window
@@ -161,7 +167,7 @@ class PlVirtualScroll extends PlElement {
161
167
 
162
168
  // check items height and offset
163
169
  if (this.variableRowHeight) {
164
- let firstVisible = used.findIndex(i => i.offset >= visibleStart && i.offset < visibleEnd);
170
+ const firstVisible = used.findIndex(i => i.offset >= visibleStart && i.offset < visibleEnd);
165
171
  if (firstVisible >= 0) {
166
172
  // fix forward
167
173
  for (let i = firstVisible + 1; i < used.length && used[i].offset < shadowEnd; i++) {
@@ -196,16 +202,16 @@ class PlVirtualScroll extends PlElement {
196
202
  }
197
203
  // filter
198
204
 
199
- let unused = this.phyPool.filter(i => i.index === null);
205
+ const unused = this.phyPool.filter(i => i.index === null);
200
206
 
201
207
  let firstShadow = used.find(i => i.offset + i.h > shadowStart && i.offset < shadowEnd);
202
208
  let lastShadow = used.findLast(i => i.offset < shadowEnd && i.offset + i.h > shadowStart);
203
209
 
204
210
  if (!firstShadow && !lastShadow) {
205
211
  // jump to nowhere,
206
- if (this.canvas.parentNode.scrollTop === 0)
212
+ if (this.canvas.parentNode.scrollTop === 0) {
207
213
  firstShadow = lastShadow = this.renderItem(0, unused.pop());
208
- else {
214
+ } else {
209
215
  const heightForStart
210
216
  = this.phyPool.length > 0
211
217
  ? this.phyPool.reduce((a, i) => a + i.h, 0) / this.phyPool.length
@@ -292,7 +298,7 @@ class PlVirtualScroll extends PlElement {
292
298
  return p_item;
293
299
  }
294
300
  if (this.items[index] instanceof PlaceHolder) this.items.load?.(this.items[index]);
295
- let target = p_item ?? this.createNewItem(this.items[index]);
301
+ const target = p_item ?? this.createNewItem(this.items[index]);
296
302
 
297
303
  target.index = index;
298
304
  if (p_item) {
@@ -304,7 +310,7 @@ class PlVirtualScroll extends PlElement {
304
310
  this.phyPool.push(target);
305
311
  }
306
312
  prev ??= 0;
307
- target.offset = typeof (prev) == 'number' ? prev : (backward ? prev.offset - target.h : prev.offset + prev.h);
313
+ target.offset = typeof (prev) === 'number' ? prev : (backward ? prev.offset - target.h : prev.offset + prev.h);
308
314
  target.ctx._ti._nodes.forEach((n) => {
309
315
  if (n.style) {
310
316
  n.style.transform = `translateY(${target.offset}px)`;
@@ -316,12 +322,12 @@ class PlVirtualScroll extends PlElement {
316
322
 
317
323
  createNewItem(v) {
318
324
  if (!this.sTpl) return;
319
- let inst = new TemplateInstance(this.sTpl);
325
+ const inst = new TemplateInstance(this.sTpl);
320
326
 
321
- let ctx = new RepeatItem(v, this.as, (ctx, m) => this.onItemChanged(ctx, m));
327
+ const ctx = new RepeatItem(v, this.as, (ctx, m) => this.onItemChanged(ctx, m));
322
328
  ctx._ti = inst;
323
329
  inst.attach(this.canvas, undefined, [ctx, ...this._hctx]);
324
- let h = !this.variableRowHeight && this.elementHeight ? this.elementHeight : calcNodesRect(inst._nodes).height;
330
+ const h = !this.variableRowHeight && this.elementHeight ? this.elementHeight : calcNodesRect(inst._nodes).height;
325
331
 
326
332
  if (!this.variableRowHeight && !this.elementHeight) {
327
333
  this.elementHeight = h;
@@ -337,7 +343,7 @@ class PlVirtualScroll extends PlElement {
337
343
  onItemChanged(ctx, m) {
338
344
  // skip replace data call
339
345
  if (!m) return;
340
- let ind = this.items.findIndex(i => i === ctx[this.as]);
346
+ const ind = this.items.findIndex(i => i === ctx[this.as]);
341
347
  if (ind < 0) console.warn('repeat item not found');
342
348
  if (m.path === this.as) {
343
349
  this.set(['items', ind], m.value, m.wmh);
@@ -375,7 +381,7 @@ function fixOffset(item) {
375
381
 
376
382
  function calcNodesRect(nodes) {
377
383
  nodes = nodes.filter(n => n.getBoundingClientRect);
378
- let rect = nodes[0].getBoundingClientRect();
384
+ const rect = nodes[0].getBoundingClientRect();
379
385
  let { top, bottom, left, right } = rect;
380
386
  ({ top, bottom, left, right } = nodes.map(n => n.getBoundingClientRect())
381
387
  .filter(i => i)
@@ -385,9 +391,9 @@ function calcNodesRect(nodes) {
385
391
  bottom: Math.max(a.bottom, c.bottom),
386
392
  left: Math.min(a.left, c.left),
387
393
  right: Math.max(a.right, c.right)
388
- })
389
- , { top, bottom, left, right }));
390
- let { x, y, height, width } = { x: left, y: top, width: right - left, height: bottom - top };
394
+ }),
395
+ { top, bottom, left, right }));
396
+ const { x, y, height, width } = { x: left, y: top, width: right - left, height: bottom - top };
391
397
  return { x, y, height, width };
392
398
  }
393
399