| 1 | const EXPLICIT_SCHEME = /^(?:[a-z][a-z0-9+.-]*:\/\/|(?:about|blob|data|file|view-source):)/i; |
| 2 | const LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|\[::1\]|0\.0\.0\.0)(?::\d+)?(?:[/?#]|$)/i; |
| 3 | |
| 4 | /** Turns address-bar input into a loadable URL; bare hosts become https, loopback hosts http. */ |
| 5 | export function normalizeAddress(input: string): string | null { |
| 6 | const value = input.trim(); |
| 7 | if (!value) return null; |
| 8 | if (EXPLICIT_SCHEME.test(value)) return value; |
| 9 | return `${LOOPBACK_HOST.test(value) ? "http" : "https"}://${value}`; |
| 10 | } |
| 11 | |
| 12 | const ZOOM_PRESETS = [0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5]; |
| 13 | const ZOOM_EPSILON = 0.005; |
| 14 | |
| 15 | /** Next Chromium zoom preset in `direction`; 0 resets to 100%. */ |
| 16 | export function zoomStep(current: number, direction: -1 | 0 | 1): number { |
| 17 | if (direction === 0) return 1; |
| 18 | if (direction > 0) return ZOOM_PRESETS.find((preset) => preset > current + ZOOM_EPSILON) ?? ZOOM_PRESETS[ZOOM_PRESETS.length - 1]; |
| 19 | return [...ZOOM_PRESETS].reverse().find((preset) => preset < current - ZOOM_EPSILON) ?? ZOOM_PRESETS[0]; |
| 20 | } |
| 21 | |
| 22 | export function zoomPercent(factor: number): number { |
| 23 | return Math.round(factor * 100); |
| 24 | } |
| 25 |