Skip to content

Commit 43fc1bc

Browse files
authored
1.1.9
1 parent 14b018d commit 43fc1bc

File tree

4 files changed

+66
-33
lines changed

4 files changed

+66
-33
lines changed

Pages.js

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -361,28 +361,30 @@ const KaraokeLine = react.memo(({ line, position, isActive, globalCharOffset = 0
361361
let lastIndex = 0;
362362
let match;
363363

364-
while ((match = whitespacePattern.exec(rawLineText)) !== null) {
364+
// Build text from charRenderData to ensure exact matching
365+
const actualText = charRenderData.map(c => c.char).join('');
366+
367+
// Reset regex state
368+
whitespacePattern.lastIndex = 0;
369+
while ((match = whitespacePattern.exec(actualText)) !== null) {
365370
if (match.index > lastIndex) {
366-
tokens.push({ type: "word", value: rawLineText.slice(lastIndex, match.index) });
371+
tokens.push({ type: "word", value: actualText.slice(lastIndex, match.index) });
367372
}
368373
tokens.push({ type: "space", value: match[0] });
369374
lastIndex = match.index + match[0].length;
370375
}
371376

372-
if (lastIndex < rawLineText.length) {
373-
tokens.push({ type: "word", value: rawLineText.slice(lastIndex) });
377+
if (lastIndex < actualText.length) {
378+
tokens.push({ type: "word", value: actualText.slice(lastIndex) });
374379
}
375380

376381
const hasWhitespaceToken = tokens.some(token => token.type === "space");
377-
// Count only actual characters from charRenderData (no spaces)
382+
// Total character count including spaces
383+
const totalTokenChars = tokens.reduce((sum, token) => sum + Array.from(token.value).length, 0);
378384
const actualCharCount = charRenderData.length;
379-
// Count characters in word tokens (excluding space tokens)
380-
const wordTokenChars = tokens
381-
.filter(token => token.type === "word")
382-
.reduce((sum, token) => sum + Array.from(token.value).length, 0);
383385

384-
// Word grouping only works if syllable text matches token words exactly
385-
let useWordGrouping = hasWhitespaceToken && wordTokenChars === actualCharCount;
386+
// Word grouping works if we have spaces and total chars match
387+
let useWordGrouping = hasWhitespaceToken && totalTokenChars === actualCharCount;
386388

387389
if (useWordGrouping) {
388390
let charCursor = 0;
@@ -427,16 +429,39 @@ const KaraokeLine = react.memo(({ line, position, isActive, globalCharOffset = 0
427429

428430
charCursor += wordChars.length;
429431
} else {
432+
// Space token - render the space characters from charRenderData
433+
const spaceChars = Array.from(token.value);
434+
const spaceCharData = charRenderData.slice(charCursor, charCursor + spaceChars.length);
435+
436+
if (spaceCharData.length !== spaceChars.length) {
437+
mappingFailed = true;
438+
return;
439+
}
440+
441+
const spaceChildren = spaceCharData.map(charData =>
442+
react.createElement(
443+
"span",
444+
{
445+
key: charData.key,
446+
className: charData.className,
447+
style: charData.style
448+
},
449+
charData.char
450+
)
451+
);
452+
430453
elements.push(
431454
react.createElement(
432455
"span",
433456
{
434457
key: `space-${tokenIndex}`,
435458
className: "lyrics-karaoke-word-space"
436459
},
437-
token.value
460+
spaceChildren
438461
)
439462
);
463+
464+
charCursor += spaceChars.length;
440465
}
441466
});
442467

@@ -517,18 +542,16 @@ const KaraokeLine = react.memo(({ line, position, isActive, globalCharOffset = 0
517542
);
518543
}
519544

545+
// Only add syllable boundary space if the next character is actually a space
520546
const nextCharData = charRenderData[index + 1];
521547
if (nextCharData && nextCharData.syllableIndex !== charData.syllableIndex) {
522-
elements.push(
523-
react.createElement(
524-
"span",
525-
{
526-
key: `space-${charData.key}`,
527-
className: "lyrics-karaoke-space"
528-
},
529-
" "
530-
)
531-
);
548+
// Check if the next character is a whitespace character
549+
if (nextCharData.char && /\s/.test(nextCharData.char)) {
550+
// Skip - the space will be rendered as part of charRenderData
551+
} else {
552+
// No space in the actual text, don't add artificial space
553+
// This prevents "woul d" style splitting
554+
}
532555
}
533556
});
534557
}

Utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ const Utils = {
581581
/**
582582
* Current version of the lyrics-plus app
583583
*/
584-
currentVersion: "1.1.8",
584+
currentVersion: "1.1.9",
585585

586586
/**
587587
* Check for updates from remote repository

style.css

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@
276276
text-shadow: var(--lyrics-text-shadow);
277277
opacity: var(--lyrics-original-opacity, 1);
278278
overflow-wrap: break-word;
279-
word-break: keep-all;
279+
word-break: auto-phrase; /* Allow natural breaks in CJK and word boundaries in Latin */
280280
margin-bottom: 12px;
281281
}
282282

@@ -288,7 +288,7 @@
288288
text-shadow: var(--lyrics-text-shadow);
289289
opacity: var(--lyrics-original-opacity, 1);
290290
overflow-wrap: break-word;
291-
word-break: keep-all;
291+
word-break: auto-phrase; /* Allow natural breaks in CJK and word boundaries in Latin */
292292
}
293293

294294
@media (min-width: 1280px) {
@@ -433,33 +433,43 @@ div.lyrics-tabBar-headerItemLink {
433433

434434
/* 새로운 가라오케 스타일 - synced 모드 기반 */
435435
.lyrics-karaoke-line {
436-
display: inline;
437-
letter-spacing: -0.06em; /* 글자 간격 더 좁게 */
436+
display: block; /* inline에서 block으로 변경하여 정상적인 줄바꿈 허용 */
437+
letter-spacing: -0.045em; /* 글자 간격 조정 (-0.06em에서 -0.02em으로 변경) */
438+
line-height: 1.3; /* 줄바꿈 시 줄간격 조정 */
438439
}
439440

440441
.lyrics-karaoke-word {
442+
/* Make word a block that wraps as a unit, but can break if too long */
441443
display: inline-block;
442-
white-space: nowrap;
444+
white-space: nowrap; /* keep word together */
445+
/* If word is too long for the line, allow breaking inside */
446+
max-width: 100%;
447+
overflow-wrap: break-word;
448+
word-break: normal;
449+
line-height: inherit;
450+
vertical-align: baseline;
443451
}
444452

445453
.lyrics-karaoke-word-space {
446454
display: inline;
447455
white-space: pre-wrap;
448456
letter-spacing: 0;
449-
min-width: 0.3em;
457+
min-width: 0.5em; /* 띄어쓰기 간격 증가 (0.3em -> 0.5em) */
450458
}
451459

452460
.lyrics-karaoke-char {
453-
display: inline-block;
461+
display: inline-block; /* transform 적용을 위해 inline-block 유지 */
454462
position: relative;
455463
color: var(--lyrics-color-inactive);
456-
/* synced 모드보다 더 좁은 letter-spacing 적용 */
457-
letter-spacing: -0.06em;
464+
/* 글자 간격을 살짝 더 넓게 조정 */
465+
letter-spacing: -0.045em; /* -0.06em에서 -0.02em으로 변경 */
458466
/* 부드러운 transition은 inline style에서 처리 */
459467
/* GPU 가속 활성화 */
460468
will-change: transform, color;
461469
backface-visibility: hidden;
462470
-webkit-font-smoothing: antialiased;
471+
/* 세로 정렬로 줄바꿈 시 정렬 개선 */
472+
vertical-align: baseline;
463473
}
464474

465475
/* Karaoke mode: ruby inside karaoke-char */

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.8
1+
1.1.9

0 commit comments

Comments
 (0)