This repository has no description
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114// SPDX-License-Identifier: AGPL-3.0-or-later
const DEVTOOLS_DOCK_THRESHOLD_PX = 160;
export type DevtoolsDockOrientation = 'horizontal' | 'vertical';
export interface DevtoolsViewportSnapshot { outerWidth: number; innerWidth: number; outerHeight: number; innerHeight: number; legacyDebuggerPresent: boolean;}
export interface DevtoolsDockState { open: boolean; orientation: DevtoolsDockOrientation | null;}
type DevtoolsDockListener = (state: DevtoolsDockState) => void;
function widthGap(snapshot: DevtoolsViewportSnapshot): number { return snapshot.outerWidth - snapshot.innerWidth;}
function heightGap(snapshot: DevtoolsViewportSnapshot): number { return snapshot.outerHeight - snapshot.innerHeight;}
function hasLegacyDebugger(): boolean { try { return Boolean((window as {Firebug?: {chrome?: {isInitialized?: boolean}}}).Firebug?.chrome?.isInitialized); } catch { return false; }}
function captureViewportSnapshot(): DevtoolsViewportSnapshot { return { outerWidth: window.outerWidth, innerWidth: window.innerWidth, outerHeight: window.outerHeight, innerHeight: window.innerHeight, legacyDebuggerPresent: hasLegacyDebugger(), };}
export function detectDevtoolsDockState(snapshot: DevtoolsViewportSnapshot): DevtoolsDockState { const wideGap = widthGap(snapshot) > DEVTOOLS_DOCK_THRESHOLD_PX; const tallGap = heightGap(snapshot) > DEVTOOLS_DOCK_THRESHOLD_PX; if (!(wideGap && tallGap) && (snapshot.legacyDebuggerPresent || wideGap || tallGap)) { return { open: true, orientation: wideGap ? 'vertical' : 'horizontal', }; } return { open: false, orientation: null, };}
export class DevtoolsDockProbe { private readonly listeners = new Set<DevtoolsDockListener>(); private readonly readSnapshot: () => DevtoolsViewportSnapshot; private started = false; private state: DevtoolsDockState = {open: false, orientation: null};
constructor(readSnapshot: () => DevtoolsViewportSnapshot = captureViewportSnapshot) { this.readSnapshot = readSnapshot; }
start(): void { if (this.started || typeof window === 'undefined') { return; } this.started = true; window.addEventListener('resize', this.handleViewportChanged); window.addEventListener('orientationchange', this.handleViewportChanged); this.poll(); }
stop(): void { if (!this.started || typeof window === 'undefined') { return; } this.started = false; window.removeEventListener('resize', this.handleViewportChanged); window.removeEventListener('orientationchange', this.handleViewportChanged); }
subscribe(listener: DevtoolsDockListener): () => void { this.listeners.add(listener); return () => { this.listeners.delete(listener); }; }
private handleViewportChanged = (): void => { this.poll(); };
private poll(): void { const nextState = detectDevtoolsDockState(this.readSnapshot()); if (nextState.open === this.state.open && nextState.orientation === this.state.orientation) { return; } this.state = nextState; for (const listener of this.listeners) { listener(nextState); } }}