diff --git a/gsm-frontend/src/components/HytaleConfigEditor.jsx b/gsm-frontend/src/components/HytaleConfigEditor.jsx index e8c230e..34433c0 100644 --- a/gsm-frontend/src/components/HytaleConfigEditor.jsx +++ b/gsm-frontend/src/components/HytaleConfigEditor.jsx @@ -84,41 +84,81 @@ export default function HytaleConfigEditor({ token }) { if (!text) return '' // Escape HTML first - let result = text + let escaped = text .replace(/&/g, '&') .replace(//g, '>') - // Use placeholder tokens to avoid regex conflicts - const tokens = [] - let tokenIndex = 0 + // Process character by character to build highlighted output + let result = '' + let i = 0 - // Replace strings with placeholders - result = result.replace(/"([^"\\]|\\.)*"/g, (match) => { - const isKey = result.indexOf(match + ':') !== -1 - const className = isKey ? 'text-blue-400' : 'text-amber-300' - tokens.push(`${match}`) - return `\x00${tokenIndex++}\x00` - }) - - // Replace booleans and null - result = result.replace(/\b(true|false|null)\b/g, (match) => { - tokens.push(`${match}`) - return `\x00${tokenIndex++}\x00` - }) - - // Replace numbers (only standalone, not inside placeholders) - result = result.replace(/(? { - if (match === '' || match === '-') return match - tokens.push(`${match}`) - return `\x00${tokenIndex++}\x00` - }) - - // Replace brackets - result = result.replace(/([{}\[\]])/g, '$1') - - // Restore tokens - result = result.replace(/\x00(\d+)\x00/g, (_, idx) => tokens[parseInt(idx)]) + while (i < escaped.length) { + // Check for string start + if (escaped[i] === '"') { + let str = '"' + i++ + while (i < escaped.length && escaped[i] !== '"') { + if (escaped[i] === '\\' && i + 1 < escaped.length) { + str += escaped[i] + escaped[i + 1] + i += 2 + } else { + str += escaped[i] + i++ + } + } + if (i < escaped.length) { + str += '"' + i++ + } + // Check if it's a key (followed by colon) + let j = i + while (j < escaped.length && /\s/.test(escaped[j])) j++ + const isKey = escaped[j] === ':' + const className = isKey ? 'text-blue-400' : 'text-amber-300' + result += `${str}` + } + // Check for brackets + else if (/[{}\[\]]/.test(escaped[i])) { + result += `${escaped[i]}` + i++ + } + // Check for numbers + else if (/[-\d]/.test(escaped[i]) && (i === 0 || /[\s,:\[\{]/.test(escaped[i-1]))) { + let num = '' + if (escaped[i] === '-') { + num += '-' + i++ + } + while (i < escaped.length && /[\d.]/.test(escaped[i])) { + num += escaped[i] + i++ + } + if (num && num !== '-') { + result += `${num}` + } else { + result += num + } + } + // Check for booleans and null + else if (escaped.slice(i, i + 4) === 'true') { + result += 'true' + i += 4 + } + else if (escaped.slice(i, i + 5) === 'false') { + result += 'false' + i += 5 + } + else if (escaped.slice(i, i + 4) === 'null') { + result += 'null' + i += 4 + } + // Regular character + else { + result += escaped[i] + i++ + } + } return result }