BLOG
Tracefield · 02
Tracefield · 01
블로그 · 14
Vibe Audit · 04
Vibe Audit · 03
Vibe Audit · 02
Vibe Audit · 01
출판편집자 · 01
StudyTree · 01
SecurityOps · 02
SecurityOps · 01
AI챗봇 · 04
AI챗봇 · 03
AI챗봇 · 02
AI챗봇 · 01
퍼플심 · 04
퍼플심 · 03
퍼플심 · 02
퍼플심 · 01
블로그 · 13
rootscan · 07
rootscan · 06
블로그 · 12
블로그 · 11
블로그 · 10
블로그 · 09
블로그 · 08
블로그 · 07
블로그 · 06
블로그 · 05
블로그 · 04
블로그 · 03
블로그 · 02
블로그 · 01
rootscan · 05
rootscan · 04
rootscan · 03
asmspeak · 03
asmspeak · 02
rootscan · 02
asmspeak · 01
rootscan · 01
웹보안도구 · 02
웹보안도구 · 01
루트캠프 · 02
루트캠프 · 01
에디터 기능 개선 및 버그 수정
에디터 안정화: 험난한 기능 개선의 길
지난번 BlockNote 도입으로 큰 틀은 잡혔지만 실제로 써보니 디테일한 부분에서 여전히 문제가 많았다.
오늘은 이 문제들을 하나씩 해결하며 에디터의 완성도를 높이는 데 집중했다.
1. 이미지 로딩과 NBSP의 충돌
가장 골치 아팠던 문제는 에디터에서 이미지가 로드되지 않는 현상이었다.
원인을 파헤쳐보니 마크다운을 BlockNote 블록으로 변환하는 전처리 과정(markdownToBlocks)에 문제가 있었다.
BlockNote가 빈 줄을 제대로 인식하지 못해서 모든 빈 줄을 NBSP(\u00A0)로 변환하도록 처리했었는데
이 과정에서 이미지 문법 바로 앞뒤의 줄바꿈까지 NBSP로 변해버리면서 파서가 이미지를 인식하지 못하게 된 것이다.
결국 전처리 로직을 수정해 '이미지가 아닌 빈 줄'만 선별적으로 변환하려 했지만 정규식 처리가 까다로웠고
근본적으로는 저장 시점에 처리하는 것이 맞다고 판단했다.
불필요한 전처리를 걷어내고 저장 로직(blocksToMarkdown)을 강화하는 방향으로 선회하여 깔끔하게 해결했다.
2. IDE 스타일 저장: 라인별 편집의 로망
보통 웹 에디터는 블록 단위로 생각하고 저장한다. 문단과 문단 사이는 당연히 떨어져 있어야 한다는 식이다.
하지만 나는 VS Code에서 마크다운 파일을 열고 한 줄 한 줄 코드를 짜듯이 글을 쓰는 경험을 웹에서도 원했다.
BlockNote는 기본적으로 모든 블록 사이에 \n\n을 넣어 저장한다.
이게 마크다운 표준에는 맞지만, IDE에서 볼 때는 불필요하게 줄 간격이 넓어 보여 가독성을 해쳤다.
내가 입력한 빈 줄만 저장되고, 나머지는 붙여서 저장되는 진정한 IDE 스타일을 구현하고 싶었다.
이를 위해 마커(Marker) 방식을 도입했다.
- 저장 전, 에디터상의 진짜 빈 줄(NBSP 블록)을
__EMPTY_LINE__이라는 마커로 변환한다. - 모든
\n\n을\n으로 바꿔버린다. (모든 블록을 다닥다닥 붙임) - 마지막으로
__EMPTY_LINE__마커를 다시\n으로 복원한다.
결과는 만족스러웠다. 웹 에디터에서 작성한 글을 VS Code로 열어도 이질감이 거의 없었다.
내가 의도적으로 띄운 줄만 정확히 빈 줄로 남고, 나머지는 깔끔하게 정리되어 있었다.
**'웹에서도 IDE처럼 라인 단위로 편집한다'**는 의도가 기술적으로 구현된 순간이었다.
덤으로, 리스트 아이템 사이나 헤딩과 본문 사이에 강제로 들어가는 공백도 제거하여 훨씬 밀도 있는 문서 작성이 가능해졌다.
3. URL 한글 깨짐과 링크 처리
마크다운으로 저장될 때 한글 URL이 %ED%85%8C...처럼 인코딩돼 저장되는 문제가 있었다. 가독성도 떨어지고 링크 수정도 불편했다.
저장 로직에 decodeURIComponent를 추가하여 한글이 그대로 저장되도록 수정했다.
또 공백이 포함된 파일명이나 URL(예: Program Files)은 마크다운 파싱 오류를 일으킬 수 있어
이런 경우에만 자동으로 < > 기호로 감싸주는([link](<url with space>)) 로직도 추가했다.
4. 다크모드 동기화: 내 맘대로 안 되는 브라우저
앱은 라이트모드인데 에디터만 다크모드로 나오는 기이한 현상이 있었다.
알고 보니 prefers-color-scheme 미디어 쿼리 때문에 브라우저/OS 설정이 강제로 적용되고 있었다.
라이브러리 내장 CSS를 오버라이드하고 테마 감지 로직에서도 브라우저 설정을 무시한 채 **앱의 테마 상태(html.dark 클래스)**만 따르도록 바꿨다.
이제 시스템 설정과 무관하게 웹사이트 설정대로 에디터 테마가 완벽하게 동기화된다.
더 나은 경험을 위한 UI/UX 디테일링
에디터 코어 기능 외에도 글쓰는 경험을 쾌적하게 만들기 위해 놓치고 있던 디테일들을 함께 손봤다.
- TOC/아웃라인 디자인 통일: 뷰 모드와 에디터의 목차 디자인을 통일했다. 아이콘, 포인트 컬러, 헤딩 카운트 배지까지 맞춰서 일관성을 높였고, 본문 제목(
article-title)이 목차에 중복으로 뜨는 문제도 ID 필터링으로 해결했다. - 직관적인 태그 관리: 태그를 클릭해야 삭제되는 방식에서, 마우스를 올리면
✕ 삭제표시가 뜨도록 변경했다. 또한 무분별한 태그 입력을 막기 위해 최대 5개까지만 입력 가능하도록 제한을 두었다. - 날짜 선택 UI: 기존 문자열 입력 방식에서 Date Picker를 도입해 클릭 한 번으로 날짜를 변경할 수 있게 했다. 날짜 포맷도 문서 전체적으로 통일했다.
- WYSIWYG 강화: 편집기 내 H2 구분선 제거, 불필요한 공백 제거, 그리고 단일 엔터도 줄바꿈으로 인식하도록(
remark-breaks) 처리하여 "보이는 대로 저장되고 보이는 대로 출력되는" 경험을 완성했다.

