개발

편집기에서 구조적으로 가지고 있던 문제들을 대부분 해결했다.

에디터 개발 14 2025. 10. 6. 2025. 12. 27.

아래는 직접 마크다운 위지윅 편집기를 만드는 과정에서 기록한 글이다. 현재는 TipTap 에디터 활용하였다. (굴복...)


키다운 중심 조작에서 뮤테이션옵저버로

기존에 개선한 버전은 각 줄마다 contenteditable을 부여해서 그 안에서 자유롭게 편집 및 데이터가 바인딩되어 작동되도록 했었다.

이 버전만으로도 작동하는 데에는 크게 문제는 없었지만, 문제는 키입력 시 처리해줘야 하는 내용이 너무 많다는 데 있었다.

예를 들면...

화살표 버튼으로 문장 사이를 왔다갔다 해야 하는 경우 커서 위치를 파악하여 앞뒤로 옮겨주는 작업을 해야 했었고,

마찬가지로 백스페이스와 엔터 동작도 그러했다.

무엇보다 가장 큰 문제는, 문장 간 드래그 선택이 안된다는 것이었다. 여러가지로 생각을 해보았지만 결국 이것은 정석적인 방법이 아니라고 판단,

기존의 다른 편집기들도 부모 컨테이너에 contenteditable을 걸고 있다는 점을 확인하여 줄 별로 이벤트를 걸고 contenteditable을 거는 것이 아닌 부모 컨테이너에서 조작을 해주기로 하였다.

커서 위치 보정은 좌표를 기준으로... 그러나 다시 필요 없게 되었다.

기존에는 줄 간 이동을 위해 좌표로 커서 위치를 보정했는데 부모 컨테이너에 ce를 걸어주니 그럴 필요가 없게 된 것이다.

결국 핵심은 mutationObserver였다.

contenteditable로 인해 발생하는 내용의 변화, 줄의 변화는 Svelte가 반응성 있게 감지하지 못한다.

사실 이것때문에 편집중인 줄에 바인딩을 걸고 contenteditable을 줬던 건데, 이것은 이것대로 부작용이 있어서 유기.

그렇다면 내가 지금 입력하고 있는 텍스트를 DOM에서 상태변수쪽에 전달하는 방식으로 작동하는 수밖에 없었다.

문제는 백스페이스와 엔터 동작이었다.

contenteditable로 감지된 변화는 내용을 집어넣어 주는데에만 사용하고 유기

contenteditable 동작에 의한 요소 추가 및 삭제는 ... 추가부터 말해보자면,

일단 DOM 요소가 하나 추가되어 옵저버가 작동한다.

여기서 상태 변수에 하나를 집어넣어주게 되면, 배열 요소 추가에 의해 DOM 요소가 하나 더 추가되게 된다.

이 과정에서 DOM에 의한 요소 추가는 배열에 없으므로 이것의 여부를 판별하여 작동을 분기 처리해주니 잘 되었다.

그리고 DOM 요소는 나머지 내용들을 처리해주고 삭제해버리면 되는 일이고.

백스페이스 시 커서 관리...

이건 진짜 왜 되지? 싶은 내용이었다.

커서 위치에 따라 편집하고 있는 줄을 가리키려고 만들었던 함수에서 포맷팅 여부를 나누는 기능이 옵션으로 들어가 있는데,

원래는 포맷팅되면 커서 위치가 제멋대로 바뀌니까... 이것을 해결하기 위해 커서 위치 보정 옵션을 꺼?놓았었다. 지금 생각해보니 왜 그랬는지 모르겠다.

암툰 그거를 끄니까 얻어걸렸다. 해결되어버렸다...

드래그 선택 시 카오스

그런데 이렇게 하니까 드래그 시 커서 위치 변화에 의해 막 엄청 어지럽게 편집줄 선택이 저기됐었다. 선택 자체가 안되는 문제가 발생했던 거지.

그래서 그냥 그거는 윈도우에다 포인터 다운 포인터 업 변수 추가해서 어찌어찌 해결했다.

챗지피티랑 잼민이한테 평가해달라고 했는데

잘 했다고 한다...

기쁘다!!!

발 뻗고 잠 잘 수 있을 것 같다.