mirror of https://github.com/sveltejs/svelte
				
				
				
			feat: add support for resize observer bindings (#8022)
	
		
	
				
					
				
			Implements ResizeObserver bindings: #5524 (comment) Continuation of: #5963 Related to #7583 --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>pull/8022/merge
							parent
							
								
									3a7685fef5
								
							
						
					
					
						commit
						0adc09da97
					
				@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Resize observer singleton.
 | 
				
			||||||
 | 
					 * One listener per element only!
 | 
				
			||||||
 | 
					 * https://groups.google.com/a/chromium.org/g/blink-dev/c/z6ienONUb5A/m/F5-VcUZtBAAJ
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class ResizeObserverSingleton {
 | 
				
			||||||
 | 
						constructor(readonly options?: ResizeObserverOptions) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						observe(element: Element, listener: Listener) {
 | 
				
			||||||
 | 
							this._listeners.set(element, listener);
 | 
				
			||||||
 | 
							this._getObserver().observe(element, this.options);
 | 
				
			||||||
 | 
							return () => {
 | 
				
			||||||
 | 
								this._listeners.delete(element);
 | 
				
			||||||
 | 
								this._observer.unobserve(element); // this line can probably be removed
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static readonly entries: WeakMap<Element, ResizeObserverEntry> = 'WeakMap' in globalThis ? new WeakMap() : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private readonly _listeners: WeakMap<Element, Listener> = 'WeakMap' in globalThis ? new WeakMap() : undefined;
 | 
				
			||||||
 | 
						private _observer?: ResizeObserver;
 | 
				
			||||||
 | 
						private _getObserver() {
 | 
				
			||||||
 | 
							return this._observer ?? (this._observer = new ResizeObserver((entries) => {
 | 
				
			||||||
 | 
								for (const entry of entries) {
 | 
				
			||||||
 | 
									ResizeObserverSingleton.entries.set(entry.target, entry);
 | 
				
			||||||
 | 
									this._listeners.get(entry.target)?.(entry);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Listener = (entry: ResizeObserverEntry)=>any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Remove this
 | 
				
			||||||
 | 
					interface ResizeObserverSize {
 | 
				
			||||||
 | 
					    readonly blockSize: number;
 | 
				
			||||||
 | 
					    readonly inlineSize: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ResizeObserverEntry {
 | 
				
			||||||
 | 
					    readonly borderBoxSize: readonly ResizeObserverSize[];
 | 
				
			||||||
 | 
					    readonly contentBoxSize: readonly ResizeObserverSize[];
 | 
				
			||||||
 | 
					    readonly contentRect: DOMRectReadOnly;
 | 
				
			||||||
 | 
					    readonly devicePixelContentBoxSize: readonly ResizeObserverSize[];
 | 
				
			||||||
 | 
					    readonly target: Element;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ResizeObserverBoxOptions = 'border-box' | 'content-box' | 'device-pixel-content-box';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ResizeObserverOptions {
 | 
				
			||||||
 | 
					    box?: ResizeObserverBoxOptions;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ResizeObserver {
 | 
				
			||||||
 | 
					    disconnect(): void;
 | 
				
			||||||
 | 
					    observe(target: Element, options?: ResizeObserverOptions): void;
 | 
				
			||||||
 | 
					    unobserve(target: Element): void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ResizeObserverCallback {
 | 
				
			||||||
 | 
					    (entries: ResizeObserverEntry[], observer: ResizeObserver): void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare let ResizeObserver: {
 | 
				
			||||||
 | 
					    prototype: ResizeObserver;
 | 
				
			||||||
 | 
					    new(callback: ResizeObserverCallback): ResizeObserver;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue