diff --git a/src/App.svelte b/src/App.svelte index 9ecb8a2..55473af 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -94,6 +94,7 @@ let overlaySavedSignature = ''; let overlayAutosaveAttemptedSignature = ''; let pendingOverlayDraft: { overlayName: string; overlaySlug: string; overlayHtml: string; overlayCss: string; overlayJavascript: string; overlayEnabled: boolean; overlayDisabledDesign: string } | null = null; + let overlayDiagnosticsOpen = false; let overlayAutosaveTimer: number | undefined; let oauthScopes: Record<'streamer' | 'bot', { connected: boolean; missing_scopes: string[]; reauthorization_required: boolean }> = { streamer: { connected: false, missing_scopes: [], reauthorization_required: false }, @@ -724,6 +725,21 @@ return JSON.stringify({ overlayName, overlaySlug, overlayHtml, overlayCss, overlayJavascript, overlayEnabled, overlayDisabledDesign }); } + function overlayVariableWarnings() { + const warnings: string[] = []; + for (const [language, source] of [['HTML', overlayHtml], ['CSS', overlayCss], ['JAVASCRIPT', overlayJavascript]] as const) { + if (source.includes('${')) { + for (const match of source.match(/\$\{([^}]*)\}/g) || []) { + const name = match.slice(2, -1); + if (!/^[A-Za-z0-9_]+$/.test(name) || name.length === 0) warnings.push(`${language}: invalid variable ${match[0]}`); + else if (name !== 'username') warnings.push(`${language}: undefined variable ${match[0]}`); + } + if (source.split('${').length - 1 !== (source.match(/\$\{[^}]*\}/g) || []).length) warnings.push(`${language}: an opening variable marker has no closing }`); + } + } + return warnings; + } + function overlayDraftCacheKey(id: string) { return `trixie.overlay.draft.${id}`; } @@ -1026,5 +1042,11 @@