Search

원활한 콘텐츠 작성을 위한 에디터 개발기

subject
에디터
contentEditable
WYSIWYG
date
2022/01/10
1 more property
에디터를 직접 만들면서 어떤 방식으로 접근했는지 자세히 적은 글. 에디터 만드는 것에 관심은 있지만 구현해본 적 없는 입장에서는 신기했다. 글에는 그간의 과정들을 간략히 적었지만 그 안에서 많은 고민과 삽질이 느껴진다.
오늘의 집에서 사용하는 문서 구조는 블럭 기반 - 메타 정보를 담은 배열 형식으로 글 나열
에디터도 블럭 기반으로 만들었다.
블럭 기반 에디터 프레임워크가 많이 없다.
웹에서 에디터를 만들 때는 일반적으로 contentEditable 을 사용한다.
장점: 브라우저가 자체적으로 클립보드, 드래그&드롭, 실행 취소 등의 기능을 제공해줌
단점: 표준이 아니다보니 브라우저마다 다르게 동작함
execCommand() 를 직접 사용하는 대신 문서의 DOM 노드를 직접 조작하는 방식
장점: 로직을 직접 작성하므로 브라우저끼리 동작이 동일해짐
단점
엣지 케이스가 많아 처리가 복잡해짐
실행 취소 기능이 동작하지 않음 - 히스토리 관리를 위한 모듈이 필요
contentEditable 이 단순히 유저의 편집 명령을 받는 용도로 축소됨.
브라우저들은 contentEditable 에 이벤트를 추가하여 유저가 무엇을 하려고 했는지 이벤트화하여 에디터 구현이 쉽도록 했다.
이벤트 예시: input, beforeinput
장점: 외부에 의해 DOM이 변경되지 않고, 유저가 무엇을 하려고 하는지에 따라 상태를 바꿔주어 react 등 상태 관리 라이브러리를 매끄럽게 사용 가능
단점: IE, 파폭에서 beforeinput 을 지원하지 않기 때문에 사용하기 어려움 → 이벤트를 가로채서 유저의 의도를 유추하기도 함
beforeinput , 이벤트 가로채기 등도 버그가 존재. 특히 한글 입력 시 문제 → 브라우저의 기본 동작을 취소하고 직접 DOM 을 건드리기 때문
DOM을 직접 건드리지 말고, contentEditable 을 브라우저가 수정하는 그대로 사용해야 한다.
contentEditable 자체의 동작을 막지 말고, 편집이 일어날 때마다 내부 상태를 업데이트한다.
블럭 기반 문서의 데이터를 내부적으로 처리하려면 DOM에 의존하지 않고 에디터 자체적으로 상태를 관리해야 한다. → JSON으로 문서화하면 처리가 간단해짐
인라인 태그의 처리 어려움 → 세그먼트 형식 사용
거꾸로 virtualDOM
순환 참조 등의 이슈로 react 대신 MVC 구조 선택
상태를 MVC 패턴으로 관리
뷰만 react 로 구성