@vaadin/component-base 23.1.0-alpha4 → 23.1.0-beta3
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/custom_typings/vaadin.d.ts +3 -3
- package/package.json +2 -2
- package/src/async.d.ts +2 -2
- package/src/browser-utils.js +1 -1
- package/src/element-mixin.js +1 -1
- package/src/focus-mixin.js +2 -2
- package/src/gestures.d.ts +8 -8
- package/src/gestures.js +64 -65
- package/src/iron-list-core.js +82 -82
- package/src/polylit-mixin.js +4 -4
- package/src/resize-mixin.d.ts +6 -0
- package/src/resize-mixin.js +45 -1
- package/src/virtualizer-iron-list-adapter.js +12 -3
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
interface Vaadin {
|
|
2
2
|
developmentModeCallback?: {
|
|
3
|
-
'usage-statistics'
|
|
4
|
-
'vaadin-license-checker'
|
|
3
|
+
'usage-statistics'?(): void;
|
|
4
|
+
'vaadin-license-checker'?(): void;
|
|
5
5
|
};
|
|
6
6
|
registrations?: Array<{ is: string; version: string }>;
|
|
7
7
|
usageStatsChecker?: {
|
|
8
|
-
maybeGatherAndSend
|
|
8
|
+
maybeGatherAndSend(): void;
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/component-base",
|
|
3
|
-
"version": "23.1.0-
|
|
3
|
+
"version": "23.1.0-beta3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
43
43
|
"sinon": "^13.0.2"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "c787ceb8a312f88631c6d429ff320d5f89b1b838"
|
|
46
46
|
}
|
package/src/async.d.ts
CHANGED
package/src/browser-utils.js
CHANGED
|
@@ -16,7 +16,7 @@ export const isChrome = testUserAgent(/Chrome/) && testVendor(/Google Inc/);
|
|
|
16
16
|
|
|
17
17
|
export const isFirefox = testUserAgent(/Firefox/);
|
|
18
18
|
|
|
19
|
-
//
|
|
19
|
+
// IPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
|
|
20
20
|
export const isIPad = testPlatform(/^iPad/) || (testPlatform(/^Mac/) && navigator.maxTouchPoints > 1);
|
|
21
21
|
|
|
22
22
|
export const isIPhone = testPlatform(/^iPhone/);
|
package/src/element-mixin.js
CHANGED
package/src/focus-mixin.js
CHANGED
|
@@ -68,7 +68,7 @@ export const FocusMixin = dedupingMixin(
|
|
|
68
68
|
disconnectedCallback() {
|
|
69
69
|
super.disconnectedCallback();
|
|
70
70
|
|
|
71
|
-
//
|
|
71
|
+
// In non-Chrome browsers, blur does not fire on the element when it is disconnected.
|
|
72
72
|
// reproducible in `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
|
|
73
73
|
if (this.hasAttribute('focused')) {
|
|
74
74
|
this._setFocused(false);
|
|
@@ -84,7 +84,7 @@ export const FocusMixin = dedupingMixin(
|
|
|
84
84
|
_setFocused(focused) {
|
|
85
85
|
this.toggleAttribute('focused', focused);
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// Focus-ring is true when the element was focused from the keyboard.
|
|
88
88
|
// Focus Ring [A11ycasts]: https://youtu.be/ilj2P5-5CjI
|
|
89
89
|
this.toggleAttribute('focus-ring', focused && this._keyboardActive);
|
|
90
90
|
}
|
package/src/gestures.d.ts
CHANGED
|
@@ -65,12 +65,12 @@ export { prevent };
|
|
|
65
65
|
declare function prevent(evName: string): void;
|
|
66
66
|
|
|
67
67
|
export interface GestureRecognizer {
|
|
68
|
-
reset
|
|
69
|
-
mousedown
|
|
70
|
-
mousemove
|
|
71
|
-
mouseup
|
|
72
|
-
touchstart
|
|
73
|
-
touchmove
|
|
74
|
-
touchend
|
|
75
|
-
click
|
|
68
|
+
reset(): void;
|
|
69
|
+
mousedown?(e: MouseEvent): void;
|
|
70
|
+
mousemove?(e: MouseEvent): void;
|
|
71
|
+
mouseup?(e: MouseEvent): void;
|
|
72
|
+
touchstart?(e: TouchEvent): void;
|
|
73
|
+
touchmove?(e: TouchEvent): void;
|
|
74
|
+
touchend?(e: TouchEvent): void;
|
|
75
|
+
click?(e: MouseEvent): void;
|
|
76
76
|
}
|
package/src/gestures.js
CHANGED
|
@@ -26,19 +26,19 @@ import { microTask } from './async.js';
|
|
|
26
26
|
const passiveTouchGestures = false;
|
|
27
27
|
const wrap = (node) => node;
|
|
28
28
|
|
|
29
|
-
//
|
|
29
|
+
// Detect native touch action support
|
|
30
30
|
const HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
|
31
31
|
const GESTURE_KEY = '__polymerGestures';
|
|
32
32
|
const HANDLED_OBJ = '__polymerGesturesHandled';
|
|
33
33
|
const TOUCH_ACTION = '__polymerGesturesTouchAction';
|
|
34
|
-
//
|
|
34
|
+
// Radius for tap and track
|
|
35
35
|
const TAP_DISTANCE = 25;
|
|
36
36
|
const TRACK_DISTANCE = 5;
|
|
37
|
-
//
|
|
37
|
+
// Number of last N track positions to keep
|
|
38
38
|
const TRACK_LENGTH = 2;
|
|
39
39
|
|
|
40
40
|
const MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];
|
|
41
|
-
//
|
|
41
|
+
// An array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons
|
|
42
42
|
const MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];
|
|
43
43
|
const MOUSE_HAS_BUTTONS = (function () {
|
|
44
44
|
try {
|
|
@@ -112,47 +112,47 @@ const canBeDisabled = {
|
|
|
112
112
|
*/
|
|
113
113
|
function hasLeftMouseButton(ev) {
|
|
114
114
|
const type = ev.type;
|
|
115
|
-
//
|
|
115
|
+
// Exit early if the event is not a mouse event
|
|
116
116
|
if (!isMouseEvent(type)) {
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
|
-
//
|
|
119
|
+
// Ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
|
|
120
120
|
// instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)
|
|
121
121
|
if (type === 'mousemove') {
|
|
122
|
-
//
|
|
122
|
+
// Allow undefined for testing events
|
|
123
123
|
let buttons = ev.buttons === undefined ? 1 : ev.buttons;
|
|
124
124
|
if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
|
|
125
125
|
buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
|
|
126
126
|
}
|
|
127
|
-
//
|
|
127
|
+
// Buttons is a bitmask, check that the left button bit is set (1)
|
|
128
128
|
return Boolean(buttons & 1);
|
|
129
129
|
}
|
|
130
|
-
//
|
|
130
|
+
// Allow undefined for testing events
|
|
131
131
|
const button = ev.button === undefined ? 0 : ev.button;
|
|
132
|
-
//
|
|
132
|
+
// Ev.button is 0 in mousedown/mouseup/click for left button activation
|
|
133
133
|
return button === 0;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function isSyntheticClick(ev) {
|
|
137
137
|
if (ev.type === 'click') {
|
|
138
|
-
//
|
|
138
|
+
// Ev.detail is 0 for HTMLElement.click in most browsers
|
|
139
139
|
if (ev.detail === 0) {
|
|
140
140
|
return true;
|
|
141
141
|
}
|
|
142
|
-
//
|
|
142
|
+
// In the worst case, check that the x/y position of the click is within
|
|
143
143
|
// the bounding box of the target of the event
|
|
144
144
|
// Thanks IE 10 >:(
|
|
145
145
|
const t = _findOriginalTarget(ev);
|
|
146
|
-
//
|
|
146
|
+
// Make sure the target of the event is an element so we can use getBoundingClientRect,
|
|
147
147
|
// if not, just assume it is a synthetic click
|
|
148
148
|
if (!t.nodeType || /** @type {Element} */ (t).nodeType !== Node.ELEMENT_NODE) {
|
|
149
149
|
return true;
|
|
150
150
|
}
|
|
151
151
|
const bcr = /** @type {Element} */ (t).getBoundingClientRect();
|
|
152
|
-
//
|
|
152
|
+
// Use page x/y to account for scrolling
|
|
153
153
|
const x = ev.pageX,
|
|
154
154
|
y = ev.pageY;
|
|
155
|
-
//
|
|
155
|
+
// Ev is a synthetic click if the position is outside the bounding box of the target
|
|
156
156
|
return !(x >= bcr.left && x <= bcr.right && y >= bcr.top && y <= bcr.bottom);
|
|
157
157
|
}
|
|
158
158
|
return false;
|
|
@@ -228,14 +228,14 @@ export const recognizers = [];
|
|
|
228
228
|
export function deepTargetFind(x, y) {
|
|
229
229
|
let node = document.elementFromPoint(x, y);
|
|
230
230
|
let next = node;
|
|
231
|
-
//
|
|
231
|
+
// This code path is only taken when native ShadowDOM is used
|
|
232
232
|
// if there is a shadowroot, it may have a node at x/y
|
|
233
233
|
// if there is not a shadowroot, exit the loop
|
|
234
234
|
while (next && next.shadowRoot && !window.ShadyDOM) {
|
|
235
|
-
//
|
|
235
|
+
// If there is a node at x/y in the shadowroot, look deeper
|
|
236
236
|
const oldNext = next;
|
|
237
237
|
next = next.shadowRoot.elementFromPoint(x, y);
|
|
238
|
-
//
|
|
238
|
+
// On Safari, elementFromPoint may return the shadowRoot host
|
|
239
239
|
if (oldNext === next) {
|
|
240
240
|
break;
|
|
241
241
|
}
|
|
@@ -247,7 +247,7 @@ export function deepTargetFind(x, y) {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
|
-
*
|
|
250
|
+
* A cheaper check than ev.composedPath()[0];
|
|
251
251
|
*
|
|
252
252
|
* @private
|
|
253
253
|
* @param {Event|Touch} ev Event.
|
|
@@ -278,10 +278,9 @@ function _handleNative(ev) {
|
|
|
278
278
|
if (!ev[HANDLED_OBJ]) {
|
|
279
279
|
ev[HANDLED_OBJ] = {};
|
|
280
280
|
if (type.slice(0, 5) === 'touch') {
|
|
281
|
-
// ev = /** @type {TouchEvent} */ (ev); // eslint-disable-line no-self-assign
|
|
282
281
|
const t = ev.changedTouches[0];
|
|
283
282
|
if (type === 'touchstart') {
|
|
284
|
-
//
|
|
283
|
+
// Only handle the first finger
|
|
285
284
|
if (ev.touches.length === 1) {
|
|
286
285
|
POINTERSTATE.touch.id = t.identifier;
|
|
287
286
|
}
|
|
@@ -297,11 +296,11 @@ function _handleNative(ev) {
|
|
|
297
296
|
}
|
|
298
297
|
}
|
|
299
298
|
const handled = ev[HANDLED_OBJ];
|
|
300
|
-
//
|
|
299
|
+
// Used to ignore synthetic mouse events
|
|
301
300
|
if (handled.skip) {
|
|
302
301
|
return;
|
|
303
302
|
}
|
|
304
|
-
//
|
|
303
|
+
// Reset recognizer state
|
|
305
304
|
for (let i = 0, r; i < recognizers.length; i++) {
|
|
306
305
|
r = recognizers[i];
|
|
307
306
|
if (gs[r.name] && !handled[r.name]) {
|
|
@@ -310,7 +309,7 @@ function _handleNative(ev) {
|
|
|
310
309
|
}
|
|
311
310
|
}
|
|
312
311
|
}
|
|
313
|
-
//
|
|
312
|
+
// Enforce gesture recognizer order
|
|
314
313
|
for (let i = 0, r; i < recognizers.length; i++) {
|
|
315
314
|
r = recognizers[i];
|
|
316
315
|
if (gs[r.name] && !handled[r.name]) {
|
|
@@ -342,7 +341,7 @@ function _handleTouchAction(ev) {
|
|
|
342
341
|
const dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
|
|
343
342
|
const dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
|
|
344
343
|
if (!ev.cancelable) {
|
|
345
|
-
//
|
|
344
|
+
// Scrolling is happening
|
|
346
345
|
} else if (ta === 'none') {
|
|
347
346
|
shouldPrevent = true;
|
|
348
347
|
} else if (ta === 'pan-x') {
|
|
@@ -392,7 +391,7 @@ export function removeListener(node, evType, handler) {
|
|
|
392
391
|
}
|
|
393
392
|
|
|
394
393
|
/**
|
|
395
|
-
*
|
|
394
|
+
* Automate the event listeners for the native events
|
|
396
395
|
*
|
|
397
396
|
* @private
|
|
398
397
|
* @param {!EventTarget} node Node on which to add the event.
|
|
@@ -410,7 +409,7 @@ function _add(node, evType, handler) {
|
|
|
410
409
|
}
|
|
411
410
|
for (let i = 0, dep, gd; i < deps.length; i++) {
|
|
412
411
|
dep = deps[i];
|
|
413
|
-
//
|
|
412
|
+
// Don't add mouse handlers on iOS because they cause gray selection overlays
|
|
414
413
|
if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') {
|
|
415
414
|
continue;
|
|
416
415
|
}
|
|
@@ -431,7 +430,7 @@ function _add(node, evType, handler) {
|
|
|
431
430
|
}
|
|
432
431
|
|
|
433
432
|
/**
|
|
434
|
-
*
|
|
433
|
+
* Automate event listener removal for native events
|
|
435
434
|
*
|
|
436
435
|
* @private
|
|
437
436
|
* @param {!EventTarget} node Node on which to remove the event.
|
|
@@ -528,7 +527,7 @@ function _fire(target, type, detail) {
|
|
|
528
527
|
const ev = new Event(type, { bubbles: true, cancelable: true, composed: true });
|
|
529
528
|
ev.detail = detail;
|
|
530
529
|
wrap(/** @type {!Node} */ (target)).dispatchEvent(ev);
|
|
531
|
-
//
|
|
530
|
+
// Forward `preventDefault` in a clean way
|
|
532
531
|
if (ev.defaultPrevented) {
|
|
533
532
|
const preventer = detail.preventer || detail.sourceEvent;
|
|
534
533
|
if (preventer && preventer.preventDefault) {
|
|
@@ -568,7 +567,7 @@ register({
|
|
|
568
567
|
* @this {GestureRecognizer}
|
|
569
568
|
* @return {void}
|
|
570
569
|
*/
|
|
571
|
-
reset
|
|
570
|
+
reset() {
|
|
572
571
|
untrackDocument(this.info);
|
|
573
572
|
},
|
|
574
573
|
|
|
@@ -577,7 +576,7 @@ register({
|
|
|
577
576
|
* @param {MouseEvent} e
|
|
578
577
|
* @return {void}
|
|
579
578
|
*/
|
|
580
|
-
mousedown
|
|
579
|
+
mousedown(e) {
|
|
581
580
|
if (!hasLeftMouseButton(e)) {
|
|
582
581
|
return;
|
|
583
582
|
}
|
|
@@ -605,7 +604,7 @@ register({
|
|
|
605
604
|
* @param {TouchEvent} e
|
|
606
605
|
* @return {void}
|
|
607
606
|
*/
|
|
608
|
-
touchstart
|
|
607
|
+
touchstart(e) {
|
|
609
608
|
downupFire('down', _findOriginalTarget(e), e.changedTouches[0], e);
|
|
610
609
|
},
|
|
611
610
|
|
|
@@ -614,7 +613,7 @@ register({
|
|
|
614
613
|
* @param {TouchEvent} e
|
|
615
614
|
* @return {void}
|
|
616
615
|
*/
|
|
617
|
-
touchend
|
|
616
|
+
touchend(e) {
|
|
618
617
|
downupFire('up', _findOriginalTarget(e), e.changedTouches[0], e);
|
|
619
618
|
},
|
|
620
619
|
});
|
|
@@ -634,8 +633,8 @@ function downupFire(type, target, event, preventer) {
|
|
|
634
633
|
x: event.clientX,
|
|
635
634
|
y: event.clientY,
|
|
636
635
|
sourceEvent: event,
|
|
637
|
-
preventer
|
|
638
|
-
prevent
|
|
636
|
+
preventer,
|
|
637
|
+
prevent(e) {
|
|
639
638
|
return prevent(e);
|
|
640
639
|
},
|
|
641
640
|
});
|
|
@@ -658,7 +657,7 @@ register({
|
|
|
658
657
|
started: false,
|
|
659
658
|
moves: [],
|
|
660
659
|
/** @this {GestureInfo} */
|
|
661
|
-
addMove
|
|
660
|
+
addMove(move) {
|
|
662
661
|
if (this.moves.length > TRACK_LENGTH) {
|
|
663
662
|
this.moves.shift();
|
|
664
663
|
}
|
|
@@ -673,7 +672,7 @@ register({
|
|
|
673
672
|
* @this {GestureRecognizer}
|
|
674
673
|
* @return {void}
|
|
675
674
|
*/
|
|
676
|
-
reset
|
|
675
|
+
reset() {
|
|
677
676
|
this.info.state = 'start';
|
|
678
677
|
this.info.started = false;
|
|
679
678
|
this.info.moves = [];
|
|
@@ -688,7 +687,7 @@ register({
|
|
|
688
687
|
* @param {MouseEvent} e
|
|
689
688
|
* @return {void}
|
|
690
689
|
*/
|
|
691
|
-
mousedown
|
|
690
|
+
mousedown(e) {
|
|
692
691
|
if (!hasLeftMouseButton(e)) {
|
|
693
692
|
return;
|
|
694
693
|
}
|
|
@@ -699,15 +698,15 @@ register({
|
|
|
699
698
|
const x = e.clientX,
|
|
700
699
|
y = e.clientY;
|
|
701
700
|
if (trackHasMovedEnough(self.info, x, y)) {
|
|
702
|
-
//
|
|
701
|
+
// First move is 'start', subsequent moves are 'move', mouseup is 'end'
|
|
703
702
|
self.info.state = self.info.started ? (e.type === 'mouseup' ? 'end' : 'track') : 'start';
|
|
704
703
|
if (self.info.state === 'start') {
|
|
705
|
-
//
|
|
704
|
+
// If and only if tracking, always prevent tap
|
|
706
705
|
prevent('tap');
|
|
707
706
|
}
|
|
708
|
-
self.info.addMove({ x
|
|
707
|
+
self.info.addMove({ x, y });
|
|
709
708
|
if (!hasLeftMouseButton(e)) {
|
|
710
|
-
//
|
|
709
|
+
// Always fire "end"
|
|
711
710
|
self.info.state = 'end';
|
|
712
711
|
untrackDocument(self.info);
|
|
713
712
|
}
|
|
@@ -722,10 +721,10 @@ register({
|
|
|
722
721
|
movefn(e);
|
|
723
722
|
}
|
|
724
723
|
|
|
725
|
-
//
|
|
724
|
+
// Remove the temporary listeners
|
|
726
725
|
untrackDocument(self.info);
|
|
727
726
|
};
|
|
728
|
-
//
|
|
727
|
+
// Add temporary document listeners as mouse retargets
|
|
729
728
|
trackDocument(this.info, movefn, upfn);
|
|
730
729
|
this.info.x = e.clientX;
|
|
731
730
|
this.info.y = e.clientY;
|
|
@@ -736,7 +735,7 @@ register({
|
|
|
736
735
|
* @param {TouchEvent} e
|
|
737
736
|
* @return {void}
|
|
738
737
|
*/
|
|
739
|
-
touchstart
|
|
738
|
+
touchstart(e) {
|
|
740
739
|
const ct = e.changedTouches[0];
|
|
741
740
|
this.info.x = ct.clientX;
|
|
742
741
|
this.info.y = ct.clientY;
|
|
@@ -747,17 +746,17 @@ register({
|
|
|
747
746
|
* @param {TouchEvent} e
|
|
748
747
|
* @return {void}
|
|
749
748
|
*/
|
|
750
|
-
touchmove
|
|
749
|
+
touchmove(e) {
|
|
751
750
|
const t = _findOriginalTarget(e);
|
|
752
751
|
const ct = e.changedTouches[0];
|
|
753
752
|
const x = ct.clientX,
|
|
754
753
|
y = ct.clientY;
|
|
755
754
|
if (trackHasMovedEnough(this.info, x, y)) {
|
|
756
755
|
if (this.info.state === 'start') {
|
|
757
|
-
//
|
|
756
|
+
// If and only if tracking, always prevent tap
|
|
758
757
|
prevent('tap');
|
|
759
758
|
}
|
|
760
|
-
this.info.addMove({ x
|
|
759
|
+
this.info.addMove({ x, y });
|
|
761
760
|
trackFire(this.info, t, ct);
|
|
762
761
|
this.info.state = 'track';
|
|
763
762
|
this.info.started = true;
|
|
@@ -769,12 +768,12 @@ register({
|
|
|
769
768
|
* @param {TouchEvent} e
|
|
770
769
|
* @return {void}
|
|
771
770
|
*/
|
|
772
|
-
touchend
|
|
771
|
+
touchend(e) {
|
|
773
772
|
const t = _findOriginalTarget(e);
|
|
774
773
|
const ct = e.changedTouches[0];
|
|
775
|
-
//
|
|
774
|
+
// Only trackend if track was started and not aborted
|
|
776
775
|
if (this.info.started) {
|
|
777
|
-
//
|
|
776
|
+
// Reset started state on up
|
|
778
777
|
this.info.state = 'end';
|
|
779
778
|
this.info.addMove({ x: ct.clientX, y: ct.clientY });
|
|
780
779
|
trackFire(this.info, t, ct);
|
|
@@ -824,12 +823,12 @@ function trackFire(info, target, touch) {
|
|
|
824
823
|
state: info.state,
|
|
825
824
|
x: touch.clientX,
|
|
826
825
|
y: touch.clientY,
|
|
827
|
-
dx
|
|
828
|
-
dy
|
|
829
|
-
ddx
|
|
830
|
-
ddy
|
|
826
|
+
dx,
|
|
827
|
+
dy,
|
|
828
|
+
ddx,
|
|
829
|
+
ddy,
|
|
831
830
|
sourceEvent: touch,
|
|
832
|
-
hover
|
|
831
|
+
hover() {
|
|
833
832
|
return deepTargetFind(touch.clientX, touch.clientY);
|
|
834
833
|
},
|
|
835
834
|
});
|
|
@@ -853,7 +852,7 @@ register({
|
|
|
853
852
|
* @this {GestureRecognizer}
|
|
854
853
|
* @return {void}
|
|
855
854
|
*/
|
|
856
|
-
reset
|
|
855
|
+
reset() {
|
|
857
856
|
this.info.x = NaN;
|
|
858
857
|
this.info.y = NaN;
|
|
859
858
|
this.info.prevent = false;
|
|
@@ -864,7 +863,7 @@ register({
|
|
|
864
863
|
* @param {MouseEvent} e
|
|
865
864
|
* @return {void}
|
|
866
865
|
*/
|
|
867
|
-
mousedown
|
|
866
|
+
mousedown(e) {
|
|
868
867
|
if (hasLeftMouseButton(e)) {
|
|
869
868
|
this.info.x = e.clientX;
|
|
870
869
|
this.info.y = e.clientY;
|
|
@@ -876,7 +875,7 @@ register({
|
|
|
876
875
|
* @param {MouseEvent} e
|
|
877
876
|
* @return {void}
|
|
878
877
|
*/
|
|
879
|
-
click
|
|
878
|
+
click(e) {
|
|
880
879
|
if (hasLeftMouseButton(e)) {
|
|
881
880
|
trackForward(this.info, e);
|
|
882
881
|
}
|
|
@@ -887,7 +886,7 @@ register({
|
|
|
887
886
|
* @param {TouchEvent} e
|
|
888
887
|
* @return {void}
|
|
889
888
|
*/
|
|
890
|
-
touchstart
|
|
889
|
+
touchstart(e) {
|
|
891
890
|
const touch = e.changedTouches[0];
|
|
892
891
|
this.info.x = touch.clientX;
|
|
893
892
|
this.info.y = touch.clientY;
|
|
@@ -898,7 +897,7 @@ register({
|
|
|
898
897
|
* @param {TouchEvent} e
|
|
899
898
|
* @return {void}
|
|
900
899
|
*/
|
|
901
|
-
touchend
|
|
900
|
+
touchend(e) {
|
|
902
901
|
trackForward(this.info, e.changedTouches[0], e);
|
|
903
902
|
},
|
|
904
903
|
});
|
|
@@ -912,20 +911,20 @@ register({
|
|
|
912
911
|
function trackForward(info, e, preventer) {
|
|
913
912
|
const dx = Math.abs(e.clientX - info.x);
|
|
914
913
|
const dy = Math.abs(e.clientY - info.y);
|
|
915
|
-
//
|
|
914
|
+
// Find original target from `preventer` for TouchEvents, or `e` for MouseEvents
|
|
916
915
|
const t = _findOriginalTarget(preventer || e);
|
|
917
916
|
if (!t || (canBeDisabled[/** @type {!HTMLElement} */ (t).localName] && t.hasAttribute('disabled'))) {
|
|
918
917
|
return;
|
|
919
918
|
}
|
|
920
|
-
//
|
|
919
|
+
// Dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`
|
|
921
920
|
if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {
|
|
922
|
-
//
|
|
921
|
+
// Prevent taps from being generated if an event has canceled them
|
|
923
922
|
if (!info.prevent) {
|
|
924
923
|
_fire(t, 'tap', {
|
|
925
924
|
x: e.clientX,
|
|
926
925
|
y: e.clientY,
|
|
927
926
|
sourceEvent: e,
|
|
928
|
-
preventer
|
|
927
|
+
preventer,
|
|
929
928
|
});
|
|
930
929
|
}
|
|
931
930
|
}
|
package/src/iron-list-core.js
CHANGED
|
@@ -166,7 +166,7 @@ export const ironList = {
|
|
|
166
166
|
* The height of the physical content that isn't on the screen.
|
|
167
167
|
*/
|
|
168
168
|
get _hiddenContentSize() {
|
|
169
|
-
|
|
169
|
+
const size = this.grid ? this._physicalRows * this._rowHeight : this._physicalSize;
|
|
170
170
|
return size - this._viewportHeight;
|
|
171
171
|
},
|
|
172
172
|
|
|
@@ -182,7 +182,7 @@ export const ironList = {
|
|
|
182
182
|
* `_physicalStart`.
|
|
183
183
|
*/
|
|
184
184
|
get _maxVirtualStart() {
|
|
185
|
-
|
|
185
|
+
const virtualCount = this._convertIndexToCompleteRow(this._virtualCount);
|
|
186
186
|
return Math.max(0, virtualCount - this._physicalCount);
|
|
187
187
|
},
|
|
188
188
|
|
|
@@ -255,9 +255,9 @@ export const ironList = {
|
|
|
255
255
|
* @type {number}
|
|
256
256
|
*/
|
|
257
257
|
get firstVisibleIndex() {
|
|
258
|
-
|
|
258
|
+
let idx = this._firstVisibleIndexVal;
|
|
259
259
|
if (idx == null) {
|
|
260
|
-
|
|
260
|
+
let physicalOffset = this._physicalTop + this._scrollOffset;
|
|
261
261
|
|
|
262
262
|
idx =
|
|
263
263
|
this._iterateItems((pidx, vidx) => {
|
|
@@ -282,12 +282,12 @@ export const ironList = {
|
|
|
282
282
|
* @type {number}
|
|
283
283
|
*/
|
|
284
284
|
get lastVisibleIndex() {
|
|
285
|
-
|
|
285
|
+
let idx = this._lastVisibleIndexVal;
|
|
286
286
|
if (idx == null) {
|
|
287
287
|
if (this.grid) {
|
|
288
288
|
idx = Math.min(this._virtualCount, this.firstVisibleIndex + this._estRowsInView * this._itemsPerRow - 1);
|
|
289
289
|
} else {
|
|
290
|
-
|
|
290
|
+
let physicalOffset = this._physicalTop + this._scrollOffset;
|
|
291
291
|
this._iterateItems((pidx, vidx) => {
|
|
292
292
|
if (physicalOffset < this._scrollBottom) {
|
|
293
293
|
idx = vidx;
|
|
@@ -323,10 +323,10 @@ export const ironList = {
|
|
|
323
323
|
/**
|
|
324
324
|
* Recycles the physical items when needed.
|
|
325
325
|
*/
|
|
326
|
-
_scrollHandler
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
326
|
+
_scrollHandler() {
|
|
327
|
+
const scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scrollTop));
|
|
328
|
+
let delta = scrollTop - this._scrollPosition;
|
|
329
|
+
const isScrollingDown = delta >= 0;
|
|
330
330
|
// Track the current scroll position.
|
|
331
331
|
this._scrollPosition = scrollTop;
|
|
332
332
|
// Clear indexes for first and last visible indexes.
|
|
@@ -335,7 +335,7 @@ export const ironList = {
|
|
|
335
335
|
// Random access.
|
|
336
336
|
if (Math.abs(delta) > this._physicalSize && this._physicalSize > 0) {
|
|
337
337
|
delta -= this._scrollOffset;
|
|
338
|
-
|
|
338
|
+
const idxAdjustment = Math.round(delta / this._physicalAverage) * this._itemsPerRow;
|
|
339
339
|
this._virtualStart += idxAdjustment;
|
|
340
340
|
this._physicalStart += idxAdjustment;
|
|
341
341
|
// Estimate new physical offset based on the virtual start index.
|
|
@@ -350,7 +350,7 @@ export const ironList = {
|
|
|
350
350
|
);
|
|
351
351
|
this._update();
|
|
352
352
|
} else if (this._physicalCount > 0) {
|
|
353
|
-
|
|
353
|
+
const reusables = this._getReusables(isScrollingDown);
|
|
354
354
|
if (isScrollingDown) {
|
|
355
355
|
this._physicalTop = reusables.physicalTop;
|
|
356
356
|
this._virtualStart += reusables.indexes.length;
|
|
@@ -370,18 +370,18 @@ export const ironList = {
|
|
|
370
370
|
*
|
|
371
371
|
* @param {boolean} fromTop If the potential reusable items are above the scrolling region.
|
|
372
372
|
*/
|
|
373
|
-
_getReusables
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
373
|
+
_getReusables(fromTop) {
|
|
374
|
+
let ith, lastIth, offsetContent, physicalItemHeight;
|
|
375
|
+
const idxs = [];
|
|
376
|
+
const protectedOffsetContent = this._hiddenContentSize * this._ratio;
|
|
377
|
+
const virtualStart = this._virtualStart;
|
|
378
|
+
const virtualEnd = this._virtualEnd;
|
|
379
|
+
const physicalCount = this._physicalCount;
|
|
380
|
+
let top = this._physicalTop + this._scrollOffset;
|
|
381
|
+
const bottom = this._physicalBottom + this._scrollOffset;
|
|
382
382
|
// This may be called outside of a scrollHandler, so use last cached position
|
|
383
|
-
|
|
384
|
-
|
|
383
|
+
const scrollTop = this._scrollPosition;
|
|
384
|
+
const scrollBottom = this._scrollBottom;
|
|
385
385
|
|
|
386
386
|
if (fromTop) {
|
|
387
387
|
ith = this._physicalStart;
|
|
@@ -434,7 +434,7 @@ export const ironList = {
|
|
|
434
434
|
* @param {!Array<number>=} itemSet
|
|
435
435
|
* @param {!Array<number>=} movingUp
|
|
436
436
|
*/
|
|
437
|
-
_update
|
|
437
|
+
_update(itemSet, movingUp) {
|
|
438
438
|
if ((itemSet && itemSet.length === 0) || this._physicalCount === 0) {
|
|
439
439
|
return;
|
|
440
440
|
}
|
|
@@ -444,7 +444,7 @@ export const ironList = {
|
|
|
444
444
|
// Adjust offset after measuring.
|
|
445
445
|
if (movingUp) {
|
|
446
446
|
while (movingUp.length) {
|
|
447
|
-
|
|
447
|
+
const idx = movingUp.pop();
|
|
448
448
|
this._physicalTop -= this._getPhysicalSizeIncrement(idx);
|
|
449
449
|
}
|
|
450
450
|
}
|
|
@@ -452,7 +452,7 @@ export const ironList = {
|
|
|
452
452
|
this._updateScrollerSize();
|
|
453
453
|
},
|
|
454
454
|
|
|
455
|
-
_isClientFull
|
|
455
|
+
_isClientFull() {
|
|
456
456
|
return (
|
|
457
457
|
this._scrollBottom !== 0 &&
|
|
458
458
|
this._physicalBottom - 1 >= this._scrollBottom &&
|
|
@@ -463,33 +463,33 @@ export const ironList = {
|
|
|
463
463
|
/**
|
|
464
464
|
* Increases the pool size.
|
|
465
465
|
*/
|
|
466
|
-
_increasePoolIfNeeded
|
|
467
|
-
|
|
466
|
+
_increasePoolIfNeeded(count) {
|
|
467
|
+
let nextPhysicalCount = this._clamp(
|
|
468
468
|
this._physicalCount + count,
|
|
469
469
|
DEFAULT_PHYSICAL_COUNT,
|
|
470
470
|
this._virtualCount - this._virtualStart,
|
|
471
471
|
);
|
|
472
472
|
nextPhysicalCount = this._convertIndexToCompleteRow(nextPhysicalCount);
|
|
473
473
|
if (this.grid) {
|
|
474
|
-
|
|
474
|
+
const correction = nextPhysicalCount % this._itemsPerRow;
|
|
475
475
|
if (correction && nextPhysicalCount - correction <= this._physicalCount) {
|
|
476
476
|
nextPhysicalCount += this._itemsPerRow;
|
|
477
477
|
}
|
|
478
478
|
nextPhysicalCount -= correction;
|
|
479
479
|
}
|
|
480
|
-
|
|
481
|
-
|
|
480
|
+
const delta = nextPhysicalCount - this._physicalCount;
|
|
481
|
+
let nextIncrease = Math.round(this._physicalCount * 0.5);
|
|
482
482
|
|
|
483
483
|
if (delta < 0) {
|
|
484
484
|
return;
|
|
485
485
|
}
|
|
486
486
|
if (delta > 0) {
|
|
487
|
-
|
|
487
|
+
const ts = window.performance.now();
|
|
488
488
|
// Concat arrays in place.
|
|
489
489
|
[].push.apply(this._physicalItems, this._createPool(delta));
|
|
490
490
|
// Push 0s into physicalSizes. Can't use Array.fill because IE11 doesn't
|
|
491
491
|
// support it.
|
|
492
|
-
for (
|
|
492
|
+
for (let i = 0; i < delta; i++) {
|
|
493
493
|
this._physicalSizes.push(0);
|
|
494
494
|
}
|
|
495
495
|
this._physicalCount += delta;
|
|
@@ -528,12 +528,12 @@ export const ironList = {
|
|
|
528
528
|
/**
|
|
529
529
|
* Renders the a new list.
|
|
530
530
|
*/
|
|
531
|
-
_render
|
|
531
|
+
_render() {
|
|
532
532
|
if (!this.isAttached || !this._isVisible) {
|
|
533
533
|
return;
|
|
534
534
|
}
|
|
535
535
|
if (this._physicalCount !== 0) {
|
|
536
|
-
|
|
536
|
+
const reusables = this._getReusables(true);
|
|
537
537
|
this._physicalTop = reusables.physicalTop;
|
|
538
538
|
this._virtualStart += reusables.indexes.length;
|
|
539
539
|
this._physicalStart += reusables.indexes.length;
|
|
@@ -547,7 +547,7 @@ export const ironList = {
|
|
|
547
547
|
}
|
|
548
548
|
},
|
|
549
549
|
|
|
550
|
-
_gridChanged
|
|
550
|
+
_gridChanged(newGrid, oldGrid) {
|
|
551
551
|
if (typeof oldGrid === 'undefined') {
|
|
552
552
|
return;
|
|
553
553
|
}
|
|
@@ -562,7 +562,7 @@ export const ironList = {
|
|
|
562
562
|
* Called when the items have changed. That is, reassignments
|
|
563
563
|
* to `items`, splices or updates to a single item.
|
|
564
564
|
*/
|
|
565
|
-
_itemsChanged
|
|
565
|
+
_itemsChanged(change) {
|
|
566
566
|
if (change.path === 'items') {
|
|
567
567
|
this._virtualStart = 0;
|
|
568
568
|
this._physicalTop = 0;
|
|
@@ -583,19 +583,19 @@ export const ironList = {
|
|
|
583
583
|
this._adjustVirtualIndex(change.value.indexSplices);
|
|
584
584
|
this._virtualCount = this.items ? this.items.length : 0;
|
|
585
585
|
// Only blur if at least one item is added or removed.
|
|
586
|
-
|
|
586
|
+
const itemAddedOrRemoved = change.value.indexSplices.some((splice) => {
|
|
587
587
|
return splice.addedCount > 0 || splice.removed.length > 0;
|
|
588
588
|
});
|
|
589
589
|
if (itemAddedOrRemoved) {
|
|
590
590
|
// Only blur activeElement if it is a descendant of the list (#505,
|
|
591
591
|
// #507).
|
|
592
|
-
|
|
592
|
+
const activeElement = this._getActiveElement();
|
|
593
593
|
if (this.contains(activeElement)) {
|
|
594
594
|
activeElement.blur();
|
|
595
595
|
}
|
|
596
596
|
}
|
|
597
597
|
// Render only if the affected index is rendered.
|
|
598
|
-
|
|
598
|
+
const affectedIndexRendered = change.value.indexSplices.some((splice) => {
|
|
599
599
|
return splice.index + splice.addedCount >= this._virtualStart && splice.index <= this._virtualEnd;
|
|
600
600
|
});
|
|
601
601
|
if (!this._isClientFull() || affectedIndexRendered) {
|
|
@@ -614,8 +614,8 @@ export const ironList = {
|
|
|
614
614
|
* @param {!function(number, number)} fn
|
|
615
615
|
* @param {!Array<number>=} itemSet
|
|
616
616
|
*/
|
|
617
|
-
_iterateItems
|
|
618
|
-
|
|
617
|
+
_iterateItems(fn, itemSet) {
|
|
618
|
+
let pidx, vidx, rtn, i;
|
|
619
619
|
|
|
620
620
|
if (arguments.length === 2 && itemSet) {
|
|
621
621
|
for (i = 0; i < itemSet.length; i++) {
|
|
@@ -647,7 +647,7 @@ export const ironList = {
|
|
|
647
647
|
* @param {number} pidx Physical index
|
|
648
648
|
* @return {number}
|
|
649
649
|
*/
|
|
650
|
-
_computeVidx
|
|
650
|
+
_computeVidx(pidx) {
|
|
651
651
|
if (pidx >= this._physicalStart) {
|
|
652
652
|
return this._virtualStart + (pidx - this._physicalStart);
|
|
653
653
|
}
|
|
@@ -659,15 +659,15 @@ export const ironList = {
|
|
|
659
659
|
*
|
|
660
660
|
* @param {!Array<number>=} itemSet
|
|
661
661
|
*/
|
|
662
|
-
_updateMetrics
|
|
662
|
+
_updateMetrics(itemSet) {
|
|
663
663
|
// Make sure we distributed all the physical items
|
|
664
664
|
// so we can measure them.
|
|
665
665
|
flush();
|
|
666
666
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
667
|
+
let newPhysicalSize = 0;
|
|
668
|
+
let oldPhysicalSize = 0;
|
|
669
|
+
const prevAvgCount = this._physicalAverageCount;
|
|
670
|
+
const prevPhysicalAvg = this._physicalAverage;
|
|
671
671
|
|
|
672
672
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
673
673
|
this._iterateItems((pidx, vidx) => {
|
|
@@ -696,7 +696,7 @@ export const ironList = {
|
|
|
696
696
|
}
|
|
697
697
|
},
|
|
698
698
|
|
|
699
|
-
_updateGridMetrics
|
|
699
|
+
_updateGridMetrics() {
|
|
700
700
|
this._itemWidth = this._physicalCount > 0 ? this._physicalItems[0].getBoundingClientRect().width : 200;
|
|
701
701
|
this._rowHeight = this._physicalCount > 0 ? this._physicalItems[0].offsetHeight : 200;
|
|
702
702
|
this._itemsPerRow = this._itemWidth ? Math.floor(this._viewportWidth / this._itemWidth) : this._itemsPerRow;
|
|
@@ -705,18 +705,18 @@ export const ironList = {
|
|
|
705
705
|
/**
|
|
706
706
|
* Updates the position of the physical items.
|
|
707
707
|
*/
|
|
708
|
-
_positionItems
|
|
708
|
+
_positionItems() {
|
|
709
709
|
this._adjustScrollPosition();
|
|
710
710
|
|
|
711
|
-
|
|
711
|
+
let y = this._physicalTop;
|
|
712
712
|
|
|
713
713
|
if (this.grid) {
|
|
714
|
-
|
|
715
|
-
|
|
714
|
+
const totalItemWidth = this._itemsPerRow * this._itemWidth;
|
|
715
|
+
const rowOffset = (this._viewportWidth - totalItemWidth) / 2;
|
|
716
716
|
|
|
717
717
|
this._iterateItems((pidx, vidx) => {
|
|
718
|
-
|
|
719
|
-
|
|
718
|
+
const modulus = vidx % this._itemsPerRow;
|
|
719
|
+
let x = Math.floor(modulus * this._itemWidth + rowOffset);
|
|
720
720
|
if (this._isRTL) {
|
|
721
721
|
x *= -1;
|
|
722
722
|
}
|
|
@@ -743,7 +743,7 @@ export const ironList = {
|
|
|
743
743
|
}
|
|
744
744
|
},
|
|
745
745
|
|
|
746
|
-
_getPhysicalSizeIncrement
|
|
746
|
+
_getPhysicalSizeIncrement(pidx) {
|
|
747
747
|
if (!this.grid) {
|
|
748
748
|
return this._physicalSizes[pidx];
|
|
749
749
|
}
|
|
@@ -761,22 +761,22 @@ export const ironList = {
|
|
|
761
761
|
* @param {number} vidx Virtual index
|
|
762
762
|
* @return {boolean}
|
|
763
763
|
*/
|
|
764
|
-
_shouldRenderNextRow
|
|
764
|
+
_shouldRenderNextRow(vidx) {
|
|
765
765
|
return vidx % this._itemsPerRow === this._itemsPerRow - 1;
|
|
766
766
|
},
|
|
767
767
|
|
|
768
768
|
/**
|
|
769
769
|
* Adjusts the scroll position when it was overestimated.
|
|
770
770
|
*/
|
|
771
|
-
_adjustScrollPosition
|
|
772
|
-
|
|
771
|
+
_adjustScrollPosition() {
|
|
772
|
+
const deltaHeight =
|
|
773
773
|
this._virtualStart === 0 ? this._physicalTop : Math.min(this._scrollPosition + this._physicalTop, 0);
|
|
774
774
|
// Note: the delta can be positive or negative.
|
|
775
775
|
if (deltaHeight !== 0) {
|
|
776
776
|
this._physicalTop -= deltaHeight;
|
|
777
777
|
// This may be called outside of a scrollHandler, so use last cached position
|
|
778
|
-
|
|
779
|
-
//
|
|
778
|
+
const scrollTop = this._scrollPosition;
|
|
779
|
+
// Juking scroll position during interial scrolling on iOS is no bueno
|
|
780
780
|
if (!IOS_TOUCH_SCROLLING && scrollTop > 0) {
|
|
781
781
|
this._resetScrollPosition(scrollTop - deltaHeight);
|
|
782
782
|
}
|
|
@@ -786,7 +786,7 @@ export const ironList = {
|
|
|
786
786
|
/**
|
|
787
787
|
* Sets the position of the scroll.
|
|
788
788
|
*/
|
|
789
|
-
_resetScrollPosition
|
|
789
|
+
_resetScrollPosition(pos) {
|
|
790
790
|
if (this.scrollTarget && pos >= 0) {
|
|
791
791
|
this._scrollTop = pos;
|
|
792
792
|
this._scrollPosition = this._scrollTop;
|
|
@@ -798,7 +798,7 @@ export const ironList = {
|
|
|
798
798
|
*
|
|
799
799
|
* @param {boolean=} forceUpdate If true, updates the height no matter what.
|
|
800
800
|
*/
|
|
801
|
-
_updateScrollerSize
|
|
801
|
+
_updateScrollerSize(forceUpdate) {
|
|
802
802
|
if (this.grid) {
|
|
803
803
|
this._estScrollHeight = this._virtualRowCount * this._rowHeight;
|
|
804
804
|
} else {
|
|
@@ -823,7 +823,7 @@ export const ironList = {
|
|
|
823
823
|
* @method scrollToIndex
|
|
824
824
|
* @param {number} idx The index of the item
|
|
825
825
|
*/
|
|
826
|
-
scrollToIndex
|
|
826
|
+
scrollToIndex(idx) {
|
|
827
827
|
if (typeof idx !== 'number' || idx < 0 || idx > this.items.length - 1) {
|
|
828
828
|
return;
|
|
829
829
|
}
|
|
@@ -843,11 +843,11 @@ export const ironList = {
|
|
|
843
843
|
// Estimate new physical offset.
|
|
844
844
|
this._physicalTop = Math.floor(this._virtualStart / this._itemsPerRow) * this._physicalAverage;
|
|
845
845
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
//
|
|
846
|
+
let currentTopItem = this._physicalStart;
|
|
847
|
+
let currentVirtualItem = this._virtualStart;
|
|
848
|
+
let targetOffsetTop = 0;
|
|
849
|
+
const hiddenContentSize = this._hiddenContentSize;
|
|
850
|
+
// Scroll to the item as much as we can.
|
|
851
851
|
while (currentVirtualItem < idx && targetOffsetTop <= hiddenContentSize) {
|
|
852
852
|
targetOffsetTop += this._getPhysicalSizeIncrement(currentTopItem);
|
|
853
853
|
currentTopItem = (currentTopItem + 1) % this._physicalCount;
|
|
@@ -857,7 +857,7 @@ export const ironList = {
|
|
|
857
857
|
this._positionItems();
|
|
858
858
|
this._resetScrollPosition(this._physicalTop + this._scrollOffset + targetOffsetTop);
|
|
859
859
|
this._increasePoolIfNeeded(0);
|
|
860
|
-
//
|
|
860
|
+
// Clear cached visible index.
|
|
861
861
|
this._firstVisibleIndexVal = null;
|
|
862
862
|
this._lastVisibleIndexVal = null;
|
|
863
863
|
},
|
|
@@ -865,7 +865,7 @@ export const ironList = {
|
|
|
865
865
|
/**
|
|
866
866
|
* Reset the physical average and the average count.
|
|
867
867
|
*/
|
|
868
|
-
_resetAverage
|
|
868
|
+
_resetAverage() {
|
|
869
869
|
this._physicalAverage = 0;
|
|
870
870
|
this._physicalAverageCount = 0;
|
|
871
871
|
},
|
|
@@ -874,11 +874,11 @@ export const ironList = {
|
|
|
874
874
|
* A handler for the `iron-resize` event triggered by `IronResizableBehavior`
|
|
875
875
|
* when the element is resized.
|
|
876
876
|
*/
|
|
877
|
-
_resizeHandler
|
|
877
|
+
_resizeHandler() {
|
|
878
878
|
this._debounce(
|
|
879
879
|
'_render',
|
|
880
880
|
() => {
|
|
881
|
-
//
|
|
881
|
+
// Clear cached visible index.
|
|
882
882
|
this._firstVisibleIndexVal = null;
|
|
883
883
|
this._lastVisibleIndexVal = null;
|
|
884
884
|
if (this._isVisible) {
|
|
@@ -902,7 +902,7 @@ export const ironList = {
|
|
|
902
902
|
* @method updateSizeForItem
|
|
903
903
|
* @param {Object} item The item instance.
|
|
904
904
|
*/
|
|
905
|
-
updateSizeForItem
|
|
905
|
+
updateSizeForItem(item) {
|
|
906
906
|
return this.updateSizeForIndex(this.items.indexOf(item));
|
|
907
907
|
},
|
|
908
908
|
|
|
@@ -912,7 +912,7 @@ export const ironList = {
|
|
|
912
912
|
* @method updateSizeForIndex
|
|
913
913
|
* @param {number} index The index of the item in the items array.
|
|
914
914
|
*/
|
|
915
|
-
updateSizeForIndex
|
|
915
|
+
updateSizeForIndex(index) {
|
|
916
916
|
if (!this._isIndexRendered(index)) {
|
|
917
917
|
return null;
|
|
918
918
|
}
|
|
@@ -925,29 +925,29 @@ export const ironList = {
|
|
|
925
925
|
* Converts a random index to the index of the item that completes it's row.
|
|
926
926
|
* Allows for better order and fill computation when grid == true.
|
|
927
927
|
*/
|
|
928
|
-
_convertIndexToCompleteRow
|
|
929
|
-
//
|
|
928
|
+
_convertIndexToCompleteRow(idx) {
|
|
929
|
+
// When grid == false _itemPerRow can be unset.
|
|
930
930
|
this._itemsPerRow = this._itemsPerRow || 1;
|
|
931
931
|
return this.grid ? Math.ceil(idx / this._itemsPerRow) * this._itemsPerRow : idx;
|
|
932
932
|
},
|
|
933
933
|
|
|
934
|
-
_isIndexRendered
|
|
934
|
+
_isIndexRendered(idx) {
|
|
935
935
|
return idx >= this._virtualStart && idx <= this._virtualEnd;
|
|
936
936
|
},
|
|
937
937
|
|
|
938
|
-
_isIndexVisible
|
|
938
|
+
_isIndexVisible(idx) {
|
|
939
939
|
return idx >= this.firstVisibleIndex && idx <= this.lastVisibleIndex;
|
|
940
940
|
},
|
|
941
941
|
|
|
942
|
-
_getPhysicalIndex
|
|
942
|
+
_getPhysicalIndex(vidx) {
|
|
943
943
|
return (this._physicalStart + (vidx - this._virtualStart)) % this._physicalCount;
|
|
944
944
|
},
|
|
945
945
|
|
|
946
|
-
_clamp
|
|
946
|
+
_clamp(v, min, max) {
|
|
947
947
|
return Math.min(max, Math.max(min, v));
|
|
948
948
|
},
|
|
949
949
|
|
|
950
|
-
_debounce
|
|
950
|
+
_debounce(name, cb, asyncModule) {
|
|
951
951
|
this._debouncers = this._debouncers || {};
|
|
952
952
|
this._debouncers[name] = Debouncer.debounce(this._debouncers[name], asyncModule, cb.bind(this));
|
|
953
953
|
enqueueDebouncer(this._debouncers[name]);
|
package/src/polylit-mixin.js
CHANGED
|
@@ -32,7 +32,7 @@ function parseObserver(observerString) {
|
|
|
32
32
|
|
|
33
33
|
function getOrCreateMap(obj, name) {
|
|
34
34
|
if (!Object.prototype.hasOwnProperty.call(obj, name)) {
|
|
35
|
-
//
|
|
35
|
+
// Clone any existing entries (superclasses)
|
|
36
36
|
obj[name] = new Map(obj[name]);
|
|
37
37
|
}
|
|
38
38
|
return obj[name];
|
|
@@ -123,7 +123,7 @@ const PolylitMixinImplementation = (superclass) => {
|
|
|
123
123
|
if (options.observer) {
|
|
124
124
|
const method = options.observer;
|
|
125
125
|
|
|
126
|
-
//
|
|
126
|
+
// Set this method
|
|
127
127
|
this.getOrCreateMap('__observers').set(name, method);
|
|
128
128
|
|
|
129
129
|
this.addCheckedInitializer((instance) => {
|
|
@@ -138,12 +138,12 @@ const PolylitMixinImplementation = (superclass) => {
|
|
|
138
138
|
this.__notifyProps = new Set();
|
|
139
139
|
// eslint-disable-next-line no-prototype-builtins
|
|
140
140
|
} else if (!this.hasOwnProperty('__notifyProps')) {
|
|
141
|
-
//
|
|
141
|
+
// Clone any existing observers (superclasses)
|
|
142
142
|
const notifyProps = this.__notifyProps;
|
|
143
143
|
this.__notifyProps = new Set(notifyProps);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
//
|
|
146
|
+
// Set this method
|
|
147
147
|
this.__notifyProps.add(name);
|
|
148
148
|
}
|
|
149
149
|
|
package/src/resize-mixin.d.ts
CHANGED
|
@@ -16,4 +16,10 @@ export declare class ResizeMixinClass {
|
|
|
16
16
|
* Override the method to implement your own behavior.
|
|
17
17
|
*/
|
|
18
18
|
protected _onResize(contentRect: DOMRect): void;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* When true, the parent element resize will be also observed.
|
|
22
|
+
* Override this getter and return `true` to enable this.
|
|
23
|
+
*/
|
|
24
|
+
protected readonly _observeParent: boolean;
|
|
19
25
|
}
|
package/src/resize-mixin.js
CHANGED
|
@@ -8,7 +8,14 @@ import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
|
8
8
|
const observer = new ResizeObserver((entries) => {
|
|
9
9
|
setTimeout(() => {
|
|
10
10
|
entries.forEach((entry) => {
|
|
11
|
-
|
|
11
|
+
// Notify child resizables, if any
|
|
12
|
+
if (entry.target.resizables) {
|
|
13
|
+
entry.target.resizables.forEach((resizable) => {
|
|
14
|
+
resizable._onResize(entry.contentRect);
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
entry.target._onResize(entry.contentRect);
|
|
18
|
+
}
|
|
12
19
|
});
|
|
13
20
|
});
|
|
14
21
|
});
|
|
@@ -25,12 +32,49 @@ export const ResizeMixin = dedupingMixin(
|
|
|
25
32
|
connectedCallback() {
|
|
26
33
|
super.connectedCallback();
|
|
27
34
|
observer.observe(this);
|
|
35
|
+
|
|
36
|
+
if (this._observeParent) {
|
|
37
|
+
const parent = this.parentNode instanceof ShadowRoot ? this.parentNode.host : this.parentNode;
|
|
38
|
+
|
|
39
|
+
if (!parent.resizables) {
|
|
40
|
+
parent.resizables = new Set();
|
|
41
|
+
observer.observe(parent);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
parent.resizables.add(this);
|
|
45
|
+
this.__parent = parent;
|
|
46
|
+
}
|
|
28
47
|
}
|
|
29
48
|
|
|
30
49
|
/** @protected */
|
|
31
50
|
disconnectedCallback() {
|
|
32
51
|
super.disconnectedCallback();
|
|
33
52
|
observer.unobserve(this);
|
|
53
|
+
|
|
54
|
+
const parent = this.__parent;
|
|
55
|
+
if (this._observeParent && parent) {
|
|
56
|
+
const resizables = parent.resizables;
|
|
57
|
+
|
|
58
|
+
if (resizables) {
|
|
59
|
+
resizables.delete(this);
|
|
60
|
+
|
|
61
|
+
if (resizables.size === 0) {
|
|
62
|
+
observer.unobserve(parent);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.__parent = null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* When true, the parent element resize will be also observed.
|
|
72
|
+
* Override this getter and return `true` to enable this.
|
|
73
|
+
*
|
|
74
|
+
* @protected
|
|
75
|
+
*/
|
|
76
|
+
get _observeParent() {
|
|
77
|
+
return false;
|
|
34
78
|
}
|
|
35
79
|
|
|
36
80
|
/**
|
|
@@ -8,7 +8,7 @@ import { isSafari } from './browser-utils.js';
|
|
|
8
8
|
import { Debouncer, flush } from './debounce.js';
|
|
9
9
|
import { ironList } from './iron-list-core.js';
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// Iron-list can by default handle sizes up to around 100000.
|
|
12
12
|
// When the size is larger than MAX_VIRTUAL_COUNT _vidxOffset is used
|
|
13
13
|
const MAX_VIRTUAL_COUNT = 100000;
|
|
14
14
|
const OFFSET_ADJUST_MIN_THRESHOLD = 1000;
|
|
@@ -172,8 +172,8 @@ export class IronListAdapter {
|
|
|
172
172
|
this.__preventElementUpdates = true;
|
|
173
173
|
|
|
174
174
|
// Record the scroll position before changing the size
|
|
175
|
-
let fvi; //
|
|
176
|
-
let fviOffsetBefore; //
|
|
175
|
+
let fvi; // First visible index
|
|
176
|
+
let fviOffsetBefore; // Scroll offset of the first visible index
|
|
177
177
|
if (size > 0) {
|
|
178
178
|
fvi = this.adjustedFirstVisibleIndex;
|
|
179
179
|
fviOffsetBefore = this.__getIndexScrollOffset(fvi);
|
|
@@ -304,6 +304,15 @@ export class IronListAdapter {
|
|
|
304
304
|
|
|
305
305
|
super._scrollHandler();
|
|
306
306
|
|
|
307
|
+
if (this._physicalCount !== 0) {
|
|
308
|
+
// After running super._scrollHandler, fix _virtualStart to workaround an iron-list issue.
|
|
309
|
+
// See https://github.com/vaadin/web-components/issues/1691
|
|
310
|
+
const reusables = this._getReusables(true);
|
|
311
|
+
this._physicalTop = reusables.physicalTop;
|
|
312
|
+
this._virtualStart += reusables.indexes.length;
|
|
313
|
+
this._physicalStart += reusables.indexes.length;
|
|
314
|
+
}
|
|
315
|
+
|
|
307
316
|
if (this.reorderElements) {
|
|
308
317
|
this.__scrollReorderDebouncer = Debouncer.debounce(
|
|
309
318
|
this.__scrollReorderDebouncer,
|