@inertiajs/core 2.1.11 → 2.2.0
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/dist/index.esm.js +539 -44
- package/dist/index.esm.js.map +4 -4
- package/dist/index.js +539 -44
- package/dist/index.js.map +4 -4
- package/package.json +9 -9
- package/types/domUtils.d.ts +2 -0
- package/types/events.d.ts +1 -0
- package/types/index.d.ts +2 -0
- package/types/infiniteScroll/data.d.ts +9 -0
- package/types/infiniteScroll/elements.d.ts +14 -0
- package/types/infiniteScroll/queryString.d.ts +12 -0
- package/types/infiniteScroll/scrollPreservation.d.ts +18 -0
- package/types/infiniteScroll.d.ts +12 -0
- package/types/intersectionObservers.d.ts +7 -0
- package/types/response.d.ts +4 -1
- package/types/router.d.ts +3 -0
- package/types/types.d.ts +88 -0
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
createHeadManager: () => createHeadManager,
|
|
34
34
|
formDataToObject: () => formDataToObject,
|
|
35
|
+
getScrollableParent: () => getScrollableParent,
|
|
35
36
|
hideProgress: () => hide2,
|
|
36
37
|
hrefToUrl: () => hrefToUrl,
|
|
37
38
|
isUrlMethodPair: () => isUrlMethodPair,
|
|
@@ -44,10 +45,14 @@ __export(index_exports, {
|
|
|
44
45
|
setupProgress: () => setupProgress,
|
|
45
46
|
shouldIntercept: () => shouldIntercept,
|
|
46
47
|
shouldNavigate: () => shouldNavigate,
|
|
47
|
-
urlWithoutHash: () => urlWithoutHash
|
|
48
|
+
urlWithoutHash: () => urlWithoutHash,
|
|
49
|
+
useInfiniteScroll: () => useInfiniteScroll
|
|
48
50
|
});
|
|
49
51
|
module.exports = __toCommonJS(index_exports);
|
|
50
52
|
|
|
53
|
+
// src/router.ts
|
|
54
|
+
var import_lodash_es3 = require("lodash-es");
|
|
55
|
+
|
|
51
56
|
// src/debounce.ts
|
|
52
57
|
function debounce(fn, delay) {
|
|
53
58
|
let timeoutID;
|
|
@@ -76,6 +81,9 @@ var fireFinishEvent = (visit) => {
|
|
|
76
81
|
var fireInvalidEvent = (response) => {
|
|
77
82
|
return fireEvent("invalid", { cancelable: true, detail: { response } });
|
|
78
83
|
};
|
|
84
|
+
var fireBeforeUpdateEvent = (page2) => {
|
|
85
|
+
return fireEvent("beforeUpdate", { detail: { page: page2 } });
|
|
86
|
+
};
|
|
79
87
|
var fireNavigateEvent = (page2) => {
|
|
80
88
|
return fireEvent("navigate", { detail: { page: page2 } });
|
|
81
89
|
};
|
|
@@ -1238,6 +1246,7 @@ var PrefetchedRequests = class {
|
|
|
1238
1246
|
"replace",
|
|
1239
1247
|
"prefetch",
|
|
1240
1248
|
"onBefore",
|
|
1249
|
+
"onBeforeUpdate",
|
|
1241
1250
|
"onStart",
|
|
1242
1251
|
"onProgress",
|
|
1243
1252
|
"onFinish",
|
|
@@ -1266,6 +1275,7 @@ var RequestParams = class _RequestParams {
|
|
|
1266
1275
|
} else {
|
|
1267
1276
|
const wrappedCallbacks = {
|
|
1268
1277
|
onBefore: this.wrapCallback(params, "onBefore"),
|
|
1278
|
+
onBeforeUpdate: this.wrapCallback(params, "onBeforeUpdate"),
|
|
1269
1279
|
onStart: this.wrapCallback(params, "onStart"),
|
|
1270
1280
|
onProgress: this.wrapCallback(params, "onProgress"),
|
|
1271
1281
|
onFinish: this.wrapCallback(params, "onFinish"),
|
|
@@ -1396,6 +1406,9 @@ var RequestParams = class _RequestParams {
|
|
|
1396
1406
|
}
|
|
1397
1407
|
};
|
|
1398
1408
|
|
|
1409
|
+
// src/response.ts
|
|
1410
|
+
var import_lodash_es2 = require("lodash-es");
|
|
1411
|
+
|
|
1399
1412
|
// src/modal.ts
|
|
1400
1413
|
var modal_default = {
|
|
1401
1414
|
modal: null,
|
|
@@ -1558,6 +1571,8 @@ var Response = class _Response {
|
|
|
1558
1571
|
await this.setRememberedState(pageResponse);
|
|
1559
1572
|
this.requestParams.setPreserveOptions(pageResponse);
|
|
1560
1573
|
pageResponse.url = history.preserveUrl ? page.get().url : this.pageUrl(pageResponse);
|
|
1574
|
+
this.requestParams.all().onBeforeUpdate(pageResponse);
|
|
1575
|
+
fireBeforeUpdateEvent(pageResponse);
|
|
1561
1576
|
return page.set(pageResponse, {
|
|
1562
1577
|
replace: this.requestParams.all().replace,
|
|
1563
1578
|
preserveScroll: this.requestParams.all().preserveScroll,
|
|
@@ -1597,36 +1612,43 @@ var Response = class _Response {
|
|
|
1597
1612
|
if (!this.requestParams.isPartial() || pageResponse.component !== page.get().component) {
|
|
1598
1613
|
return;
|
|
1599
1614
|
}
|
|
1600
|
-
const
|
|
1615
|
+
const propsToAppend = pageResponse.mergeProps || [];
|
|
1616
|
+
const propsToPrepend = pageResponse.prependProps || [];
|
|
1601
1617
|
const propsToDeepMerge = pageResponse.deepMergeProps || [];
|
|
1602
1618
|
const matchPropsOn = pageResponse.matchPropsOn || [];
|
|
1603
|
-
|
|
1604
|
-
const
|
|
1619
|
+
const mergeProp = (prop, shouldAppend) => {
|
|
1620
|
+
const currentProp = (0, import_lodash_es2.get)(page.get().props, prop);
|
|
1621
|
+
const incomingProp = (0, import_lodash_es2.get)(pageResponse.props, prop);
|
|
1605
1622
|
if (Array.isArray(incomingProp)) {
|
|
1606
|
-
|
|
1607
|
-
|
|
1623
|
+
const newArray = this.mergeOrMatchItems(
|
|
1624
|
+
currentProp || [],
|
|
1608
1625
|
incomingProp,
|
|
1609
1626
|
prop,
|
|
1610
|
-
matchPropsOn
|
|
1627
|
+
matchPropsOn,
|
|
1628
|
+
shouldAppend
|
|
1611
1629
|
);
|
|
1630
|
+
(0, import_lodash_es2.set)(pageResponse.props, prop, newArray);
|
|
1612
1631
|
} else if (typeof incomingProp === "object" && incomingProp !== null) {
|
|
1613
|
-
|
|
1614
|
-
...
|
|
1632
|
+
const newObject = {
|
|
1633
|
+
...currentProp || {},
|
|
1615
1634
|
...incomingProp
|
|
1616
1635
|
};
|
|
1636
|
+
(0, import_lodash_es2.set)(pageResponse.props, prop, newObject);
|
|
1617
1637
|
}
|
|
1618
|
-
}
|
|
1638
|
+
};
|
|
1639
|
+
propsToAppend.forEach((prop) => mergeProp(prop, true));
|
|
1640
|
+
propsToPrepend.forEach((prop) => mergeProp(prop, false));
|
|
1619
1641
|
propsToDeepMerge.forEach((prop) => {
|
|
1620
|
-
const incomingProp = pageResponse.props[prop];
|
|
1621
1642
|
const currentProp = page.get().props[prop];
|
|
1622
|
-
const
|
|
1643
|
+
const incomingProp = pageResponse.props[prop];
|
|
1644
|
+
const deepMerge = (target, source, matchProp) => {
|
|
1623
1645
|
if (Array.isArray(source)) {
|
|
1624
|
-
return this.mergeOrMatchItems(target, source,
|
|
1646
|
+
return this.mergeOrMatchItems(target, source, matchProp, matchPropsOn);
|
|
1625
1647
|
}
|
|
1626
1648
|
if (typeof source === "object" && source !== null) {
|
|
1627
1649
|
return Object.keys(source).reduce(
|
|
1628
1650
|
(acc, key) => {
|
|
1629
|
-
acc[key] = deepMerge(target ? target[key] : void 0, source[key], `${
|
|
1651
|
+
acc[key] = deepMerge(target ? target[key] : void 0, source[key], `${matchProp}.${key}`);
|
|
1630
1652
|
return acc;
|
|
1631
1653
|
},
|
|
1632
1654
|
{ ...target }
|
|
@@ -1638,32 +1660,52 @@ var Response = class _Response {
|
|
|
1638
1660
|
});
|
|
1639
1661
|
pageResponse.props = { ...page.get().props, ...pageResponse.props };
|
|
1640
1662
|
}
|
|
1641
|
-
mergeOrMatchItems(
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1644
|
-
|
|
1663
|
+
mergeOrMatchItems(existingItems, newItems, matchProp, matchPropsOn, shouldAppend = true) {
|
|
1664
|
+
const items = Array.isArray(existingItems) ? existingItems : [];
|
|
1665
|
+
const matchingKey = matchPropsOn.find((key) => {
|
|
1666
|
+
const keyPath = key.split(".").slice(0, -1).join(".");
|
|
1667
|
+
return keyPath === matchProp;
|
|
1645
1668
|
});
|
|
1646
|
-
if (!
|
|
1647
|
-
return [...
|
|
1648
|
-
}
|
|
1649
|
-
const uniqueProperty =
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
map.set(item[uniqueProperty], item);
|
|
1655
|
-
} else {
|
|
1656
|
-
map.set(Symbol(), item);
|
|
1669
|
+
if (!matchingKey) {
|
|
1670
|
+
return shouldAppend ? [...items, ...newItems] : [...newItems, ...items];
|
|
1671
|
+
}
|
|
1672
|
+
const uniqueProperty = matchingKey.split(".").pop() || "";
|
|
1673
|
+
const newItemsMap = /* @__PURE__ */ new Map();
|
|
1674
|
+
newItems.forEach((item) => {
|
|
1675
|
+
if (this.hasUniqueProperty(item, uniqueProperty)) {
|
|
1676
|
+
newItemsMap.set(item[uniqueProperty], item);
|
|
1657
1677
|
}
|
|
1658
1678
|
});
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1679
|
+
return shouldAppend ? this.appendWithMatching(items, newItems, newItemsMap, uniqueProperty) : this.prependWithMatching(items, newItems, newItemsMap, uniqueProperty);
|
|
1680
|
+
}
|
|
1681
|
+
appendWithMatching(existingItems, newItems, newItemsMap, uniqueProperty) {
|
|
1682
|
+
const updatedExisting = existingItems.map((item) => {
|
|
1683
|
+
if (this.hasUniqueProperty(item, uniqueProperty) && newItemsMap.has(item[uniqueProperty])) {
|
|
1684
|
+
return newItemsMap.get(item[uniqueProperty]);
|
|
1685
|
+
}
|
|
1686
|
+
return item;
|
|
1687
|
+
});
|
|
1688
|
+
const newItemsToAdd = newItems.filter((item) => {
|
|
1689
|
+
if (!this.hasUniqueProperty(item, uniqueProperty)) {
|
|
1690
|
+
return true;
|
|
1691
|
+
}
|
|
1692
|
+
return !existingItems.some(
|
|
1693
|
+
(existing) => this.hasUniqueProperty(existing, uniqueProperty) && existing[uniqueProperty] === item[uniqueProperty]
|
|
1694
|
+
);
|
|
1695
|
+
});
|
|
1696
|
+
return [...updatedExisting, ...newItemsToAdd];
|
|
1697
|
+
}
|
|
1698
|
+
prependWithMatching(existingItems, newItems, newItemsMap, uniqueProperty) {
|
|
1699
|
+
const untouchedExisting = existingItems.filter((item) => {
|
|
1700
|
+
if (this.hasUniqueProperty(item, uniqueProperty)) {
|
|
1701
|
+
return !newItemsMap.has(item[uniqueProperty]);
|
|
1664
1702
|
}
|
|
1703
|
+
return true;
|
|
1665
1704
|
});
|
|
1666
|
-
return
|
|
1705
|
+
return [...newItems, ...untouchedExisting];
|
|
1706
|
+
}
|
|
1707
|
+
hasUniqueProperty(item, property) {
|
|
1708
|
+
return item && typeof item === "object" && property in item;
|
|
1667
1709
|
}
|
|
1668
1710
|
async setRememberedState(pageResponse) {
|
|
1669
1711
|
const rememberedState = await history.getState(history.rememberedState, {});
|
|
@@ -2005,6 +2047,43 @@ var Router = class {
|
|
|
2005
2047
|
replace(params) {
|
|
2006
2048
|
this.clientVisit(params, { replace: true });
|
|
2007
2049
|
}
|
|
2050
|
+
replaceProp(name, value, options) {
|
|
2051
|
+
this.replace({
|
|
2052
|
+
preserveScroll: true,
|
|
2053
|
+
preserveState: true,
|
|
2054
|
+
props(currentProps) {
|
|
2055
|
+
const newValue = typeof value === "function" ? value((0, import_lodash_es3.get)(currentProps, name), currentProps) : value;
|
|
2056
|
+
return (0, import_lodash_es3.set)((0, import_lodash_es3.cloneDeep)(currentProps), name, newValue);
|
|
2057
|
+
},
|
|
2058
|
+
...options || {}
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
appendToProp(name, value, options) {
|
|
2062
|
+
this.replaceProp(
|
|
2063
|
+
name,
|
|
2064
|
+
(currentValue, currentProps) => {
|
|
2065
|
+
const newValue = typeof value === "function" ? value(currentValue, currentProps) : value;
|
|
2066
|
+
if (!Array.isArray(currentValue)) {
|
|
2067
|
+
currentValue = currentValue !== void 0 ? [currentValue] : [];
|
|
2068
|
+
}
|
|
2069
|
+
return [...currentValue, newValue];
|
|
2070
|
+
},
|
|
2071
|
+
options
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
2074
|
+
prependToProp(name, value, options) {
|
|
2075
|
+
this.replaceProp(
|
|
2076
|
+
name,
|
|
2077
|
+
(currentValue, currentProps) => {
|
|
2078
|
+
const newValue = typeof value === "function" ? value(currentValue, currentProps) : value;
|
|
2079
|
+
if (!Array.isArray(currentValue)) {
|
|
2080
|
+
currentValue = currentValue !== void 0 ? [currentValue] : [];
|
|
2081
|
+
}
|
|
2082
|
+
return [newValue, ...currentValue];
|
|
2083
|
+
},
|
|
2084
|
+
options
|
|
2085
|
+
);
|
|
2086
|
+
}
|
|
2008
2087
|
push(params) {
|
|
2009
2088
|
this.clientVisit(params);
|
|
2010
2089
|
}
|
|
@@ -2097,6 +2176,8 @@ var Router = class {
|
|
|
2097
2176
|
}),
|
|
2098
2177
|
onBefore: options.onBefore || (() => {
|
|
2099
2178
|
}),
|
|
2179
|
+
onBeforeUpdate: options.onBeforeUpdate || (() => {
|
|
2180
|
+
}),
|
|
2100
2181
|
onStart: options.onStart || (() => {
|
|
2101
2182
|
}),
|
|
2102
2183
|
onProgress: options.onProgress || (() => {
|
|
@@ -2124,8 +2205,48 @@ var Router = class {
|
|
|
2124
2205
|
}
|
|
2125
2206
|
};
|
|
2126
2207
|
|
|
2208
|
+
// src/domUtils.ts
|
|
2209
|
+
var elementInViewport = (el) => {
|
|
2210
|
+
const rect = el.getBoundingClientRect();
|
|
2211
|
+
const verticallyVisible = rect.top < window.innerHeight && rect.bottom >= 0;
|
|
2212
|
+
const horizontallyVisible = rect.left < window.innerWidth && rect.right >= 0;
|
|
2213
|
+
return verticallyVisible && horizontallyVisible;
|
|
2214
|
+
};
|
|
2215
|
+
var getScrollableParent = (element) => {
|
|
2216
|
+
let parent = element?.parentElement;
|
|
2217
|
+
while (parent) {
|
|
2218
|
+
const overflowY = window.getComputedStyle(parent).overflowY;
|
|
2219
|
+
if (overflowY === "auto" || overflowY === "scroll") {
|
|
2220
|
+
return parent;
|
|
2221
|
+
}
|
|
2222
|
+
parent = parent.parentElement;
|
|
2223
|
+
}
|
|
2224
|
+
return null;
|
|
2225
|
+
};
|
|
2226
|
+
var getElementsInViewportFromCollection = (referenceElement, elements) => {
|
|
2227
|
+
const referenceIndex = elements.indexOf(referenceElement);
|
|
2228
|
+
const visibleElements = [];
|
|
2229
|
+
for (let i = referenceIndex; i >= 0; i--) {
|
|
2230
|
+
const element = elements[i];
|
|
2231
|
+
if (elementInViewport(element)) {
|
|
2232
|
+
visibleElements.push(element);
|
|
2233
|
+
} else {
|
|
2234
|
+
break;
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
for (let i = referenceIndex + 1; i < elements.length; i++) {
|
|
2238
|
+
const element = elements[i];
|
|
2239
|
+
if (elementInViewport(element)) {
|
|
2240
|
+
visibleElements.push(element);
|
|
2241
|
+
} else {
|
|
2242
|
+
break;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
return visibleElements;
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2127
2248
|
// src/formObject.ts
|
|
2128
|
-
var
|
|
2249
|
+
var import_lodash_es4 = require("lodash-es");
|
|
2129
2250
|
function undotKey(key) {
|
|
2130
2251
|
if (!key.includes(".")) {
|
|
2131
2252
|
return key;
|
|
@@ -2160,15 +2281,15 @@ function formDataToObject(source) {
|
|
|
2160
2281
|
const path = parseKey(undotKey(key));
|
|
2161
2282
|
if (path[path.length - 1] === "") {
|
|
2162
2283
|
const arrayPath = path.slice(0, -1);
|
|
2163
|
-
const existing = (0,
|
|
2284
|
+
const existing = (0, import_lodash_es4.get)(form, arrayPath);
|
|
2164
2285
|
if (Array.isArray(existing)) {
|
|
2165
2286
|
existing.push(value);
|
|
2166
2287
|
} else {
|
|
2167
|
-
(0,
|
|
2288
|
+
(0, import_lodash_es4.set)(form, arrayPath, [value]);
|
|
2168
2289
|
}
|
|
2169
2290
|
continue;
|
|
2170
2291
|
}
|
|
2171
|
-
(0,
|
|
2292
|
+
(0, import_lodash_es4.set)(form, path, value);
|
|
2172
2293
|
}
|
|
2173
2294
|
return form;
|
|
2174
2295
|
}
|
|
@@ -2285,6 +2406,380 @@ function createHeadManager(isServer2, titleCallback, onUpdate) {
|
|
|
2285
2406
|
};
|
|
2286
2407
|
}
|
|
2287
2408
|
|
|
2409
|
+
// src/infiniteScroll/data.ts
|
|
2410
|
+
var MERGE_INTENT_HEADER = "X-Inertia-Infinite-Scroll-Merge-Intent";
|
|
2411
|
+
var useInfiniteScrollData = (options) => {
|
|
2412
|
+
const getScrollPropFromCurrentPage = () => {
|
|
2413
|
+
const scrollProp = page.get().scrollProps?.[options.getPropName()];
|
|
2414
|
+
if (scrollProp) {
|
|
2415
|
+
return scrollProp;
|
|
2416
|
+
}
|
|
2417
|
+
throw new Error(`The page object does not contain a scroll prop named "${options.getPropName()}".`);
|
|
2418
|
+
};
|
|
2419
|
+
const { previousPage, nextPage, currentPage: lastLoadedPage } = getScrollPropFromCurrentPage();
|
|
2420
|
+
const state = {
|
|
2421
|
+
loading: false,
|
|
2422
|
+
previousPage,
|
|
2423
|
+
nextPage,
|
|
2424
|
+
lastLoadedPage
|
|
2425
|
+
};
|
|
2426
|
+
const getScrollPropKeyForSide = (side) => {
|
|
2427
|
+
return side === "next" ? "nextPage" : "previousPage";
|
|
2428
|
+
};
|
|
2429
|
+
const findPageToLoad = (side) => {
|
|
2430
|
+
const pagePropName = getScrollPropKeyForSide(side);
|
|
2431
|
+
return state[pagePropName];
|
|
2432
|
+
};
|
|
2433
|
+
const syncStateOnSuccess = (side) => {
|
|
2434
|
+
const scrollProp = getScrollPropFromCurrentPage();
|
|
2435
|
+
const paginationProp = getScrollPropKeyForSide(side);
|
|
2436
|
+
state.lastLoadedPage = scrollProp.currentPage;
|
|
2437
|
+
state[paginationProp] = scrollProp[paginationProp];
|
|
2438
|
+
};
|
|
2439
|
+
const getPageName = () => getScrollPropFromCurrentPage().pageName;
|
|
2440
|
+
const fetchPage = (side, reloadOptions = {}) => {
|
|
2441
|
+
const page2 = findPageToLoad(side);
|
|
2442
|
+
if (state.loading || page2 === null) {
|
|
2443
|
+
return;
|
|
2444
|
+
}
|
|
2445
|
+
state.loading = true;
|
|
2446
|
+
router.reload({
|
|
2447
|
+
...reloadOptions,
|
|
2448
|
+
data: { [getPageName()]: page2 },
|
|
2449
|
+
only: [options.getPropName()],
|
|
2450
|
+
preserveUrl: true,
|
|
2451
|
+
// we handle URL updates manually via useInfiniteScrollQueryString()
|
|
2452
|
+
headers: {
|
|
2453
|
+
[MERGE_INTENT_HEADER]: side === "previous" ? "prepend" : "append",
|
|
2454
|
+
...reloadOptions.headers
|
|
2455
|
+
},
|
|
2456
|
+
onBefore: (visit) => {
|
|
2457
|
+
side === "next" ? options.onBeforeNextRequest() : options.onBeforePreviousRequest();
|
|
2458
|
+
reloadOptions.onBefore?.(visit);
|
|
2459
|
+
},
|
|
2460
|
+
onBeforeUpdate: (page3) => {
|
|
2461
|
+
options.onBeforeUpdate();
|
|
2462
|
+
reloadOptions.onBeforeUpdate?.(page3);
|
|
2463
|
+
},
|
|
2464
|
+
onSuccess: (page3) => {
|
|
2465
|
+
syncStateOnSuccess(side);
|
|
2466
|
+
reloadOptions.onSuccess?.(page3);
|
|
2467
|
+
},
|
|
2468
|
+
onFinish: (visit) => {
|
|
2469
|
+
state.loading = false;
|
|
2470
|
+
side === "next" ? options.onCompleteNextRequest(state.lastLoadedPage) : options.onCompletePreviousRequest(state.lastLoadedPage);
|
|
2471
|
+
reloadOptions.onFinish?.(visit);
|
|
2472
|
+
}
|
|
2473
|
+
});
|
|
2474
|
+
};
|
|
2475
|
+
const getLastLoadedPage = () => state.lastLoadedPage;
|
|
2476
|
+
const hasPrevious = () => !!state.previousPage;
|
|
2477
|
+
const hasNext = () => !!state.nextPage;
|
|
2478
|
+
const fetchPrevious = (reloadOptions) => fetchPage("previous", reloadOptions);
|
|
2479
|
+
const fetchNext = (reloadOptions) => fetchPage("next", reloadOptions);
|
|
2480
|
+
return {
|
|
2481
|
+
getLastLoadedPage,
|
|
2482
|
+
getPageName,
|
|
2483
|
+
hasPrevious,
|
|
2484
|
+
hasNext,
|
|
2485
|
+
fetchNext,
|
|
2486
|
+
fetchPrevious
|
|
2487
|
+
};
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
// src/intersectionObservers.ts
|
|
2491
|
+
var useIntersectionObservers = () => {
|
|
2492
|
+
const intersectionObservers = [];
|
|
2493
|
+
const newIntersectionObserver = (callback, options = {}) => {
|
|
2494
|
+
const observer = new IntersectionObserver((entries) => {
|
|
2495
|
+
for (const entry of entries) {
|
|
2496
|
+
if (entry.isIntersecting) {
|
|
2497
|
+
callback(entry);
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
}, options);
|
|
2501
|
+
intersectionObservers.push(observer);
|
|
2502
|
+
return observer;
|
|
2503
|
+
};
|
|
2504
|
+
const flushAll = () => {
|
|
2505
|
+
intersectionObservers.forEach((observer) => observer.disconnect());
|
|
2506
|
+
intersectionObservers.length = 0;
|
|
2507
|
+
};
|
|
2508
|
+
return {
|
|
2509
|
+
new: newIntersectionObserver,
|
|
2510
|
+
flushAll
|
|
2511
|
+
};
|
|
2512
|
+
};
|
|
2513
|
+
|
|
2514
|
+
// src/infiniteScroll/elements.ts
|
|
2515
|
+
var INFINITE_SCROLL_PAGE_KEY = "infiniteScrollPage";
|
|
2516
|
+
var INFINITE_SCROLL_IGNORE_KEY = "infiniteScrollIgnore";
|
|
2517
|
+
var getPageFromElement = (element) => element.dataset[INFINITE_SCROLL_PAGE_KEY];
|
|
2518
|
+
var useInfiniteScrollElementManager = (options) => {
|
|
2519
|
+
const intersectionObservers = useIntersectionObservers();
|
|
2520
|
+
let itemsObserver;
|
|
2521
|
+
let startElementObserver;
|
|
2522
|
+
let endElementObserver;
|
|
2523
|
+
let itemsMutationObserver;
|
|
2524
|
+
let triggersEnabled = false;
|
|
2525
|
+
const setupObservers = () => {
|
|
2526
|
+
itemsMutationObserver = new MutationObserver((mutations) => {
|
|
2527
|
+
mutations.forEach((mutation) => {
|
|
2528
|
+
mutation.addedNodes.forEach((node) => {
|
|
2529
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2530
|
+
addedElements.add(node);
|
|
2531
|
+
}
|
|
2532
|
+
});
|
|
2533
|
+
});
|
|
2534
|
+
});
|
|
2535
|
+
itemsMutationObserver.observe(options.getItemsElement(), { childList: true });
|
|
2536
|
+
itemsObserver = intersectionObservers.new(
|
|
2537
|
+
(entry) => options.onItemIntersected(entry.target),
|
|
2538
|
+
{ threshold: 0 }
|
|
2539
|
+
);
|
|
2540
|
+
const observerOptions = {
|
|
2541
|
+
root: options.getScrollableParent(),
|
|
2542
|
+
rootMargin: `${Math.max(1, options.getTriggerMargin())}px`
|
|
2543
|
+
};
|
|
2544
|
+
startElementObserver = intersectionObservers.new(options.onPreviousTriggered, observerOptions);
|
|
2545
|
+
endElementObserver = intersectionObservers.new(options.onNextTriggered, observerOptions);
|
|
2546
|
+
};
|
|
2547
|
+
const enableTriggers = () => {
|
|
2548
|
+
if (triggersEnabled) {
|
|
2549
|
+
disableTriggers();
|
|
2550
|
+
}
|
|
2551
|
+
const startElement = options.getStartElement();
|
|
2552
|
+
const endElement = options.getEndElement();
|
|
2553
|
+
if (startElement && options.shouldFetchPrevious()) {
|
|
2554
|
+
startElementObserver.observe(startElement);
|
|
2555
|
+
}
|
|
2556
|
+
if (endElement && options.shouldFetchNext()) {
|
|
2557
|
+
endElementObserver.observe(endElement);
|
|
2558
|
+
}
|
|
2559
|
+
triggersEnabled = true;
|
|
2560
|
+
};
|
|
2561
|
+
const disableTriggers = () => {
|
|
2562
|
+
if (!triggersEnabled) {
|
|
2563
|
+
return;
|
|
2564
|
+
}
|
|
2565
|
+
startElementObserver.disconnect();
|
|
2566
|
+
endElementObserver.disconnect();
|
|
2567
|
+
triggersEnabled = false;
|
|
2568
|
+
};
|
|
2569
|
+
const refreshTriggers = () => {
|
|
2570
|
+
if (triggersEnabled) {
|
|
2571
|
+
enableTriggers();
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
const flushAll = () => {
|
|
2575
|
+
intersectionObservers.flushAll();
|
|
2576
|
+
itemsMutationObserver?.disconnect();
|
|
2577
|
+
};
|
|
2578
|
+
const addedElements = /* @__PURE__ */ new Set();
|
|
2579
|
+
const elementIsUntagged = (element) => !(INFINITE_SCROLL_PAGE_KEY in element.dataset) && !(INFINITE_SCROLL_IGNORE_KEY in element.dataset);
|
|
2580
|
+
const processManuallyAddedElements = () => {
|
|
2581
|
+
Array.from(addedElements).forEach((element) => {
|
|
2582
|
+
if (elementIsUntagged(element)) {
|
|
2583
|
+
element.dataset[INFINITE_SCROLL_IGNORE_KEY] = "true";
|
|
2584
|
+
}
|
|
2585
|
+
itemsObserver.observe(element);
|
|
2586
|
+
});
|
|
2587
|
+
addedElements.clear();
|
|
2588
|
+
};
|
|
2589
|
+
const findUntaggedElements = (containerElement) => {
|
|
2590
|
+
return Array.from(
|
|
2591
|
+
containerElement.querySelectorAll(
|
|
2592
|
+
`:scope > *:not([data-infinite-scroll-page]):not([data-infinite-scroll-ignore])`
|
|
2593
|
+
)
|
|
2594
|
+
);
|
|
2595
|
+
};
|
|
2596
|
+
const processServerLoadedElements = (loadedPage) => {
|
|
2597
|
+
findUntaggedElements(options.getItemsElement()).forEach((element) => {
|
|
2598
|
+
if (elementIsUntagged(element)) {
|
|
2599
|
+
element.dataset[INFINITE_SCROLL_PAGE_KEY] = loadedPage?.toString() || "1";
|
|
2600
|
+
}
|
|
2601
|
+
itemsObserver.observe(element);
|
|
2602
|
+
});
|
|
2603
|
+
};
|
|
2604
|
+
return {
|
|
2605
|
+
setupObservers,
|
|
2606
|
+
enableTriggers,
|
|
2607
|
+
disableTriggers,
|
|
2608
|
+
refreshTriggers,
|
|
2609
|
+
flushAll,
|
|
2610
|
+
processManuallyAddedElements,
|
|
2611
|
+
processServerLoadedElements
|
|
2612
|
+
};
|
|
2613
|
+
};
|
|
2614
|
+
|
|
2615
|
+
// src/infiniteScroll/queryString.ts
|
|
2616
|
+
var useInfiniteScrollQueryString = (options) => {
|
|
2617
|
+
const onItemIntersected = debounce((itemElement) => {
|
|
2618
|
+
if (options.shouldPreserveUrl() || !itemElement) {
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
const pageMap = /* @__PURE__ */ new Map();
|
|
2622
|
+
const elements = [...options.getItemsElement().children];
|
|
2623
|
+
getElementsInViewportFromCollection(itemElement, elements).forEach((element) => {
|
|
2624
|
+
const page2 = getPageFromElement(element) ?? "1";
|
|
2625
|
+
if (pageMap.has(page2)) {
|
|
2626
|
+
pageMap.set(page2, pageMap.get(page2) + 1);
|
|
2627
|
+
} else {
|
|
2628
|
+
pageMap.set(page2, 1);
|
|
2629
|
+
}
|
|
2630
|
+
});
|
|
2631
|
+
const sortedPages = Array.from(pageMap.entries()).sort((a, b) => b[1] - a[1]);
|
|
2632
|
+
const mostVisiblePage = sortedPages[0]?.[0];
|
|
2633
|
+
if (mostVisiblePage === void 0) {
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
const url = new URL(window.location.href);
|
|
2637
|
+
if (mostVisiblePage === "1") {
|
|
2638
|
+
url.searchParams.delete(options.getPageName());
|
|
2639
|
+
} else {
|
|
2640
|
+
url.searchParams.set(options.getPageName(), mostVisiblePage.toString());
|
|
2641
|
+
}
|
|
2642
|
+
router.replace({
|
|
2643
|
+
url: url.toString(),
|
|
2644
|
+
preserveScroll: true,
|
|
2645
|
+
preserveState: true
|
|
2646
|
+
});
|
|
2647
|
+
}, 250);
|
|
2648
|
+
return {
|
|
2649
|
+
onItemIntersected
|
|
2650
|
+
};
|
|
2651
|
+
};
|
|
2652
|
+
|
|
2653
|
+
// src/infiniteScroll/scrollPreservation.ts
|
|
2654
|
+
var useInfiniteScrollPreservation = (options) => {
|
|
2655
|
+
const createCallbacks = () => {
|
|
2656
|
+
let currentScrollTop;
|
|
2657
|
+
let referenceElement = null;
|
|
2658
|
+
let referenceElementTop = 0;
|
|
2659
|
+
const captureScrollPosition = () => {
|
|
2660
|
+
const scrollableContainer = options.getScrollableParent();
|
|
2661
|
+
const itemsElement = options.getItemsElement();
|
|
2662
|
+
currentScrollTop = scrollableContainer?.scrollTop || window.scrollY;
|
|
2663
|
+
const visibleElements = getElementsInViewportFromCollection(
|
|
2664
|
+
itemsElement.firstElementChild,
|
|
2665
|
+
[...itemsElement.children]
|
|
2666
|
+
);
|
|
2667
|
+
if (visibleElements.length > 0) {
|
|
2668
|
+
referenceElement = visibleElements[0];
|
|
2669
|
+
const containerRect = scrollableContainer?.getBoundingClientRect() || { top: 0 };
|
|
2670
|
+
const containerTop = scrollableContainer ? containerRect.top : 0;
|
|
2671
|
+
const rect = referenceElement.getBoundingClientRect();
|
|
2672
|
+
referenceElementTop = rect.top - containerTop;
|
|
2673
|
+
}
|
|
2674
|
+
};
|
|
2675
|
+
const restoreScrollPosition = () => {
|
|
2676
|
+
if (!referenceElement) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
let attempts = 0;
|
|
2680
|
+
let restored = false;
|
|
2681
|
+
const restore = () => {
|
|
2682
|
+
attempts++;
|
|
2683
|
+
if (restored || attempts > 10) {
|
|
2684
|
+
return false;
|
|
2685
|
+
}
|
|
2686
|
+
const scrollableContainer = options.getScrollableParent();
|
|
2687
|
+
const containerRect = scrollableContainer?.getBoundingClientRect() || { top: 0 };
|
|
2688
|
+
const containerTop = scrollableContainer ? containerRect.top : 0;
|
|
2689
|
+
const newRect = referenceElement.getBoundingClientRect();
|
|
2690
|
+
const newElementTop = newRect.top - containerTop;
|
|
2691
|
+
const adjustment = newElementTop - referenceElementTop;
|
|
2692
|
+
if (adjustment === 0) {
|
|
2693
|
+
window.requestAnimationFrame(restore);
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
if (scrollableContainer) {
|
|
2697
|
+
scrollableContainer.scrollTo({ top: currentScrollTop + adjustment });
|
|
2698
|
+
} else {
|
|
2699
|
+
window.scrollTo(0, window.scrollY + adjustment);
|
|
2700
|
+
}
|
|
2701
|
+
restored = true;
|
|
2702
|
+
};
|
|
2703
|
+
restore();
|
|
2704
|
+
};
|
|
2705
|
+
return {
|
|
2706
|
+
captureScrollPosition,
|
|
2707
|
+
restoreScrollPosition
|
|
2708
|
+
};
|
|
2709
|
+
};
|
|
2710
|
+
return {
|
|
2711
|
+
createCallbacks
|
|
2712
|
+
};
|
|
2713
|
+
};
|
|
2714
|
+
|
|
2715
|
+
// src/infiniteScroll.ts
|
|
2716
|
+
function useInfiniteScroll(options) {
|
|
2717
|
+
const queryStringManager = useInfiniteScrollQueryString({ ...options, getPageName: () => dataManager.getPageName() });
|
|
2718
|
+
const scrollPreservation = useInfiniteScrollPreservation(options);
|
|
2719
|
+
const elementManager = useInfiniteScrollElementManager({
|
|
2720
|
+
...options,
|
|
2721
|
+
// As items enter viewport, update URL to reflect the most visible page
|
|
2722
|
+
onItemIntersected: queryStringManager.onItemIntersected,
|
|
2723
|
+
onPreviousTriggered: () => dataManager.fetchPrevious(),
|
|
2724
|
+
onNextTriggered: () => dataManager.fetchNext()
|
|
2725
|
+
});
|
|
2726
|
+
const dataManager = useInfiniteScrollData({
|
|
2727
|
+
...options,
|
|
2728
|
+
// Before updating page data, tag any manually added DOM elements
|
|
2729
|
+
// so they don't get confused with server-loaded content
|
|
2730
|
+
onBeforeUpdate: elementManager.processManuallyAddedElements,
|
|
2731
|
+
// After successful request, tag new server content
|
|
2732
|
+
onCompletePreviousRequest: (loadedPage) => {
|
|
2733
|
+
setTimeout(() => {
|
|
2734
|
+
elementManager.processServerLoadedElements(loadedPage);
|
|
2735
|
+
options.onCompletePreviousRequest();
|
|
2736
|
+
window.queueMicrotask(elementManager.refreshTriggers);
|
|
2737
|
+
});
|
|
2738
|
+
},
|
|
2739
|
+
onCompleteNextRequest: (loadedPage) => {
|
|
2740
|
+
setTimeout(() => {
|
|
2741
|
+
elementManager.processServerLoadedElements(loadedPage);
|
|
2742
|
+
options.onCompleteNextRequest();
|
|
2743
|
+
window.queueMicrotask(elementManager.refreshTriggers);
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
});
|
|
2747
|
+
const addScrollPreservationCallbacks = (reloadOptions) => {
|
|
2748
|
+
const { captureScrollPosition, restoreScrollPosition } = scrollPreservation.createCallbacks();
|
|
2749
|
+
const originalOnBeforeUpdate = reloadOptions.onBeforeUpdate || (() => {
|
|
2750
|
+
});
|
|
2751
|
+
const originalOnSuccess = reloadOptions.onSuccess || (() => {
|
|
2752
|
+
});
|
|
2753
|
+
reloadOptions.onBeforeUpdate = (page2) => {
|
|
2754
|
+
originalOnBeforeUpdate(page2);
|
|
2755
|
+
captureScrollPosition();
|
|
2756
|
+
};
|
|
2757
|
+
reloadOptions.onSuccess = (page2) => {
|
|
2758
|
+
originalOnSuccess(page2);
|
|
2759
|
+
restoreScrollPosition();
|
|
2760
|
+
};
|
|
2761
|
+
return reloadOptions;
|
|
2762
|
+
};
|
|
2763
|
+
const originalFetchNext = dataManager.fetchNext;
|
|
2764
|
+
dataManager.fetchNext = (reloadOptions = {}) => {
|
|
2765
|
+
if (options.inReverseMode()) {
|
|
2766
|
+
reloadOptions = addScrollPreservationCallbacks(reloadOptions);
|
|
2767
|
+
}
|
|
2768
|
+
originalFetchNext(reloadOptions);
|
|
2769
|
+
};
|
|
2770
|
+
const originalFetchPrevious = dataManager.fetchPrevious;
|
|
2771
|
+
dataManager.fetchPrevious = (reloadOptions = {}) => {
|
|
2772
|
+
if (!options.inReverseMode()) {
|
|
2773
|
+
reloadOptions = addScrollPreservationCallbacks(reloadOptions);
|
|
2774
|
+
}
|
|
2775
|
+
originalFetchPrevious(reloadOptions);
|
|
2776
|
+
};
|
|
2777
|
+
return {
|
|
2778
|
+
dataManager,
|
|
2779
|
+
elementManager
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2288
2783
|
// src/navigationEvents.ts
|
|
2289
2784
|
function shouldIntercept(event) {
|
|
2290
2785
|
const isLink = event.currentTarget.tagName.toLowerCase() === "a";
|
|
@@ -2330,7 +2825,7 @@ var configure = (options) => {
|
|
|
2330
2825
|
progress2.id = baseComponentSelector;
|
|
2331
2826
|
progress2.innerHTML = settings.template;
|
|
2332
2827
|
};
|
|
2333
|
-
var
|
|
2828
|
+
var set4 = (n) => {
|
|
2334
2829
|
const started = isStarted();
|
|
2335
2830
|
n = clamp(n, settings.minimum, 1);
|
|
2336
2831
|
status = n === 1 ? null : n;
|
|
@@ -2379,7 +2874,7 @@ var set2 = (n) => {
|
|
|
2379
2874
|
var isStarted = () => typeof status === "number";
|
|
2380
2875
|
var start = () => {
|
|
2381
2876
|
if (!status) {
|
|
2382
|
-
|
|
2877
|
+
set4(0);
|
|
2383
2878
|
}
|
|
2384
2879
|
const work = function() {
|
|
2385
2880
|
setTimeout(function() {
|
|
@@ -2399,7 +2894,7 @@ var done = (force) => {
|
|
|
2399
2894
|
return;
|
|
2400
2895
|
}
|
|
2401
2896
|
increaseByRandom(0.3 + 0.5 * Math.random());
|
|
2402
|
-
|
|
2897
|
+
set4(1);
|
|
2403
2898
|
};
|
|
2404
2899
|
var increaseByRandom = (amount) => {
|
|
2405
2900
|
const n = status;
|
|
@@ -2423,7 +2918,7 @@ var increaseByRandom = (amount) => {
|
|
|
2423
2918
|
}
|
|
2424
2919
|
return 0;
|
|
2425
2920
|
})();
|
|
2426
|
-
return
|
|
2921
|
+
return set4(clamp(n + amount, 0, 0.994));
|
|
2427
2922
|
};
|
|
2428
2923
|
var render = (fromStart) => {
|
|
2429
2924
|
if (isRendered()) {
|
|
@@ -2569,7 +3064,7 @@ var progress_component_default = {
|
|
|
2569
3064
|
configure,
|
|
2570
3065
|
isStarted,
|
|
2571
3066
|
done,
|
|
2572
|
-
set:
|
|
3067
|
+
set: set4,
|
|
2573
3068
|
remove,
|
|
2574
3069
|
start,
|
|
2575
3070
|
status,
|