@schukai/monster 4.137.5 → 4.137.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 +1 -1
- package/source/components/form/context-error.mjs +1 -1
- package/source/components/form/login.mjs +1 -1
- package/source/components/form/sheet.mjs +83 -7
- package/source/components/layout/slider.mjs +146 -47
- package/source/types/version.mjs +1 -1
- package/test/cases/components/form/sheet.mjs +126 -0
- package/test/cases/components/layout/slider.mjs +165 -0
- package/test/cases/components/navigation/table-of-content.mjs +32 -21
- package/test/cases/dom/resource/data.mjs +15 -7
- package/test/cases/dom/resourcemanager.mjs +8 -4
- package/test/cases/monster.mjs +1 -1
- package/test/web/import.js +3 -6
- package/test/web/test.html +2 -2
- package/test/web/tests.js +14285 -15456
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.137.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.137.7"}
|
|
@@ -1905,7 +1905,7 @@ function getTemplate() {
|
|
|
1905
1905
|
<monster-collapse data-monster-option-openByDefault="true"
|
|
1906
1906
|
data-monster-role="login-collapse"
|
|
1907
1907
|
exportparts="control:collapse-login-control,
|
|
1908
|
-
|
|
1908
|
+
container:collapse-login-container,
|
|
1909
1909
|
deco:collapse-login-deco"
|
|
1910
1910
|
part="login-collapse">
|
|
1911
1911
|
<monster-field-set
|
|
@@ -56,6 +56,12 @@ const menuStateSymbol = Symbol("sheetMenuState");
|
|
|
56
56
|
const dragFillSymbol = Symbol("sheetDragFill");
|
|
57
57
|
const lastCopySymbol = Symbol("sheetLastCopy");
|
|
58
58
|
const dragSelectSymbol = Symbol("sheetDragSelect");
|
|
59
|
+
const pendingResizeMoveSymbol = Symbol("sheetPendingResizeMove");
|
|
60
|
+
const resizeMoveFrameSymbol = Symbol("sheetResizeMoveFrame");
|
|
61
|
+
const pendingSelectionMoveSymbol = Symbol("sheetPendingSelectionMove");
|
|
62
|
+
const selectionMoveFrameSymbol = Symbol("sheetSelectionMoveFrame");
|
|
63
|
+
const pendingFillMoveSymbol = Symbol("sheetPendingFillMove");
|
|
64
|
+
const fillMoveFrameSymbol = Symbol("sheetFillMoveFrame");
|
|
59
65
|
|
|
60
66
|
class Sheet extends CustomControl {
|
|
61
67
|
static get [instanceSymbol]() {
|
|
@@ -1020,15 +1026,31 @@ function handleResizeMove(event) {
|
|
|
1020
1026
|
const grid = event.currentTarget;
|
|
1021
1027
|
const sheet = grid.getRootNode().host;
|
|
1022
1028
|
if (!sheet || !sheet[resizeStateSymbol]) return;
|
|
1023
|
-
|
|
1029
|
+
scheduleResizeMove.call(sheet, event.clientX, event.clientY);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
function scheduleResizeMove(clientX, clientY) {
|
|
1033
|
+
this[pendingResizeMoveSymbol] = { clientX, clientY };
|
|
1034
|
+
if (this[resizeMoveFrameSymbol]) return;
|
|
1035
|
+
this[resizeMoveFrameSymbol] = requestAnimationFrame(() => {
|
|
1036
|
+
this[resizeMoveFrameSymbol] = null;
|
|
1037
|
+
flushResizeMove.call(this);
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
function flushResizeMove() {
|
|
1042
|
+
const pending = this[pendingResizeMoveSymbol];
|
|
1043
|
+
this[pendingResizeMoveSymbol] = null;
|
|
1044
|
+
if (!pending || !this[resizeStateSymbol]) return;
|
|
1045
|
+
const state = this[resizeStateSymbol];
|
|
1024
1046
|
if (state.kind === "column") {
|
|
1025
|
-
const delta =
|
|
1047
|
+
const delta = pending.clientX - state.start;
|
|
1026
1048
|
const size = state.startSize + delta;
|
|
1027
|
-
setColumnSize.call(
|
|
1049
|
+
setColumnSize.call(this, state.id, size);
|
|
1028
1050
|
} else if (state.kind === "row") {
|
|
1029
|
-
const delta =
|
|
1051
|
+
const delta = pending.clientY - state.start;
|
|
1030
1052
|
const size = state.startSize + delta;
|
|
1031
|
-
setRowSize.call(
|
|
1053
|
+
setRowSize.call(this, state.id, size);
|
|
1032
1054
|
}
|
|
1033
1055
|
}
|
|
1034
1056
|
|
|
@@ -1043,6 +1065,11 @@ function handleResizeEnd(event) {
|
|
|
1043
1065
|
grid.removeEventListener("pointermove", handleResizeMove);
|
|
1044
1066
|
grid.removeEventListener("pointerup", handleResizeEnd);
|
|
1045
1067
|
grid.removeEventListener("pointercancel", handleResizeEnd);
|
|
1068
|
+
if (sheet[resizeMoveFrameSymbol]) {
|
|
1069
|
+
cancelAnimationFrame(sheet[resizeMoveFrameSymbol]);
|
|
1070
|
+
sheet[resizeMoveFrameSymbol] = null;
|
|
1071
|
+
}
|
|
1072
|
+
flushResizeMove.call(sheet);
|
|
1046
1073
|
sheet[resizeStateSymbol] = null;
|
|
1047
1074
|
}
|
|
1048
1075
|
|
|
@@ -1050,6 +1077,9 @@ function setColumnSize(columnId, size) {
|
|
|
1050
1077
|
const min = getSizeNumber(this.getOption("constraints.minColumnWidth"), 64);
|
|
1051
1078
|
const max = getSizeNumber(this.getOption("constraints.maxColumnWidth"), 360);
|
|
1052
1079
|
const next = clamp(size, min, max);
|
|
1080
|
+
if (getColumnWidthNumber.call(this, columnId) === next) {
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1053
1083
|
this.setOption(`sizes.columns.${columnId}`, next);
|
|
1054
1084
|
this[skipRenderSymbol] = true;
|
|
1055
1085
|
if (this.getOption("features.virtualize", false) === true) {
|
|
@@ -1067,6 +1097,9 @@ function setRowSize(rowId, size) {
|
|
|
1067
1097
|
const min = getSizeNumber(this.getOption("constraints.minRowHeight"), 28);
|
|
1068
1098
|
const max = getSizeNumber(this.getOption("constraints.maxRowHeight"), 120);
|
|
1069
1099
|
const next = clamp(size, min, max);
|
|
1100
|
+
if (getRowHeightNumber.call(this, rowId) === next) {
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1070
1103
|
this.setOption(`sizes.rows.${rowId}`, next);
|
|
1071
1104
|
this[skipRenderSymbol] = true;
|
|
1072
1105
|
if (this.getOption("features.virtualize", false) === true) {
|
|
@@ -1178,7 +1211,23 @@ function handleSelectionDragMove(event) {
|
|
|
1178
1211
|
if (Math.abs(dx) < 3 && Math.abs(dy) < 3) return;
|
|
1179
1212
|
state.moved = true;
|
|
1180
1213
|
}
|
|
1181
|
-
|
|
1214
|
+
scheduleSelectionDragMove.call(this, event.clientX, event.clientY);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
function scheduleSelectionDragMove(clientX, clientY) {
|
|
1218
|
+
this[pendingSelectionMoveSymbol] = { clientX, clientY };
|
|
1219
|
+
if (this[selectionMoveFrameSymbol]) return;
|
|
1220
|
+
this[selectionMoveFrameSymbol] = requestAnimationFrame(() => {
|
|
1221
|
+
this[selectionMoveFrameSymbol] = null;
|
|
1222
|
+
flushSelectionDragMove.call(this);
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
function flushSelectionDragMove() {
|
|
1227
|
+
const pending = this[pendingSelectionMoveSymbol];
|
|
1228
|
+
this[pendingSelectionMoveSymbol] = null;
|
|
1229
|
+
if (!pending || !this[dragSelectSymbol]?.active) return;
|
|
1230
|
+
const cell = getCellFromPoint.call(this, pending.clientX, pending.clientY);
|
|
1182
1231
|
if (!cell) return;
|
|
1183
1232
|
const rowId = cell.dataset.rowId;
|
|
1184
1233
|
const colId = cell.dataset.colId;
|
|
@@ -1189,6 +1238,11 @@ function handleSelectionDragMove(event) {
|
|
|
1189
1238
|
function handleSelectionDragEnd() {
|
|
1190
1239
|
const state = this[dragSelectSymbol];
|
|
1191
1240
|
if (!state) return;
|
|
1241
|
+
if (this[selectionMoveFrameSymbol]) {
|
|
1242
|
+
cancelAnimationFrame(this[selectionMoveFrameSymbol]);
|
|
1243
|
+
this[selectionMoveFrameSymbol] = null;
|
|
1244
|
+
}
|
|
1245
|
+
flushSelectionDragMove.call(this);
|
|
1192
1246
|
if (state.cleanup) state.cleanup();
|
|
1193
1247
|
this[dragSelectSymbol] = null;
|
|
1194
1248
|
this.removeAttribute("data-selecting");
|
|
@@ -1805,8 +1859,25 @@ function handleFillMove(event) {
|
|
|
1805
1859
|
if (Math.abs(dx) < 3 && Math.abs(dy) < 3) return;
|
|
1806
1860
|
state.moved = true;
|
|
1807
1861
|
}
|
|
1862
|
+
scheduleFillMove.call(this, event.clientX, event.clientY);
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
function scheduleFillMove(clientX, clientY) {
|
|
1866
|
+
this[pendingFillMoveSymbol] = { clientX, clientY };
|
|
1867
|
+
if (this[fillMoveFrameSymbol]) return;
|
|
1868
|
+
this[fillMoveFrameSymbol] = requestAnimationFrame(() => {
|
|
1869
|
+
this[fillMoveFrameSymbol] = null;
|
|
1870
|
+
flushFillMove.call(this);
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
function flushFillMove() {
|
|
1875
|
+
const state = this[dragFillSymbol];
|
|
1876
|
+
const pending = this[pendingFillMoveSymbol];
|
|
1877
|
+
this[pendingFillMoveSymbol] = null;
|
|
1878
|
+
if (!state || !pending) return;
|
|
1808
1879
|
const data = normalizeValue.call(this);
|
|
1809
|
-
const cell = getCellFromPoint.call(this,
|
|
1880
|
+
const cell = getCellFromPoint.call(this, pending.clientX, pending.clientY);
|
|
1810
1881
|
if (!cell) return;
|
|
1811
1882
|
const rowId = cell.dataset.rowId;
|
|
1812
1883
|
const colId = cell.dataset.colId;
|
|
@@ -1829,6 +1900,11 @@ function handleFillMove(event) {
|
|
|
1829
1900
|
function handleFillEnd() {
|
|
1830
1901
|
const state = this[dragFillSymbol];
|
|
1831
1902
|
if (!state) return;
|
|
1903
|
+
if (this[fillMoveFrameSymbol]) {
|
|
1904
|
+
cancelAnimationFrame(this[fillMoveFrameSymbol]);
|
|
1905
|
+
this[fillMoveFrameSymbol] = null;
|
|
1906
|
+
}
|
|
1907
|
+
flushFillMove.call(this);
|
|
1832
1908
|
if (state.cleanup) state.cleanup();
|
|
1833
1909
|
this.removeAttribute("data-filling");
|
|
1834
1910
|
const data = normalizeValue.call(this);
|
|
@@ -106,27 +106,28 @@ class Slider extends CustomElement {
|
|
|
106
106
|
startPos: 0,
|
|
107
107
|
autoPlayInterval: null,
|
|
108
108
|
resizeObserver: null, // Store the observer for later cleanup
|
|
109
|
+
resizeFrame: null,
|
|
110
|
+
pendingResizeSize: null,
|
|
111
|
+
lastResizeSize: null,
|
|
112
|
+
visibleSlides: null,
|
|
113
|
+
dragFrame: null,
|
|
114
|
+
pendingDragEvent: null,
|
|
109
115
|
|
|
110
116
|
eventHandler: {
|
|
111
117
|
mouseOverPause: null,
|
|
112
118
|
mouseout: null,
|
|
113
119
|
touchstart: null,
|
|
114
120
|
touchend: null,
|
|
121
|
+
thumbnailMoved: null,
|
|
115
122
|
},
|
|
116
123
|
};
|
|
117
124
|
|
|
118
|
-
|
|
119
|
-
const slides = this.shadowRoot.querySelector(
|
|
120
|
-
`[${ATTRIBUTE_ROLE}="slider"]`,
|
|
121
|
-
);
|
|
125
|
+
initControlReferences.call(this);
|
|
122
126
|
|
|
127
|
+
// Set the CSS custom property for slide width based on visible slides.
|
|
123
128
|
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
124
|
-
|
|
125
|
-
"--monster-slides-width",
|
|
126
|
-
`${100 / slidesVisible}%`,
|
|
127
|
-
);
|
|
129
|
+
setVisibleSlidesWidth.call(this, slidesVisible);
|
|
128
130
|
|
|
129
|
-
initControlReferences.call(this);
|
|
130
131
|
initEventHandler.call(this);
|
|
131
132
|
initStructure.call(this);
|
|
132
133
|
|
|
@@ -151,6 +152,16 @@ class Slider extends CustomElement {
|
|
|
151
152
|
this[configSymbol].resizeObserver = null;
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
if (this[configSymbol]?.resizeFrame) {
|
|
156
|
+
getWindow().cancelAnimationFrame(this[configSymbol].resizeFrame);
|
|
157
|
+
this[configSymbol].resizeFrame = null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (this[configSymbol]?.dragFrame) {
|
|
161
|
+
getWindow().cancelAnimationFrame(this[configSymbol].dragFrame);
|
|
162
|
+
this[configSymbol].dragFrame = null;
|
|
163
|
+
}
|
|
164
|
+
|
|
154
165
|
// Remove autoplay-related event listeners
|
|
155
166
|
if (this[configSymbol]?.eventHandler) {
|
|
156
167
|
const { mouseOverPause, mouseout, touchstart, touchend } =
|
|
@@ -172,6 +183,13 @@ class Slider extends CustomElement {
|
|
|
172
183
|
this.removeEventListener("touchend", touchend);
|
|
173
184
|
this[configSymbol].eventHandler.touchend = null;
|
|
174
185
|
}
|
|
186
|
+
if (this[configSymbol].eventHandler.thumbnailMoved) {
|
|
187
|
+
this.removeEventListener(
|
|
188
|
+
"monster-slider-moved",
|
|
189
|
+
this[configSymbol].eventHandler.thumbnailMoved,
|
|
190
|
+
);
|
|
191
|
+
this[configSymbol].eventHandler.thumbnailMoved = null;
|
|
192
|
+
}
|
|
175
193
|
}
|
|
176
194
|
}
|
|
177
195
|
|
|
@@ -327,7 +345,6 @@ function initStructure() {
|
|
|
327
345
|
* @description Generates the thumbnail navigation elements.
|
|
328
346
|
*/
|
|
329
347
|
function initThumbnails() {
|
|
330
|
-
const self = this;
|
|
331
348
|
const thumbnails = this.shadowRoot.querySelector(
|
|
332
349
|
"[data-monster-role='thumbnails']",
|
|
333
350
|
);
|
|
@@ -350,20 +367,26 @@ function initThumbnails() {
|
|
|
350
367
|
});
|
|
351
368
|
|
|
352
369
|
// Listen for move events to update the active thumbnail
|
|
353
|
-
this.
|
|
354
|
-
|
|
355
|
-
|
|
370
|
+
if (this[configSymbol].eventHandler.thumbnailMoved === null) {
|
|
371
|
+
this[configSymbol].eventHandler.thumbnailMoved = (e) => {
|
|
372
|
+
const index = e.detail.index;
|
|
373
|
+
const thumbnail = thumbnails.children[index];
|
|
356
374
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
375
|
+
if (!thumbnail) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
360
378
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
379
|
+
Array.from(thumbnails.children).forEach((thumb) => {
|
|
380
|
+
thumb.classList.remove("current");
|
|
381
|
+
});
|
|
364
382
|
|
|
365
|
-
|
|
366
|
-
|
|
383
|
+
thumbnail.classList.add("current");
|
|
384
|
+
};
|
|
385
|
+
this.addEventListener(
|
|
386
|
+
"monster-slider-moved",
|
|
387
|
+
this[configSymbol].eventHandler.thumbnailMoved,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
367
390
|
}
|
|
368
391
|
|
|
369
392
|
/**
|
|
@@ -509,6 +532,23 @@ function getVisibleSlidesFromContainerWidth() {
|
|
|
509
532
|
return visibleSlides;
|
|
510
533
|
}
|
|
511
534
|
|
|
535
|
+
/**
|
|
536
|
+
* @private
|
|
537
|
+
* @param {number} slidesVisible
|
|
538
|
+
* @return {boolean}
|
|
539
|
+
*/
|
|
540
|
+
function setVisibleSlidesWidth(slidesVisible) {
|
|
541
|
+
if (this[configSymbol].visibleSlides === slidesVisible) {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
this[configSymbol].visibleSlides = slidesVisible;
|
|
545
|
+
this[sliderElementSymbol].style.setProperty(
|
|
546
|
+
"--monster-slides-width",
|
|
547
|
+
`${100 / slidesVisible}%`,
|
|
548
|
+
);
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
|
|
512
552
|
/**
|
|
513
553
|
* @private
|
|
514
554
|
* @description Clones slides to create the "infinite" loop effect for the carousel.
|
|
@@ -757,7 +797,7 @@ function initEventHandler() {
|
|
|
757
797
|
);
|
|
758
798
|
}
|
|
759
799
|
|
|
760
|
-
|
|
800
|
+
this[configSymbol].lastResizeSize = {
|
|
761
801
|
width: this[sliderElementSymbol]?.offsetWidth || 0,
|
|
762
802
|
height: this[sliderElementSymbol]?.offsetHeight || 0,
|
|
763
803
|
};
|
|
@@ -766,30 +806,7 @@ function initEventHandler() {
|
|
|
766
806
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
767
807
|
for (let entry of entries) {
|
|
768
808
|
const { width, height } = entry.contentRect;
|
|
769
|
-
|
|
770
|
-
self.stopAutoPlay();
|
|
771
|
-
|
|
772
|
-
// Re-init thumbnails if layout changes
|
|
773
|
-
if (this.getOption("features.thumbnails")) {
|
|
774
|
-
initThumbnails.call(this);
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
// Recalculate visible slides and update CSS property
|
|
778
|
-
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
779
|
-
this[sliderElementSymbol].style.setProperty(
|
|
780
|
-
"--monster-slides-width",
|
|
781
|
-
`${100 / slidesVisible}%`,
|
|
782
|
-
);
|
|
783
|
-
|
|
784
|
-
// Move to start without animation
|
|
785
|
-
moveTo.call(self, 0, false);
|
|
786
|
-
self.startAutoPlay();
|
|
787
|
-
|
|
788
|
-
fireCustomEvent(self, "monster-slider-resized", {
|
|
789
|
-
width: width,
|
|
790
|
-
height: height,
|
|
791
|
-
});
|
|
792
|
-
}
|
|
809
|
+
scheduleResizeUpdate.call(this, width, height);
|
|
793
810
|
}
|
|
794
811
|
});
|
|
795
812
|
|
|
@@ -799,6 +816,62 @@ function initEventHandler() {
|
|
|
799
816
|
return this;
|
|
800
817
|
}
|
|
801
818
|
|
|
819
|
+
function scheduleResizeUpdate(width, height) {
|
|
820
|
+
const lastSize = this[configSymbol].lastResizeSize;
|
|
821
|
+
if (
|
|
822
|
+
this[configSymbol].resizeFrame === null &&
|
|
823
|
+
lastSize &&
|
|
824
|
+
width === lastSize.width &&
|
|
825
|
+
height === lastSize.height
|
|
826
|
+
) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
this[configSymbol].pendingResizeSize = { width, height };
|
|
830
|
+
if (this[configSymbol].resizeFrame !== null) {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
this[configSymbol].resizeFrame = getWindow().requestAnimationFrame(() => {
|
|
834
|
+
this[configSymbol].resizeFrame = null;
|
|
835
|
+
flushResizeUpdate.call(this);
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
function flushResizeUpdate() {
|
|
840
|
+
const size = this[configSymbol].pendingResizeSize;
|
|
841
|
+
this[configSymbol].pendingResizeSize = null;
|
|
842
|
+
if (!size) {
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
const lastSize = this[configSymbol].lastResizeSize;
|
|
847
|
+
if (
|
|
848
|
+
lastSize &&
|
|
849
|
+
size.width === lastSize.width &&
|
|
850
|
+
size.height === lastSize.height
|
|
851
|
+
) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
this[configSymbol].lastResizeSize = size;
|
|
855
|
+
|
|
856
|
+
const previousVisibleSlides = this[configSymbol].visibleSlides;
|
|
857
|
+
const slidesVisible = getVisibleSlidesFromContainerWidth.call(this);
|
|
858
|
+
const visibleSlidesChanged = setVisibleSlidesWidth.call(this, slidesVisible);
|
|
859
|
+
|
|
860
|
+
if (
|
|
861
|
+
visibleSlidesChanged &&
|
|
862
|
+
previousVisibleSlides !== null &&
|
|
863
|
+
this.getOption("features.thumbnails")
|
|
864
|
+
) {
|
|
865
|
+
initThumbnails.call(this);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
this.stopAutoPlay();
|
|
869
|
+
moveTo.call(this, 0, false);
|
|
870
|
+
this.startAutoPlay();
|
|
871
|
+
|
|
872
|
+
fireCustomEvent(this, "monster-slider-resized", size);
|
|
873
|
+
}
|
|
874
|
+
|
|
802
875
|
/**
|
|
803
876
|
* @private
|
|
804
877
|
* @description Handles the "mousedown" or "touchstart" event to begin dragging.
|
|
@@ -819,7 +892,7 @@ function startDragging(e, type) {
|
|
|
819
892
|
this[sliderElementSymbol].style.transitionProperty = "none";
|
|
820
893
|
|
|
821
894
|
const callbackMousemove = (x) => {
|
|
822
|
-
|
|
895
|
+
scheduleDragging.call(this, x, type);
|
|
823
896
|
};
|
|
824
897
|
|
|
825
898
|
const callbackMouseUp = () => {
|
|
@@ -830,6 +903,12 @@ function startDragging(e, type) {
|
|
|
830
903
|
document.body.removeEventListener(endEvent, callbackMouseUp);
|
|
831
904
|
document.body.removeEventListener(moveEvent, callbackMousemove);
|
|
832
905
|
|
|
906
|
+
if (this[configSymbol].dragFrame !== null) {
|
|
907
|
+
getWindow().cancelAnimationFrame(this[configSymbol].dragFrame);
|
|
908
|
+
this[configSymbol].dragFrame = null;
|
|
909
|
+
}
|
|
910
|
+
flushDragging.call(this, type);
|
|
911
|
+
|
|
833
912
|
this[configSymbol].isDragging = false;
|
|
834
913
|
this[configSymbol].startPos = 0;
|
|
835
914
|
this[sliderElementSymbol].classList.remove("grabbing");
|
|
@@ -880,6 +959,26 @@ function dragging(e, type) {
|
|
|
880
959
|
`translateX(calc(${this[configSymbol].lastOffset} + ${this[configSymbol].draggingPos}px))`;
|
|
881
960
|
}
|
|
882
961
|
|
|
962
|
+
function scheduleDragging(e, type) {
|
|
963
|
+
this[configSymbol].pendingDragEvent = e;
|
|
964
|
+
if (this[configSymbol].dragFrame !== null) {
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
this[configSymbol].dragFrame = getWindow().requestAnimationFrame(() => {
|
|
968
|
+
this[configSymbol].dragFrame = null;
|
|
969
|
+
flushDragging.call(this, type);
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
function flushDragging(type) {
|
|
974
|
+
const event = this[configSymbol].pendingDragEvent;
|
|
975
|
+
this[configSymbol].pendingDragEvent = null;
|
|
976
|
+
if (!event) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
dragging.call(this, event, type);
|
|
980
|
+
}
|
|
981
|
+
|
|
883
982
|
/**
|
|
884
983
|
* @private
|
|
885
984
|
* @description Caches references to key elements in the shadow DOM.
|
package/source/types/version.mjs
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as chai from "chai";
|
|
2
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
3
|
+
|
|
4
|
+
const expect = chai.expect;
|
|
5
|
+
|
|
6
|
+
describe("Sheet", function () {
|
|
7
|
+
let Sheet;
|
|
8
|
+
|
|
9
|
+
before(function (done) {
|
|
10
|
+
initJSDOM()
|
|
11
|
+
.then(() => {
|
|
12
|
+
import("../../../../source/components/form/sheet.mjs")
|
|
13
|
+
.then((m) => {
|
|
14
|
+
Sheet = m.Sheet;
|
|
15
|
+
done();
|
|
16
|
+
})
|
|
17
|
+
.catch((e) => done(e));
|
|
18
|
+
})
|
|
19
|
+
.catch((e) => done(e));
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
document.getElementById("mocks").innerHTML = "";
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should register monster-sheet", function () {
|
|
27
|
+
expect(document.createElement("monster-sheet")).to.be.instanceof(Sheet);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should coalesce column resize pointer moves", function (done) {
|
|
31
|
+
const originalRequestAnimationFrame = window.requestAnimationFrame;
|
|
32
|
+
const originalGlobalRequestAnimationFrame = globalThis.requestAnimationFrame;
|
|
33
|
+
const originalCancelAnimationFrame = window.cancelAnimationFrame;
|
|
34
|
+
const originalGlobalCancelAnimationFrame = globalThis.cancelAnimationFrame;
|
|
35
|
+
const scheduledCallbacks = [];
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
window.requestAnimationFrame = (callback) => {
|
|
39
|
+
scheduledCallbacks.push(callback);
|
|
40
|
+
return scheduledCallbacks.length;
|
|
41
|
+
};
|
|
42
|
+
globalThis.requestAnimationFrame = window.requestAnimationFrame;
|
|
43
|
+
window.cancelAnimationFrame = () => {};
|
|
44
|
+
globalThis.cancelAnimationFrame = window.cancelAnimationFrame;
|
|
45
|
+
|
|
46
|
+
const mocks = document.getElementById("mocks");
|
|
47
|
+
const sheet = document.createElement("monster-sheet");
|
|
48
|
+
mocks.appendChild(sheet);
|
|
49
|
+
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
try {
|
|
52
|
+
const grid = sheet.shadowRoot.querySelector(
|
|
53
|
+
'[data-monster-role="grid"]',
|
|
54
|
+
);
|
|
55
|
+
const handle = sheet.shadowRoot.querySelector(
|
|
56
|
+
'[data-monster-role="column-resize"]',
|
|
57
|
+
);
|
|
58
|
+
const header = handle.parentElement;
|
|
59
|
+
grid.setPointerCapture = () => {};
|
|
60
|
+
grid.releasePointerCapture = () => {};
|
|
61
|
+
Object.defineProperty(header, "getBoundingClientRect", {
|
|
62
|
+
configurable: true,
|
|
63
|
+
value: () => ({ width: 120 }),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
let resizeEvents = 0;
|
|
67
|
+
sheet.addEventListener("monster-sheet-resize-column", () => {
|
|
68
|
+
resizeEvents++;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const down = new Event("pointerdown", { bubbles: true });
|
|
72
|
+
Object.assign(down, {
|
|
73
|
+
button: 0,
|
|
74
|
+
clientX: 100,
|
|
75
|
+
clientY: 0,
|
|
76
|
+
pointerId: 1,
|
|
77
|
+
});
|
|
78
|
+
handle.dispatchEvent(down);
|
|
79
|
+
|
|
80
|
+
const firstMove = new Event("pointermove", { bubbles: true });
|
|
81
|
+
Object.assign(firstMove, {
|
|
82
|
+
clientX: 130,
|
|
83
|
+
clientY: 0,
|
|
84
|
+
pointerId: 1,
|
|
85
|
+
});
|
|
86
|
+
const secondMove = new Event("pointermove", { bubbles: true });
|
|
87
|
+
Object.assign(secondMove, {
|
|
88
|
+
clientX: 150,
|
|
89
|
+
clientY: 0,
|
|
90
|
+
pointerId: 1,
|
|
91
|
+
});
|
|
92
|
+
grid.dispatchEvent(firstMove);
|
|
93
|
+
grid.dispatchEvent(secondMove);
|
|
94
|
+
|
|
95
|
+
expect(scheduledCallbacks.length).to.equal(1);
|
|
96
|
+
scheduledCallbacks.shift()();
|
|
97
|
+
expect(resizeEvents).to.equal(1);
|
|
98
|
+
|
|
99
|
+
const repeatedMove = new Event("pointermove", { bubbles: true });
|
|
100
|
+
Object.assign(repeatedMove, {
|
|
101
|
+
clientX: 150,
|
|
102
|
+
clientY: 0,
|
|
103
|
+
pointerId: 1,
|
|
104
|
+
});
|
|
105
|
+
grid.dispatchEvent(repeatedMove);
|
|
106
|
+
scheduledCallbacks.shift()();
|
|
107
|
+
expect(resizeEvents).to.equal(1);
|
|
108
|
+
done();
|
|
109
|
+
} catch (e) {
|
|
110
|
+
done(e);
|
|
111
|
+
} finally {
|
|
112
|
+
window.requestAnimationFrame = originalRequestAnimationFrame;
|
|
113
|
+
globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
|
|
114
|
+
window.cancelAnimationFrame = originalCancelAnimationFrame;
|
|
115
|
+
globalThis.cancelAnimationFrame = originalGlobalCancelAnimationFrame;
|
|
116
|
+
}
|
|
117
|
+
}, 0);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
window.requestAnimationFrame = originalRequestAnimationFrame;
|
|
120
|
+
globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
|
|
121
|
+
window.cancelAnimationFrame = originalCancelAnimationFrame;
|
|
122
|
+
globalThis.cancelAnimationFrame = originalGlobalCancelAnimationFrame;
|
|
123
|
+
done(e);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|