@async/framework 0.11.14 → 0.11.16
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/CHANGELOG.md +42 -3
- package/README.md +101 -14
- package/browser.d.ts +42 -2
- package/browser.js +288 -16
- package/browser.min.js +1 -1
- package/browser.ts +288 -16
- package/browser.umd.js +288 -16
- package/browser.umd.min.js +1 -1
- package/framework.d.ts +42 -2
- package/framework.ts +288 -16
- package/package.json +23 -68
- package/runtime/events.d.ts +48 -0
- package/runtime/events.js +208 -0
- package/runtime/shared.js +85 -0
- package/runtime/signals.d.ts +31 -0
- package/runtime/signals.js +209 -0
- package/runtime.d.ts +72 -0
- package/runtime.js +63 -0
- package/server.js +288 -16
package/browser.js
CHANGED
|
@@ -1161,6 +1161,7 @@ const __attributesModule = (() => {
|
|
|
1161
1161
|
async: ["async:"],
|
|
1162
1162
|
class: ["class:"],
|
|
1163
1163
|
signal: ["signal:"],
|
|
1164
|
+
intersect: ["intersect:"],
|
|
1164
1165
|
on: ["on:"]
|
|
1165
1166
|
});
|
|
1166
1167
|
|
|
@@ -1173,6 +1174,7 @@ const __attributesModule = (() => {
|
|
|
1173
1174
|
async: normalizePrefixes(config.async, defaultPrefixes.async),
|
|
1174
1175
|
class: normalizePrefixes(config.class, defaultPrefixes.class),
|
|
1175
1176
|
signal: normalizePrefixes(config.signal, defaultPrefixes.signal),
|
|
1177
|
+
intersect: normalizePrefixes(config.intersect, defaultPrefixes.intersect),
|
|
1176
1178
|
on: normalizePrefixes(config.on, defaultPrefixes.on)
|
|
1177
1179
|
};
|
|
1178
1180
|
}
|
|
@@ -2138,6 +2140,7 @@ const __componentModule = (() => {
|
|
|
2138
2140
|
const cleanups = [];
|
|
2139
2141
|
const attachHooks = [];
|
|
2140
2142
|
const visibleHooks = [];
|
|
2143
|
+
const intersectionHooks = [];
|
|
2141
2144
|
const destroyHooks = [];
|
|
2142
2145
|
const bindingIds = [];
|
|
2143
2146
|
const templateOptions = {
|
|
@@ -2159,6 +2162,7 @@ const __componentModule = (() => {
|
|
|
2159
2162
|
cleanups,
|
|
2160
2163
|
attachHooks,
|
|
2161
2164
|
visibleHooks,
|
|
2165
|
+
intersectionHooks,
|
|
2162
2166
|
destroyHooks,
|
|
2163
2167
|
renderScopedTemplate
|
|
2164
2168
|
});
|
|
@@ -2210,6 +2214,15 @@ const __componentModule = (() => {
|
|
|
2210
2214
|
cleanups.push(cleanup);
|
|
2211
2215
|
}
|
|
2212
2216
|
},
|
|
2217
|
+
intersection(target, observeIntersection) {
|
|
2218
|
+
if (intersectionHooks.length === 0) {
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
for (let index = 0; index < intersectionHooks.length; index += 1) {
|
|
2222
|
+
const hook = intersectionHooks[index];
|
|
2223
|
+
hook(target, observeIntersection);
|
|
2224
|
+
}
|
|
2225
|
+
},
|
|
2213
2226
|
cleanup() {
|
|
2214
2227
|
while (destroyHooks.length > 0) {
|
|
2215
2228
|
destroyHooks.pop()?.();
|
|
@@ -2239,7 +2252,7 @@ const __componentModule = (() => {
|
|
|
2239
2252
|
}
|
|
2240
2253
|
}
|
|
2241
2254
|
|
|
2242
|
-
function createComponentContext({ runtime, scope, cleanups, attachHooks, visibleHooks, destroyHooks, renderScopedTemplate }) {
|
|
2255
|
+
function createComponentContext({ runtime, scope, cleanups, attachHooks, visibleHooks, intersectionHooks, destroyHooks, renderScopedTemplate }) {
|
|
2243
2256
|
const { signals, handlers, loader, server, router, cache, scheduler } = runtime;
|
|
2244
2257
|
const generatedHandlers = new WeakMap();
|
|
2245
2258
|
let generatedHandlerCounter = 0;
|
|
@@ -2327,6 +2340,7 @@ const __componentModule = (() => {
|
|
|
2327
2340
|
cleanups.push(child.cleanup);
|
|
2328
2341
|
attachHooks.push((target) => child.attach(target));
|
|
2329
2342
|
visibleHooks.push((target) => child.visible(target, loader._observeVisible));
|
|
2343
|
+
intersectionHooks.push((target) => child.intersection(target, loader._observeIntersection));
|
|
2330
2344
|
return rawHtml(child.html);
|
|
2331
2345
|
},
|
|
2332
2346
|
|
|
@@ -2350,14 +2364,22 @@ const __componentModule = (() => {
|
|
|
2350
2364
|
return rawHtml(chunks.join(""));
|
|
2351
2365
|
},
|
|
2352
2366
|
|
|
2353
|
-
on(eventName,
|
|
2367
|
+
on(eventName, optionsOrFn, maybeFn) {
|
|
2354
2368
|
if (typeof eventName !== "string" || eventName.length === 0) {
|
|
2355
2369
|
throw new TypeError("Component lifecycle event must be a non-empty string.");
|
|
2356
2370
|
}
|
|
2357
|
-
|
|
2371
|
+
const event = eventName === "mount" ? "attach" : eventName;
|
|
2372
|
+
if (event === "intersect") {
|
|
2373
|
+
const { options, fn } = normalizeOptionsCallback(`Component lifecycle "${eventName}"`, optionsOrFn, maybeFn);
|
|
2374
|
+
intersectionHooks.push((target) => {
|
|
2375
|
+
context.intersect(target, options, fn);
|
|
2376
|
+
});
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
if (maybeFn !== undefined || typeof optionsOrFn !== "function") {
|
|
2358
2380
|
throw new TypeError(`Component lifecycle "${eventName}" requires a function.`);
|
|
2359
2381
|
}
|
|
2360
|
-
const
|
|
2382
|
+
const fn = optionsOrFn;
|
|
2361
2383
|
if (event === "attach") {
|
|
2362
2384
|
attachHooks.push((target) => fn.call(context, target));
|
|
2363
2385
|
return;
|
|
@@ -2379,6 +2401,18 @@ const __componentModule = (() => {
|
|
|
2379
2401
|
|
|
2380
2402
|
onVisible(fn) {
|
|
2381
2403
|
context.on("visible", fn);
|
|
2404
|
+
},
|
|
2405
|
+
|
|
2406
|
+
intersect(target, optionsOrFn, maybeFn) {
|
|
2407
|
+
const { options, fn } = normalizeOptionsCallback("this.intersect(target, ...)", optionsOrFn, maybeFn);
|
|
2408
|
+
const cleanup = loader._observeIntersection(target, (event) => fn.call(context, event), {
|
|
2409
|
+
...options,
|
|
2410
|
+
scope
|
|
2411
|
+
});
|
|
2412
|
+
if (typeof cleanup === "function") {
|
|
2413
|
+
cleanups.push(cleanup);
|
|
2414
|
+
}
|
|
2415
|
+
return cleanup;
|
|
2382
2416
|
}
|
|
2383
2417
|
};
|
|
2384
2418
|
|
|
@@ -2394,6 +2428,16 @@ const __componentModule = (() => {
|
|
|
2394
2428
|
}
|
|
2395
2429
|
}
|
|
2396
2430
|
|
|
2431
|
+
function normalizeOptionsCallback(label, optionsOrFn, maybeFn) {
|
|
2432
|
+
if (typeof optionsOrFn === "function" && maybeFn === undefined) {
|
|
2433
|
+
return { options: {}, fn: optionsOrFn };
|
|
2434
|
+
}
|
|
2435
|
+
if ((optionsOrFn == null || (typeof optionsOrFn === "object" && !Array.isArray(optionsOrFn))) && typeof maybeFn === "function") {
|
|
2436
|
+
return { options: optionsOrFn ?? {}, fn: maybeFn };
|
|
2437
|
+
}
|
|
2438
|
+
throw new TypeError(`${label} requires (fn) or (options, fn).`);
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2397
2441
|
function scoped(scope, name) {
|
|
2398
2442
|
if (typeof name !== "string" || name.length === 0) {
|
|
2399
2443
|
throw new TypeError("Scoped signal or handler name must be a non-empty string.");
|
|
@@ -3489,6 +3533,7 @@ const __loaderModule = (() => {
|
|
|
3489
3533
|
const signalBindings = new WeakMap();
|
|
3490
3534
|
const mountedElements = new WeakSet();
|
|
3491
3535
|
const visibleElements = new WeakSet();
|
|
3536
|
+
const intersectionBindings = new WeakMap();
|
|
3492
3537
|
const boundaryState = new WeakMap();
|
|
3493
3538
|
const renderingBoundaries = new WeakSet();
|
|
3494
3539
|
const inlineBindings = new Map();
|
|
@@ -3552,6 +3597,7 @@ const __loaderModule = (() => {
|
|
|
3552
3597
|
api.scan(target);
|
|
3553
3598
|
rendered.mount(target);
|
|
3554
3599
|
rendered.visible(target, api._observeVisible);
|
|
3600
|
+
rendered.intersection(target, api._observeIntersection);
|
|
3555
3601
|
addCleanup(rendered.cleanup, target, "children");
|
|
3556
3602
|
return rendered;
|
|
3557
3603
|
},
|
|
@@ -3575,6 +3621,10 @@ const __loaderModule = (() => {
|
|
|
3575
3621
|
return observeVisible(target, fn);
|
|
3576
3622
|
},
|
|
3577
3623
|
|
|
3624
|
+
_observeIntersection(target, fn, options = {}) {
|
|
3625
|
+
return observeIntersection(target, fn, options);
|
|
3626
|
+
},
|
|
3627
|
+
|
|
3578
3628
|
_registerBinding(value) {
|
|
3579
3629
|
const id = `${inlineBindingPrefix}${++inlineBindingCounter}`;
|
|
3580
3630
|
inlineBindings.set(id, value);
|
|
@@ -3606,7 +3656,7 @@ const __loaderModule = (() => {
|
|
|
3606
3656
|
if (!eventName) {
|
|
3607
3657
|
continue;
|
|
3608
3658
|
}
|
|
3609
|
-
if (eventName === "attach" || eventName === "mount" || eventName === "visible") {
|
|
3659
|
+
if (eventName === "attach" || eventName === "mount" || eventName === "visible" || eventName === "intersect") {
|
|
3610
3660
|
continue;
|
|
3611
3661
|
}
|
|
3612
3662
|
bindEvent(element, eventName, element.getAttribute(name));
|
|
@@ -3879,6 +3929,25 @@ const __loaderModule = (() => {
|
|
|
3879
3929
|
visibleElements.add(element);
|
|
3880
3930
|
addCleanup(observeVisible(element, () => scheduleLifecycle(element, () => runPseudo(element, ref), `visible:${ref}`)), element);
|
|
3881
3931
|
}
|
|
3932
|
+
|
|
3933
|
+
for (const element of elementsIn(scope)) {
|
|
3934
|
+
const ref = readAttribute(element, attributeConfig, "on", "intersect");
|
|
3935
|
+
if (ref == null) {
|
|
3936
|
+
continue;
|
|
3937
|
+
}
|
|
3938
|
+
const options = readIntersectionOptions(element);
|
|
3939
|
+
const key = `intersect:${ref}:${serializeIntersectionOptions(options)}`;
|
|
3940
|
+
const bound = intersectionBindings.get(element) ?? new Set();
|
|
3941
|
+
if (bound.has(key)) {
|
|
3942
|
+
continue;
|
|
3943
|
+
}
|
|
3944
|
+
bound.add(key);
|
|
3945
|
+
intersectionBindings.set(element, bound);
|
|
3946
|
+
addCleanup(observeIntersection(element, (event) => runPseudo(element, ref, event), {
|
|
3947
|
+
...options,
|
|
3948
|
+
key
|
|
3949
|
+
}), element);
|
|
3950
|
+
}
|
|
3882
3951
|
}
|
|
3883
3952
|
|
|
3884
3953
|
function readPseudoRefs(element, names) {
|
|
@@ -3892,7 +3961,7 @@ const __loaderModule = (() => {
|
|
|
3892
3961
|
return refs;
|
|
3893
3962
|
}
|
|
3894
3963
|
|
|
3895
|
-
async function runPseudo(element, ref) {
|
|
3964
|
+
async function runPseudo(element, ref, context = {}) {
|
|
3896
3965
|
try {
|
|
3897
3966
|
const results = await handlerRegistry.run(ref, {
|
|
3898
3967
|
signals: signalRegistry,
|
|
@@ -3904,7 +3973,8 @@ const __loaderModule = (() => {
|
|
|
3904
3973
|
scheduler: schedulerInstance,
|
|
3905
3974
|
element,
|
|
3906
3975
|
el: element,
|
|
3907
|
-
root: rootNode
|
|
3976
|
+
root: rootNode,
|
|
3977
|
+
...context
|
|
3908
3978
|
});
|
|
3909
3979
|
for (const result of results) {
|
|
3910
3980
|
if (typeof result === "function") {
|
|
@@ -3917,28 +3987,230 @@ const __loaderModule = (() => {
|
|
|
3917
3987
|
}
|
|
3918
3988
|
|
|
3919
3989
|
function observeVisible(target, fn) {
|
|
3990
|
+
return observeIntersection(target, (event) => {
|
|
3991
|
+
if (event.isIntersecting) {
|
|
3992
|
+
fn(target);
|
|
3993
|
+
}
|
|
3994
|
+
}, {
|
|
3995
|
+
once: true,
|
|
3996
|
+
threshold: 0
|
|
3997
|
+
});
|
|
3998
|
+
}
|
|
3999
|
+
|
|
4000
|
+
function observeIntersection(target, fn, options = {}) {
|
|
4001
|
+
if (typeof fn !== "function") {
|
|
4002
|
+
throw new TypeError("observeIntersection(target, fn) requires a callback.");
|
|
4003
|
+
}
|
|
4004
|
+
const normalized = normalizeIntersectionOptions(target, options);
|
|
3920
4005
|
const ownerWindow = target.ownerDocument?.defaultView ?? globalThis;
|
|
3921
4006
|
const Observer = ownerWindow.IntersectionObserver ?? globalThis.IntersectionObserver;
|
|
3922
4007
|
if (!Observer) {
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
4008
|
+
let cleaned = false;
|
|
4009
|
+
const event = createIntersectionEvent({
|
|
4010
|
+
target,
|
|
4011
|
+
root: normalized.root,
|
|
4012
|
+
entry: createFallbackIntersectionEntry(target),
|
|
4013
|
+
observer: null,
|
|
4014
|
+
unsupported: true
|
|
4015
|
+
});
|
|
4016
|
+
const cancel = schedulerInstance.enqueue("lifecycle", () => {
|
|
4017
|
+
if (!cleaned && !destroyed) {
|
|
4018
|
+
fn(event);
|
|
3926
4019
|
}
|
|
3927
4020
|
}, {
|
|
3928
|
-
scope:
|
|
3929
|
-
key: "
|
|
4021
|
+
scope: normalized.scope,
|
|
4022
|
+
key: normalized.key ?? "intersect:fallback"
|
|
3930
4023
|
});
|
|
3931
|
-
return () => {
|
|
4024
|
+
return () => {
|
|
4025
|
+
cleaned = true;
|
|
4026
|
+
cancel?.();
|
|
4027
|
+
};
|
|
3932
4028
|
}
|
|
3933
4029
|
|
|
4030
|
+
let cleaned = false;
|
|
4031
|
+
let stopped = false;
|
|
3934
4032
|
const observer = new Observer((entries) => {
|
|
3935
|
-
if (
|
|
4033
|
+
if (cleaned || stopped || destroyed) {
|
|
4034
|
+
return;
|
|
4035
|
+
}
|
|
4036
|
+
const observedEntries = entries.filter((entry) => entry.target === target);
|
|
4037
|
+
const targetEntries = observedEntries.length > 0 ? observedEntries : entries;
|
|
4038
|
+
const entry = targetEntries[0];
|
|
4039
|
+
if (!entry) {
|
|
4040
|
+
return;
|
|
4041
|
+
}
|
|
4042
|
+
const event = createIntersectionEvent({
|
|
4043
|
+
target,
|
|
4044
|
+
root: normalized.root,
|
|
4045
|
+
entry,
|
|
4046
|
+
entries: targetEntries,
|
|
4047
|
+
observer,
|
|
4048
|
+
unsupported: false
|
|
4049
|
+
});
|
|
4050
|
+
if (normalized.once && event.isIntersecting) {
|
|
4051
|
+
stopped = true;
|
|
3936
4052
|
observer.disconnect();
|
|
3937
|
-
fn(target);
|
|
3938
4053
|
}
|
|
4054
|
+
runIntersectionCallback(fn, event, normalized, () => !cleaned);
|
|
4055
|
+
}, {
|
|
4056
|
+
root: normalized.root,
|
|
4057
|
+
rootMargin: normalized.rootMargin,
|
|
4058
|
+
threshold: normalized.threshold
|
|
3939
4059
|
});
|
|
3940
4060
|
observer.observe(target);
|
|
3941
|
-
return () =>
|
|
4061
|
+
return () => {
|
|
4062
|
+
if (cleaned) {
|
|
4063
|
+
return;
|
|
4064
|
+
}
|
|
4065
|
+
cleaned = true;
|
|
4066
|
+
stopped = true;
|
|
4067
|
+
observer.disconnect();
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
function readIntersectionOptions(element) {
|
|
4072
|
+
const options = {};
|
|
4073
|
+
const threshold = readAttribute(element, attributeConfig, "intersect", "threshold");
|
|
4074
|
+
if (threshold != null) {
|
|
4075
|
+
options.threshold = parseIntersectionThreshold(threshold);
|
|
4076
|
+
}
|
|
4077
|
+
const rootMargin = readAttribute(element, attributeConfig, "intersect", "root-margin")
|
|
4078
|
+
?? readAttribute(element, attributeConfig, "intersect", "rootMargin");
|
|
4079
|
+
if (rootMargin != null) {
|
|
4080
|
+
options.rootMargin = rootMargin;
|
|
4081
|
+
}
|
|
4082
|
+
const once = readAttribute(element, attributeConfig, "intersect", "once");
|
|
4083
|
+
if (once != null) {
|
|
4084
|
+
options.once = parseBooleanAttribute(once);
|
|
4085
|
+
}
|
|
4086
|
+
return options;
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4089
|
+
function parseIntersectionThreshold(value) {
|
|
4090
|
+
const parts = String(value).split(",").map((part) => part.trim()).filter(Boolean);
|
|
4091
|
+
if (parts.length === 0) {
|
|
4092
|
+
throw new TypeError("intersect:threshold must include a number from 0 to 1.");
|
|
4093
|
+
}
|
|
4094
|
+
const thresholds = parts.map((part) => {
|
|
4095
|
+
const number = Number(part);
|
|
4096
|
+
return validateIntersectionThreshold(number);
|
|
4097
|
+
});
|
|
4098
|
+
return thresholds.length === 1 ? thresholds[0] : thresholds;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4101
|
+
function parseBooleanAttribute(value) {
|
|
4102
|
+
const normalized = String(value).trim().toLowerCase();
|
|
4103
|
+
return normalized === "" || normalized === "true" || normalized === "1";
|
|
4104
|
+
}
|
|
4105
|
+
|
|
4106
|
+
function serializeIntersectionOptions(options) {
|
|
4107
|
+
return JSON.stringify({
|
|
4108
|
+
rootMargin: options.rootMargin ?? "0px",
|
|
4109
|
+
threshold: options.threshold ?? 0,
|
|
4110
|
+
once: Boolean(options.once)
|
|
4111
|
+
});
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
function normalizeIntersectionOptions(target, options) {
|
|
4115
|
+
const ownerWindow = target?.ownerDocument?.defaultView ?? globalThis;
|
|
4116
|
+
if (!isElement(target, ownerWindow)) {
|
|
4117
|
+
throw new TypeError("Intersection target must be an Element.");
|
|
4118
|
+
}
|
|
4119
|
+
const root = options.root ?? null;
|
|
4120
|
+
if (root !== null && !isElement(root, ownerWindow) && !isDocument(root, ownerWindow)) {
|
|
4121
|
+
throw new TypeError("Intersection root must be an Element, Document, or null.");
|
|
4122
|
+
}
|
|
4123
|
+
const rootMargin = options.rootMargin ?? "0px";
|
|
4124
|
+
if (typeof rootMargin !== "string") {
|
|
4125
|
+
throw new TypeError("Intersection rootMargin must be a string.");
|
|
4126
|
+
}
|
|
4127
|
+
const threshold = normalizeIntersectionThreshold(options.threshold ?? 0);
|
|
4128
|
+
const schedule = options.schedule ?? "lifecycle";
|
|
4129
|
+
if (schedule !== "lifecycle" && schedule !== "sync") {
|
|
4130
|
+
throw new TypeError('Intersection schedule must be "lifecycle" or "sync".');
|
|
4131
|
+
}
|
|
4132
|
+
return {
|
|
4133
|
+
root,
|
|
4134
|
+
rootMargin,
|
|
4135
|
+
threshold,
|
|
4136
|
+
once: Boolean(options.once),
|
|
4137
|
+
schedule,
|
|
4138
|
+
scope: options.scope ?? target,
|
|
4139
|
+
key: options.key
|
|
4140
|
+
};
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
function normalizeIntersectionThreshold(threshold) {
|
|
4144
|
+
if (Array.isArray(threshold)) {
|
|
4145
|
+
return threshold.map(validateIntersectionThreshold);
|
|
4146
|
+
}
|
|
4147
|
+
return validateIntersectionThreshold(threshold);
|
|
4148
|
+
}
|
|
4149
|
+
|
|
4150
|
+
function validateIntersectionThreshold(value) {
|
|
4151
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
|
|
4152
|
+
throw new TypeError("Intersection threshold must be a number from 0 to 1.");
|
|
4153
|
+
}
|
|
4154
|
+
return value;
|
|
4155
|
+
}
|
|
4156
|
+
|
|
4157
|
+
function runIntersectionCallback(fn, event, options, isActive = () => true) {
|
|
4158
|
+
if (options.schedule === "sync") {
|
|
4159
|
+
if (isActive()) {
|
|
4160
|
+
fn(event);
|
|
4161
|
+
}
|
|
4162
|
+
return;
|
|
4163
|
+
}
|
|
4164
|
+
schedulerInstance.enqueue("lifecycle", () => {
|
|
4165
|
+
if (!destroyed && isActive()) {
|
|
4166
|
+
fn(event);
|
|
4167
|
+
}
|
|
4168
|
+
}, {
|
|
4169
|
+
scope: options.scope,
|
|
4170
|
+
key: options.key
|
|
4171
|
+
});
|
|
4172
|
+
}
|
|
4173
|
+
|
|
4174
|
+
function createIntersectionEvent({ target, root, entry, entries = [entry], observer, unsupported }) {
|
|
4175
|
+
const isIntersecting = Boolean(entry?.isIntersecting);
|
|
4176
|
+
const intersectionRatio = typeof entry?.intersectionRatio === "number"
|
|
4177
|
+
? entry.intersectionRatio
|
|
4178
|
+
: (isIntersecting ? 1 : 0);
|
|
4179
|
+
return {
|
|
4180
|
+
target,
|
|
4181
|
+
element: target,
|
|
4182
|
+
el: target,
|
|
4183
|
+
root: root ?? rootNode,
|
|
4184
|
+
entry,
|
|
4185
|
+
entries,
|
|
4186
|
+
observer,
|
|
4187
|
+
isIntersecting,
|
|
4188
|
+
intersectionRatio,
|
|
4189
|
+
unsupported: Boolean(unsupported)
|
|
4190
|
+
};
|
|
4191
|
+
}
|
|
4192
|
+
|
|
4193
|
+
function createFallbackIntersectionEntry(target) {
|
|
4194
|
+
const rect = target.getBoundingClientRect?.() ?? null;
|
|
4195
|
+
return {
|
|
4196
|
+
target,
|
|
4197
|
+
isIntersecting: true,
|
|
4198
|
+
intersectionRatio: 1,
|
|
4199
|
+
time: 0,
|
|
4200
|
+
rootBounds: null,
|
|
4201
|
+
boundingClientRect: rect,
|
|
4202
|
+
intersectionRect: rect
|
|
4203
|
+
};
|
|
4204
|
+
}
|
|
4205
|
+
|
|
4206
|
+
function isElement(value, ownerWindow = globalThis) {
|
|
4207
|
+
const ElementRef = ownerWindow.Element ?? globalThis.Element;
|
|
4208
|
+
return Boolean(ElementRef && value instanceof ElementRef);
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
function isDocument(value, ownerWindow = globalThis) {
|
|
4212
|
+
const DocumentRef = ownerWindow.Document ?? globalThis.Document;
|
|
4213
|
+
return Boolean(DocumentRef && value instanceof DocumentRef);
|
|
3942
4214
|
}
|
|
3943
4215
|
|
|
3944
4216
|
function assertActive() {
|