rename visualobserver

This commit is contained in:
“chrisshank” 2024-11-26 01:02:19 -08:00
parent 1475c41a85
commit fee3a9f342
3 changed files with 35 additions and 37 deletions

View File

@ -1,8 +1,8 @@
import { FolkGeometry } from '../canvas/fc-geometry';
import { Vertex } from './utils';
import { VisualObserverEntry, VisualObserverManager } from './visual-observer';
import { ClientRectObserverEntry, ClientRectObserverManager } from './visual-observer';
const visualObserver = new VisualObserverManager();
const clientRectObserver = new ClientRectObserverManager();
const vertexRegex = /(?<x>-?([0-9]*[.])?[0-9]+),\s*(?<y>-?([0-9]*[.])?[0-9]+)/;
@ -50,7 +50,7 @@ export class AbstractArrow extends HTMLElement {
return this.#sourceElement;
}
#sourceCallback = (entry: VisualObserverEntry) => {
#sourceCallback = (entry: ClientRectObserverEntry) => {
this.#sourceRect = entry.contentRect;
this.#update();
};
@ -88,7 +88,7 @@ export class AbstractArrow extends HTMLElement {
}
};
#sourceIframeCallback = (entry: VisualObserverEntry) => {
#sourceIframeCallback = (entry: ClientRectObserverEntry) => {
this.#sourceIframeRect = entry.contentRect;
this.#updateSourceIframeRect();
};
@ -124,7 +124,7 @@ export class AbstractArrow extends HTMLElement {
return this.#targetElement;
}
#targetCallback = (entry: VisualObserverEntry) => {
#targetCallback = (entry: ClientRectObserverEntry) => {
this.#targetRect = entry.contentRect;
this.#update();
};
@ -162,7 +162,7 @@ export class AbstractArrow extends HTMLElement {
}
};
#targetIframeCallback = (entry: VisualObserverEntry) => {
#targetIframeCallback = (entry: ClientRectObserverEntry) => {
this.#targetIframeRect = entry.contentRect;
this.#updateTargetIframeRect();
};
@ -214,13 +214,13 @@ export class AbstractArrow extends HTMLElement {
this.#sourceRect = this.#sourceElement.getBoundingClientRect();
} else if (this.#sourceElement instanceof HTMLIFrameElement && this.#sourceIframeSelector) {
window.addEventListener('message', this.#sourcePostMessage);
visualObserver.observe(this.#sourceElement, this.#sourceIframeCallback);
clientRectObserver.observe(this.#sourceElement, this.#sourceIframeCallback);
this.#sourceElement.contentWindow?.postMessage({
type: 'folk-observe-element',
selector: this.#sourceIframeSelector,
});
} else {
visualObserver.observe(this.#sourceElement, this.#sourceCallback);
clientRectObserver.observe(this.#sourceElement, this.#sourceCallback);
this.#sourceRect = this.#sourceElement.getBoundingClientRect();
}
}
@ -234,13 +234,13 @@ export class AbstractArrow extends HTMLElement {
this.#sourceElement.removeEventListener('move', this.#sourceHandler);
} else if (this.#sourceElement instanceof HTMLIFrameElement && this.#sourceIframeSelector) {
window.removeEventListener('message', this.#sourcePostMessage);
visualObserver.unobserve(this.#sourceElement, this.#sourceIframeCallback);
clientRectObserver.unobserve(this.#sourceElement, this.#sourceIframeCallback);
this.#sourceElement.contentWindow?.postMessage({
type: 'folk-unobserve-element',
selector: this.#sourceIframeSelector,
});
} else {
visualObserver.unobserve(this.#sourceElement, this.#sourceCallback);
clientRectObserver.unobserve(this.#sourceElement, this.#sourceCallback);
}
}
@ -264,13 +264,13 @@ export class AbstractArrow extends HTMLElement {
this.#targetElement.addEventListener('move', this.#targetHandler);
} else if (this.#targetElement instanceof HTMLIFrameElement && this.#targetIframeSelector) {
window.addEventListener('message', this.#targetPostMessage);
visualObserver.observe(this.#targetElement, this.#targetIframeCallback);
clientRectObserver.observe(this.#targetElement, this.#targetIframeCallback);
this.#targetElement.contentWindow?.postMessage({
type: 'folk-observe-element',
selector: this.#targetIframeSelector,
});
} else {
visualObserver.observe(this.#targetElement, this.#targetCallback);
clientRectObserver.observe(this.#targetElement, this.#targetCallback);
}
this.#targetRect = this.#targetElement.getBoundingClientRect();
}
@ -284,13 +284,13 @@ export class AbstractArrow extends HTMLElement {
this.#targetElement.removeEventListener('move', this.#targetHandler);
} else if (this.#targetElement instanceof HTMLIFrameElement && this.#targetIframeSelector) {
window.removeEventListener('message', this.#targetPostMessage);
visualObserver.unobserve(this.#targetElement, this.#targetIframeCallback);
clientRectObserver.unobserve(this.#targetElement, this.#targetIframeCallback);
this.#targetElement.contentWindow?.postMessage({
type: 'folk-unobserve-element',
selector: this.#targetIframeSelector,
});
} else {
visualObserver.unobserve(this.#targetElement, this.#targetCallback);
clientRectObserver.unobserve(this.#targetElement, this.#targetCallback);
}
}

View File

@ -1,5 +1,5 @@
import { FolkGeometry } from '../canvas/fc-geometry';
import { VisualObserverManager, VisualObserverEntry } from './visual-observer.ts';
import { ClientRectObserverManager, ClientRectObserverEntry } from './visual-observer.ts';
interface ObservedElementEntry {
selector: string;
@ -51,7 +51,7 @@ if (window.parent !== window) {
const observedElements = new Map();
const observedSelectors = new Map();
function boundingBoxCallback(entry: VisualObserverEntry) {}
function boundingBoxCallback(entry: ClientRectObserverEntry) {}
function onGeometryChange(event) {
window.parent.postMessage({

View File

@ -1,14 +1,14 @@
export interface VisualObserverEntry {
export interface ClientRectObserverEntry {
target: Element;
contentRect: DOMRectReadOnly;
isAppearing: boolean;
}
export interface VisualObserverCallback {
(this: VisualObserver, entries: VisualObserverEntry[], observer: VisualObserver): void;
export interface ClientRectObserverCallback {
(this: ClientRectObserver, entries: ClientRectObserverEntry[], observer: ClientRectObserver): void;
}
interface VisualObserverElement {
interface ClientRectObserverElement {
io: IntersectionObserver | null;
threshold: number;
isFirstUpdate: boolean;
@ -17,20 +17,20 @@ interface VisualObserverElement {
/**
* Create an observer that notifies when an element is resized, moved, or added/removed from the DOM.
*/
export class VisualObserver {
export class ClientRectObserver {
#root = document.documentElement;
#rootRect = this.#root.getBoundingClientRect();
#entries: VisualObserverEntry[] = [];
#entries: ClientRectObserverEntry[] = [];
#rafId = 0;
#callback: VisualObserverCallback;
#callback: ClientRectObserverCallback;
constructor(callback: VisualObserverCallback) {
constructor(callback: ClientRectObserverCallback) {
this.#callback = callback;
}
#elements = new Map<Element, VisualObserverElement>();
#elements = new Map<Element, ClientRectObserverElement>();
#resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
const rootEntry = entries.find((entry) => entry.target === this.#root);
@ -49,7 +49,7 @@ export class VisualObserver {
}
});
#appendEntry(entry: VisualObserverEntry) {
#appendEntry(entry: ClientRectObserverEntry) {
// deduplicate the same target
this.#entries.push(entry);
@ -66,9 +66,7 @@ export class VisualObserver {
};
// We should be guaranteed that each `IntersectionObserver` only observes one element.
#onIntersection = ([
{ target, intersectionRatio, boundingClientRect },
]: IntersectionObserverEntry[]) => {
#onIntersection = ([{ target, intersectionRatio, boundingClientRect }]: IntersectionObserverEntry[]) => {
const el = this.#elements.get(target);
if (el === undefined) return;
@ -100,7 +98,7 @@ export class VisualObserver {
#refreshElement(
target: Element,
contentRect: DOMRectReadOnly = target.getBoundingClientRect()
): VisualObserverEntry {
): ClientRectObserverEntry {
// Assume el exists
const el = this.#elements.get(target)!;
@ -176,7 +174,7 @@ export class VisualObserver {
this.#resizeObserver.observe(target);
}
takeRecords(): VisualObserverEntry[] {
takeRecords(): ClientRectObserverEntry[] {
if (this.#rafId === 0) return [];
const entries = this.#entries;
@ -203,12 +201,12 @@ export class VisualObserver {
}
}
export type VisualObserverEntryCallback = (entry: VisualObserverEntry) => void;
export type ClientRectObserverEntryCallback = (entry: ClientRectObserverEntry) => void;
export class VisualObserverManager {
#elementMap = new WeakMap<Element, Set<VisualObserverEntryCallback>>();
export class ClientRectObserverManager {
#elementMap = new WeakMap<Element, Set<ClientRectObserverEntryCallback>>();
#vo = new VisualObserver((entries) => {
#vo = new ClientRectObserver((entries) => {
for (const entry of entries) {
const callbacks = this.#elementMap.get(entry.target);
@ -218,7 +216,7 @@ export class VisualObserverManager {
}
});
observe(target: Element, callback: VisualObserverEntryCallback): void {
observe(target: Element, callback: ClientRectObserverEntryCallback): void {
let callbacks = this.#elementMap.get(target);
if (callbacks === undefined) {
@ -231,7 +229,7 @@ export class VisualObserverManager {
callbacks.add(callback);
}
unobserve(target: Element, callback: VisualObserverEntryCallback): void {
unobserve(target: Element, callback: ClientRectObserverEntryCallback): void {
let callbacks = this.#elementMap.get(target);
if (callbacks === undefined) return;