diff --git a/src/util/rgb/Decode.ts b/src/util/rgb/Decode.ts index e809cf33..3ec2b628 100644 --- a/src/util/rgb/Decode.ts +++ b/src/util/rgb/Decode.ts @@ -1,16 +1,19 @@ function hexToHSL(hex: string) { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); if (!result) return { h: 100, s: 100, l: 100 }; + const r = parseInt(result[1], 16) / 255; const g = parseInt(result[2], 16) / 255; const b = parseInt(result[3], 16) / 255; - const max = Math.max(r, g, b), - min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + let h = 0; - let s, - l = (max + min) / 2; + let s = 0; + let l = (max + min) / 2; + if (max === min) { - h = s = 0; // achromatic + h = s = 0; } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); @@ -36,43 +39,39 @@ function hexToHSL(hex: string) { } export function getSignificantPoints(gradient: string[], threshold: number) { - // Convert all colors to HSL const hslColors = gradient.map(hexToHSL); - // Calculate differences between consecutive colors const differences = []; for (let i = 1; i < hslColors.length; i++) { const hDiff = Math.abs(hslColors[i].h - hslColors[i - 1].h); const sDiff = Math.abs(hslColors[i].s - hslColors[i - 1].s); const lDiff = Math.abs(hslColors[i].l - hslColors[i - 1].l); - // Weight hue, saturation, and lightness changes differences.push({ index: i, - change: hDiff * 2 + sDiff + lDiff, // Hue changes weighted more heavily + change: hDiff * 2 + sDiff + lDiff, }); } - // Identify significant points based on notable changes const significantPoints = [gradient[0]]; // Always include the first color - // Iterate over differences to capture significant transitions for (let i = 1; i < differences.length; i++) { if (differences[i - 1].change > threshold) { - // Dynamic threshold based on gradient characteristics significantPoints.push(gradient[differences[i - 1].index]); } } - significantPoints.push(gradient[gradient.length - 1]); // Always include the last color + significantPoints.push(gradient[gradient.length - 1]); return significantPoints; } export function decodeLegacy(rgbtext: string) { - const legacyCodeRegex = - /(?:(?:[&§]|\\u00a7)x(?:(?:[&§]|\\u00a7)[0-9A-Fa-f]){6}|&#[0-9A-Fa-f]{6}|(?:[&§]|\\u00a7)[l-orL-ORkK])/g; - const matches = [...rgbtext.matchAll(legacyCodeRegex)]; + if (!rgbtext || !rgbtext.trim()) return null; + const codeRegex = + /(?:(?:[&§]|\\u00a7)x(?:(?:[&§]|\\u00a7)[0-9A-Fa-f]){6}|[&#§]\b[0-9A-Fa-f]{6}\b|&#[0-9A-Fa-f]{6}|]*style=["']([^"']*)["'][^>]*>|<\/span>|(?:[&§]|\\u00a7)[l-orL-ORkK])/gi; + + const matches = [...rgbtext.matchAll(codeRegex)]; if (matches.length === 0) return null; const colors: Array<{ hex: string; pos: number }> = []; @@ -98,38 +97,49 @@ export function decodeLegacy(rgbtext: string) { const match = matches[i]; const codeStr = match[0]; - const lastChar = codeStr.charAt(codeStr.length - 1).toLowerCase(); - if (codeStr.length === 2 || codeStr.startsWith('\\u00a7')) { - if (lastChar === 'r') { - currentColor = '#ffffff'; - currentFmts.bold = false; - currentFmts.italic = false; - currentFmts.underline = false; - currentFmts.strikethrough = false; - currentFmts.obfuscate = false; - } else if (lastChar === 'l') { - currentFmts.bold = true; - } else if (lastChar === 'o') { - currentFmts.italic = true; - } else if (lastChar === 'n') { + if (codeStr.toLowerCase().startsWith('') { + // closing tag } else { - if (codeStr.startsWith('&#')) { + const lastChar = codeStr.charAt(codeStr.length - 1).toLowerCase(); + if (codeStr.length === 2 || codeStr.startsWith('\\u00a7')) { + if (lastChar === 'r') { + currentColor = '#ffffff'; + currentFmts.bold = false; + currentFmts.italic = false; + currentFmts.underline = false; + currentFmts.strikethrough = false; + currentFmts.obfuscate = false; + } else if (lastChar === 'l') { + currentFmts.bold = true; + } else if (lastChar === 'o') { + currentFmts.italic = true; + } else if (lastChar === 'n') { + currentFmts.underline = true; + } else if (lastChar === 'm') { + currentFmts.strikethrough = true; + } else if (lastChar === 'k') { + currentFmts.obfuscate = true; + } + } else if (codeStr.startsWith('&#') || codeStr.startsWith('§#')) { currentColor = '#' + codeStr.slice(2); + } else if (codeStr.startsWith('#')) { + currentColor = codeStr; } else { - const hexDigits = codeStr.replace(/(?:[&§]|\\u00a7|x)/g, ''); + const hexDigits = codeStr.replace(/(?:[&§]|\\u00a7|x)/gi, ''); currentColor = '#' + hexDigits; } - currentFmts.bold = false; - currentFmts.italic = false; - currentFmts.underline = false; - currentFmts.strikethrough = false; - currentFmts.obfuscate = false; } const startIdx = match.index + codeStr.length;