@thinkpixellab-public/px-vue 5.2.0 → 5.3.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.
- package/bases/PxBaseActiveTab.vue +2 -2
- package/bases/PxBaseScroll.vue +13 -3
- package/components/PxBackgroundFader.vue +1 -1
- package/components/PxCardGrid.vue +1 -1
- package/components/PxColorPanel.vue +1 -1
- package/components/PxGsapScrubber.vue +1 -1
- package/components/PxMenu.vue +5 -5
- package/components/PxSlides.vue +1 -1
- package/components/PxSticky.vue +1 -1
- package/components/PxSyncHeight.vue +1 -1
- package/components/PxToolPanel.vue +3 -3
- package/components/PxTransitionExpand.vue +2 -2
- package/composables/useVModelRef.js +4 -5
- package/package.json +3 -3
- package/plugins/common-client.js +29 -0
- package/plugins/filters/spacenator.js +3 -0
- package/plugins/filters/striphtml.js +8 -5
- package/utils/balanceText.js +0 -68
- package/utils/caretPosition.js +2 -4
- package/utils/drag.js +1 -3
- package/utils/scrollWatcher.js +3 -0
- package/utils/svgIcons.js +43 -47
- package/utils/tween.js +7 -5
- package/utils/uniqueId.js +0 -4
- package/utils/utils.js +7 -2
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
return { isBrowserTabActive: false, browserTabActivationCount: 0 };
|
|
14
14
|
},
|
|
15
15
|
mounted() {
|
|
16
|
-
if (typeof document
|
|
16
|
+
if (typeof document === 'undefined') {
|
|
17
17
|
console.warn('Unable to create visibility change listener. No document object.');
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
@@ -21,7 +21,7 @@ export default {
|
|
|
21
21
|
document.addEventListener('visibilitychange', this.onTabVisibilityChange);
|
|
22
22
|
this.onTabVisibilityChange();
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
beforeUnmount() {
|
|
25
25
|
document.removeEventListener('visibilitychange', this.onTabVisibilityChange);
|
|
26
26
|
},
|
|
27
27
|
methods: {
|
package/bases/PxBaseScroll.vue
CHANGED
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
computed: {
|
|
14
14
|
scrollingElement() {
|
|
15
15
|
// derived classes can return something here to watch somethign other than document
|
|
16
|
-
return window !== undefined ? window : null;
|
|
16
|
+
return typeof window !== 'undefined' ? window : null;
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
// watch: {},
|
|
@@ -22,7 +22,8 @@ export default {
|
|
|
22
22
|
let scroller = this.scrollingElement;
|
|
23
23
|
let ticking = false;
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
this._scroller = scroller;
|
|
26
|
+
this._scrollHandler = () => {
|
|
26
27
|
this.scrollPosition.x = scroller.scrollX;
|
|
27
28
|
this.scrollPosition.y = scroller.scrollY;
|
|
28
29
|
|
|
@@ -34,7 +35,16 @@ export default {
|
|
|
34
35
|
|
|
35
36
|
ticking = true;
|
|
36
37
|
}
|
|
37
|
-
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
scroller.addEventListener('scroll', this._scrollHandler);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
beforeUnmount() {
|
|
44
|
+
if (this._scroller && this._scrollHandler) {
|
|
45
|
+
this._scroller.removeEventListener('scroll', this._scrollHandler);
|
|
46
|
+
this._scroller = null;
|
|
47
|
+
this._scrollHandler = null;
|
|
38
48
|
}
|
|
39
49
|
},
|
|
40
50
|
methods: {
|
package/components/PxMenu.vue
CHANGED
|
@@ -184,11 +184,11 @@ const menuDirective = createDirective('click');
|
|
|
184
184
|
|
|
185
185
|
export {
|
|
186
186
|
PxMenu as default,
|
|
187
|
-
PxMenu
|
|
188
|
-
createDirective
|
|
189
|
-
contextMenuDirective
|
|
190
|
-
menuDirective
|
|
191
|
-
clickDirective
|
|
187
|
+
PxMenu,
|
|
188
|
+
createDirective,
|
|
189
|
+
contextMenuDirective,
|
|
190
|
+
menuDirective,
|
|
191
|
+
clickDirective,
|
|
192
192
|
};
|
|
193
193
|
</script>
|
|
194
194
|
|
package/components/PxSlides.vue
CHANGED
package/components/PxSticky.vue
CHANGED
|
@@ -202,12 +202,12 @@ export default {
|
|
|
202
202
|
y: 0,
|
|
203
203
|
width: null,
|
|
204
204
|
height: null,
|
|
205
|
-
...
|
|
205
|
+
...this.bounds,
|
|
206
206
|
};
|
|
207
207
|
this.ready = true;
|
|
208
208
|
});
|
|
209
209
|
},
|
|
210
|
-
|
|
210
|
+
beforeUnmount() {
|
|
211
211
|
this.removeContainerResizeHandlers();
|
|
212
212
|
if (this.dragHandler) {
|
|
213
213
|
this.dragHandler.disabled = true;
|
|
@@ -306,7 +306,7 @@ export default {
|
|
|
306
306
|
|
|
307
307
|
removeContainerResizeHandlers() {
|
|
308
308
|
if (this.teleportToBody) {
|
|
309
|
-
window.removeEventListener('resize', this.
|
|
309
|
+
window.removeEventListener('resize', this.updateContainerSize);
|
|
310
310
|
} else if (this.resizeObserver) {
|
|
311
311
|
this.resizeObserver.disconnect();
|
|
312
312
|
this.resizeObserver = null;
|
|
@@ -55,7 +55,7 @@ export default {
|
|
|
55
55
|
element.style.opacity = null;
|
|
56
56
|
|
|
57
57
|
// force repaint
|
|
58
|
-
getComputedStyle(element).height;
|
|
58
|
+
void getComputedStyle(element).height;
|
|
59
59
|
|
|
60
60
|
// trigger the animation
|
|
61
61
|
//setTimeout(() => {
|
|
@@ -76,7 +76,7 @@ export default {
|
|
|
76
76
|
element.style.opacity = 0;
|
|
77
77
|
|
|
78
78
|
// force repaint
|
|
79
|
-
getComputedStyle(element).height;
|
|
79
|
+
void getComputedStyle(element).height;
|
|
80
80
|
|
|
81
81
|
//setTimeout(() => {
|
|
82
82
|
element.style.height = 0;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { ref, watch } from 'vue';
|
|
2
2
|
|
|
3
3
|
export default function useVModelRef(props, propName, emit) {
|
|
4
|
-
if (!props
|
|
4
|
+
if (!(propName in props)) {
|
|
5
5
|
console.error(`The prop ${propName} is required for the useVModel composable.`);
|
|
6
6
|
return null;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
const propRef = ref(prop);
|
|
9
|
+
const propRef = ref(props[propName]);
|
|
11
10
|
const emitName = `update:${propName}`;
|
|
12
11
|
|
|
13
12
|
watch(
|
|
14
|
-
() =>
|
|
13
|
+
() => props[propName],
|
|
15
14
|
nv => {
|
|
16
|
-
|
|
15
|
+
propRef.value = nv;
|
|
17
16
|
},
|
|
18
17
|
);
|
|
19
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thinkpixellab-public/px-vue",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.1",
|
|
4
4
|
"description": "General purpose Vue components and helpers that can be used across projects.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Pixel Lab"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@floating-ui/dom": "^1.7.6",
|
|
46
46
|
"@popperjs/core": "^2.11.8",
|
|
47
|
-
"@thinkpixellab-public/px-styles": "^4.2.
|
|
47
|
+
"@thinkpixellab-public/px-styles": "^4.2.2",
|
|
48
48
|
"@thinkpixellab-public/px-vue-tester": "^2.0.0",
|
|
49
49
|
"body-scroll-lock": "^3.1.5",
|
|
50
50
|
"chrono-node": "^2.9.1",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
72
72
|
"@vue/test-utils": "^2.4.11",
|
|
73
73
|
"@vueless/storybook-dark-mode": "^10.0.8",
|
|
74
|
-
"chromatic": "^17.
|
|
74
|
+
"chromatic": "^17.3.0",
|
|
75
75
|
"jsdom": "^29.1.1",
|
|
76
76
|
"oxfmt": "^0.53.0",
|
|
77
77
|
"oxlint": "^1.68.0",
|
package/plugins/common-client.js
CHANGED
|
@@ -10,12 +10,41 @@ export default {
|
|
|
10
10
|
$eventBus.emit(eventName, values);
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// Track each handler against the component instance that registered it
|
|
14
|
+
// (when called as `this.$globalOn(...)`, `this` is that instance) so it
|
|
15
|
+
// can be removed automatically on unmount. Without this, component-scoped
|
|
16
|
+
// subscriptions leak — they survive unmount and keep firing on dead
|
|
17
|
+
// instances across client-side navigation. This plugin is client-only
|
|
18
|
+
// ($globalOn is undefined on the server), so none of this runs in SSR.
|
|
13
19
|
app.config.globalProperties.$globalOn = function (eventName, fn) {
|
|
14
20
|
$eventBus.on(eventName, fn);
|
|
21
|
+
if (this) {
|
|
22
|
+
(this.__globalBusHandlers ??= []).push([eventName, fn]);
|
|
23
|
+
}
|
|
15
24
|
};
|
|
16
25
|
|
|
17
26
|
app.config.globalProperties.$globalOff = function (eventName, fn) {
|
|
18
27
|
$eventBus.off(eventName, fn);
|
|
28
|
+
// keep the per-instance tracking in sync with manual removals
|
|
29
|
+
if (this && this.__globalBusHandlers) {
|
|
30
|
+
this.__globalBusHandlers = this.__globalBusHandlers.filter(
|
|
31
|
+
([e, f]) => !(e === eventName && (fn === undefined || f === fn)),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
19
34
|
};
|
|
35
|
+
|
|
36
|
+
// Auto-remove a component's bus handlers when it unmounts, by reference,
|
|
37
|
+
// so only that instance's subscriptions are cleaned up.
|
|
38
|
+
app.mixin({
|
|
39
|
+
beforeUnmount() {
|
|
40
|
+
const handlers = this.__globalBusHandlers;
|
|
41
|
+
if (handlers) {
|
|
42
|
+
for (const [eventName, fn] of handlers) {
|
|
43
|
+
$eventBus.off(eventName, fn);
|
|
44
|
+
}
|
|
45
|
+
this.__globalBusHandlers = null;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
20
49
|
},
|
|
21
50
|
};
|
|
@@ -4,11 +4,14 @@ export default val => {
|
|
|
4
4
|
val = val.replace(/<\/li>/g, '</li> ');
|
|
5
5
|
val = val.replace(/<\/div>/g, '</div> ');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
// Parse into a <template>: its content is an inert fragment, so
|
|
8
|
+
// <img onerror> and other resource loads never fire the way they do
|
|
9
|
+
// when innerHTML is set on a live element. Fragment parsing (unlike
|
|
10
|
+
// DOMParser's full-document parse) keeps leading/trailing whitespace,
|
|
11
|
+
// which callers rely on when stripping per-fragment and joining.
|
|
12
|
+
const tpl = document.createElement('template');
|
|
13
|
+
tpl.innerHTML = val;
|
|
14
|
+
const text = (tpl.content.textContent || '').replace(/(\n)+/g, ' ');
|
|
12
15
|
|
|
13
16
|
return text;
|
|
14
17
|
} else {
|
package/utils/balanceText.js
CHANGED
|
@@ -90,72 +90,4 @@ function textElementIsMultipleLines(element) {
|
|
|
90
90
|
return actualHeight > expectedSingleLineHeight + buffer;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// Function to see if a headline is multiple lines we only want to break if the headline is multiple
|
|
94
|
-
// lines. We achieve this by turning the first word into a span and then we compare the height of
|
|
95
|
-
// that span to the height of the entire headline. If the headline is bigger than the span by 10px
|
|
96
|
-
// we balance the headline.
|
|
97
|
-
function textElementIsMultipleLinesLEGACY(element) {
|
|
98
|
-
if (!element) {
|
|
99
|
-
console.warn('textElementIsMultipleLines called with no element');
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// try to move deeper into the element
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
if (element.nodeType == 1) {
|
|
107
|
-
while (element.firstChild && element.firstChild.nodeType == 1) {
|
|
108
|
-
element = element.firstChild;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
var firstWordHeight;
|
|
116
|
-
var elementHeight;
|
|
117
|
-
var HEIGHT_OFFSET;
|
|
118
|
-
var elementWords;
|
|
119
|
-
var firstWord;
|
|
120
|
-
var ORIGINAL_ELEMENT_TEXT;
|
|
121
|
-
|
|
122
|
-
ORIGINAL_ELEMENT_TEXT = element.innerHTML;
|
|
123
|
-
|
|
124
|
-
// Usually there is around a 5px discrepency between the first word and the height of the whole
|
|
125
|
-
// headline so subtract the height of the headline by 10 px and we should be good
|
|
126
|
-
HEIGHT_OFFSET = 10;
|
|
127
|
-
|
|
128
|
-
// Get all the words in the headline as an array -- will include punctuatio. This is used to put
|
|
129
|
-
// the headline back together
|
|
130
|
-
elementWords = element.innerHTML.split(' ');
|
|
131
|
-
|
|
132
|
-
// Make span for first word and give it an id so we can access it in le dom
|
|
133
|
-
firstWord = document.createElement('span');
|
|
134
|
-
firstWord.id = 'element-first-word';
|
|
135
|
-
firstWord.innerHTML = elementWords[0];
|
|
136
|
-
|
|
137
|
-
// This is the entire headline as an array except for first word. We will append it to the
|
|
138
|
-
// headline after the span
|
|
139
|
-
elementWords = elementWords.slice(1);
|
|
140
|
-
|
|
141
|
-
// Empty the headline and append the span to it
|
|
142
|
-
element.innerHTML = '';
|
|
143
|
-
element.appendChild(firstWord);
|
|
144
|
-
|
|
145
|
-
// Add the rest of the element back to it
|
|
146
|
-
element.innerHTML += ' ' + elementWords.join(' ');
|
|
147
|
-
|
|
148
|
-
// Update the first word variable in the dom
|
|
149
|
-
firstWord = document.getElementById('element-first-word');
|
|
150
|
-
|
|
151
|
-
firstWordHeight = firstWord?.offsetHeight;
|
|
152
|
-
elementHeight = element?.offsetHeight;
|
|
153
|
-
|
|
154
|
-
// Restore the original element text
|
|
155
|
-
element.innerHTML = ORIGINAL_ELEMENT_TEXT;
|
|
156
|
-
|
|
157
|
-
// Compare the height of the element and the height of the first word
|
|
158
|
-
return elementHeight - HEIGHT_OFFSET > firstWordHeight;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
93
|
export default balanceText;
|
package/utils/caretPosition.js
CHANGED
|
@@ -31,10 +31,8 @@ function createRange(node, endPos) {
|
|
|
31
31
|
function canProceed(element) {
|
|
32
32
|
if (
|
|
33
33
|
!element ||
|
|
34
|
-
|
|
35
|
-
typeof
|
|
36
|
-
!document ||
|
|
37
|
-
typeof document == undefined ||
|
|
34
|
+
typeof window === 'undefined' ||
|
|
35
|
+
typeof document === 'undefined' ||
|
|
38
36
|
!element.contains(document.activeElement)
|
|
39
37
|
) {
|
|
40
38
|
return false;
|
package/utils/drag.js
CHANGED
|
@@ -48,7 +48,7 @@ function Drag(element, options) {
|
|
|
48
48
|
|
|
49
49
|
// touch support test
|
|
50
50
|
this.supportsTouch = !!(
|
|
51
|
-
typeof window !== undefined &&
|
|
51
|
+
typeof window !== 'undefined' &&
|
|
52
52
|
window.TouchEvent &&
|
|
53
53
|
'ontouchstart' in window
|
|
54
54
|
);
|
|
@@ -170,8 +170,6 @@ function Drag(element, options) {
|
|
|
170
170
|
this.ops.onInertia(this.inertiaEv);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
console.log('inertia');
|
|
174
|
-
|
|
175
173
|
// test for near zero velocity and end
|
|
176
174
|
if (Math.abs(this.velocity.x) > 0.5 || Math.abs(this.velocity.y) > 0.5) {
|
|
177
175
|
requestAnimationFrame(this.inertiaUpdate.bind(this));
|
package/utils/scrollWatcher.js
CHANGED
|
@@ -265,6 +265,9 @@ class ScrollWatcher {
|
|
|
265
265
|
|
|
266
266
|
static removeWatch(watcherElement) {
|
|
267
267
|
var idx = this.elements.indexOf(watcherElement);
|
|
268
|
+
if (idx === -1) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
268
271
|
this.elements = this.elements
|
|
269
272
|
.slice(0, idx)
|
|
270
273
|
.concat(this.elements.slice(idx + 1, this.elements.length));
|
package/utils/svgIcons.js
CHANGED
|
@@ -60,7 +60,7 @@ function preparePoints(points, ops) {
|
|
|
60
60
|
// shift to center
|
|
61
61
|
bounds = getBoundingBox(points);
|
|
62
62
|
|
|
63
|
-
if (
|
|
63
|
+
if (ops.naturalSizeFixed) {
|
|
64
64
|
points = shiftPoints(
|
|
65
65
|
points,
|
|
66
66
|
(bounds.width - ops.naturalSize) / 2,
|
|
@@ -101,30 +101,28 @@ const svgArrowDefaults = {
|
|
|
101
101
|
// sizing, stroke, etc.
|
|
102
102
|
...sharedDefaults,
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
chevron: false,
|
|
127
|
-
},
|
|
104
|
+
/**
|
|
105
|
+
* The angle in which the arrow is pointing. If a number is provide it will be interpreted
|
|
106
|
+
* in degrees (0 is up, 90 is pointing right, etc.). Alternatively one of the following
|
|
107
|
+
* strings can be provided as the direction in which it points: up, right, down, left.
|
|
108
|
+
*/
|
|
109
|
+
angle: 0,
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The aspect of the arrow (think of a rectangle that the arrow will fill), aspect is considered
|
|
113
|
+
* for an arrow that is pointing up
|
|
114
|
+
*/
|
|
115
|
+
pointerAspect: 2,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The size of the arrow relative to the outer bounds.
|
|
119
|
+
*/
|
|
120
|
+
pointerSize: 0.4,
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* If true, no stem will be generated
|
|
124
|
+
*/
|
|
125
|
+
chevron: false,
|
|
128
126
|
};
|
|
129
127
|
|
|
130
128
|
function svgArrow(options = {}) {
|
|
@@ -196,33 +194,31 @@ const svgCheckDefaults = {
|
|
|
196
194
|
// sizing, stroke, etc.
|
|
197
195
|
...sharedDefaults,
|
|
198
196
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
lift: 0,
|
|
219
|
-
},
|
|
197
|
+
/**
|
|
198
|
+
* The aspect of the checkmark (think of the checkmark as through drawn an angle of 0
|
|
199
|
+
* degrees so it is perfectly straight, this is the aspect between width and height of the
|
|
200
|
+
* rectangle that creates).
|
|
201
|
+
*/
|
|
202
|
+
aspect: 0.4,
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The rotational angle of the checkmark.
|
|
206
|
+
*/
|
|
207
|
+
angle: 40,
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Represents the amount of lift that bottom of the checkmark has relative to the total
|
|
211
|
+
* height (so a value of 0.5 would cause) the bottom line to be angle so much that it
|
|
212
|
+
* reaches the middle of the horizontal line. Normally this is often 0 (for a complete right
|
|
213
|
+
* angle) and almost always less than around 0.25.
|
|
214
|
+
*/
|
|
215
|
+
lift: 0,
|
|
220
216
|
};
|
|
221
217
|
|
|
222
218
|
function svgCheck(options = {}) {
|
|
223
219
|
const ops = { ...svgCheckDefaults, ...options };
|
|
224
220
|
|
|
225
|
-
let points,
|
|
221
|
+
let points, viewBox;
|
|
226
222
|
|
|
227
223
|
const w = ops.aspect;
|
|
228
224
|
const h = 0.9;
|
package/utils/tween.js
CHANGED
|
@@ -27,7 +27,7 @@ const easings = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const isClient = () => {
|
|
30
|
-
return !process.server && typeof window !== 'undefined' && typeof document !== undefined;
|
|
30
|
+
return !process.server && typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const getActiveTweens = () => {
|
|
@@ -51,7 +51,8 @@ const getNextTweenId = () => {
|
|
|
51
51
|
window.pxTween = window?.pxTween || {};
|
|
52
52
|
window.pxTween.nextTweenId = 0;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
window.pxTween.nextTweenId += 1;
|
|
55
|
+
return window.pxTween.nextTweenId;
|
|
55
56
|
};
|
|
56
57
|
|
|
57
58
|
const deleteTween = id => {
|
|
@@ -83,14 +84,15 @@ function tweenValue(from, to, cb, { time, done, easeFunc, delay } = {}) {
|
|
|
83
84
|
cb(from - ease(percentage) * diff);
|
|
84
85
|
}
|
|
85
86
|
if (elapsed < targetTime + delay) {
|
|
86
|
-
window
|
|
87
|
+
if (window) window.requestAnimationFrame(step);
|
|
87
88
|
} else {
|
|
88
89
|
cb(to);
|
|
89
|
-
done
|
|
90
|
+
if (done) done();
|
|
91
|
+
deleteTween(id);
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
|
-
window
|
|
95
|
+
if (window) window.requestAnimationFrame(step);
|
|
94
96
|
return id;
|
|
95
97
|
}
|
|
96
98
|
|
package/utils/uniqueId.js
CHANGED
package/utils/utils.js
CHANGED
|
@@ -33,7 +33,7 @@ export function ensureArray(value) {
|
|
|
33
33
|
* @param {*} fn The function to be called to generate each item.
|
|
34
34
|
*/
|
|
35
35
|
export function arrayFill(count, fn) {
|
|
36
|
-
return Array.from({ count }, (_, i) => fn(i));
|
|
36
|
+
return Array.from({ length: count }, (_, i) => fn(i));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -282,6 +282,11 @@ export function deepMerge(target, source, overwrite = true) {
|
|
|
282
282
|
|
|
283
283
|
for (const key in source) {
|
|
284
284
|
if (source.hasOwnProperty(key)) {
|
|
285
|
+
// Don't let attacker-controlled keys walk the prototype chain.
|
|
286
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
|
|
285
290
|
const sourceValue = source[key];
|
|
286
291
|
const targetValue = target[key];
|
|
287
292
|
|
|
@@ -386,7 +391,7 @@ export function getClientRect(element, relativeTo = null, scrollAdjust = true) {
|
|
|
386
391
|
// TODO: do we need to adjust for other scroll containers?
|
|
387
392
|
|
|
388
393
|
let scroll = { left: 0, top: 0 };
|
|
389
|
-
if (scrollAdjust && typeof window !== undefined) {
|
|
394
|
+
if (scrollAdjust && typeof window !== 'undefined') {
|
|
390
395
|
scroll.left = window.scrollX;
|
|
391
396
|
scroll.top = window.scrollY;
|
|
392
397
|
}
|