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