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