React WYSIWYG 에디터 도입기

최낙원·2022년 3월 5일
3

조건

  • IME 입력 문제 <- 매우 중요
  • decorator, custom element 지원
    HashTag, @Mention 비슷한 것
  • (state 지원)
  • (블록형 문서 포맷)

후보

직접 작성

https://bucketplace.co.kr/post/2020-09-18-원활한-콘텐츠-작성을-위한-에디터-개발기/
정 안되면 직접 작성하면서 발전시키기로

Draft.js

  • React 기준으로 개발됨
  • State와 블록

[https://medium.com/bgpworks/draft-js-사용기-에디터-만들기-afad9b308a40](https://medium.com/bgpworks/draft-js-%EC%82%AC%EC%9A%A9%EA%B8%B0-%EC%97%90%EB%94%94%ED%84%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0-afad9b308a40
https://krasimir.gitbooks.io/react-in-patterns/content/chapter-05/)

실패

한글 입력시 State가 제대로 바뀌지 않음

0.11.7 버전으로 테스트

예제: https://dmc31a42.github.io/react-wysiwyg-research/draft-js-0-11-7/examples/draft-0-10-0/tweet/tweet.html

@test를 입력 후 지운 다음 @테스트를 입력하고 오른쪽 방향키를 눌러 조합형 입력을 완료한 모습

영문을 입력할 때는 blocks의 text가 정상적으로 반영되고 있지만, 조합형 입력에서는 커서의 위치만 업데이트되고 글자가 업데이트 되지 않는 모습을 보임

https://github.com/facebook/draft-js/issues/2282 에서 0.11에서 변화 감지를 MutationObserver로 바꾸어서 그렇다는데 0.10으로 다시 확인

0.10.5 버전으로 테스트

예제: https://dmc31a42.github.io/react-wysiwyg-research/draft-js-0-10-5/examples/draft-0-10-0/tweet/tweet.html

@test를 입력 후 지운 다음 @테스트를 입력하고 오른쪽 방향키를 눌러 조합형 입력을 완료한 모습

똑같이 안된다.

draft-js\src\component\handlers\edit\DraftEditorEditHandler.js
의 각종 event handler를 보면 IME 입력시 이벤트는 제대로 핸들링하지 않는것(State 갱신)으로 보임

약간 수정하면 될 수도 있겠지만 이미 2년간 지원이 끊겨서 더이상 사용하지 않는 것이 바람직해보임

https://github.com/CodeSoom/ConStu/issues/108
( https://github.com/nib-edit/Nib )

Toast UI Editor

Slate

https://www.slatejs.org/examples/mentions

실패

결과만 놓고 보면 실패

구체적으로 안드로이드에서 조합형 입력을 할 때 느리게 입력하면 오류. 한번 오류난 이후로는 어떻게 입력해도 오류가 나지는 않음.

예제: https://dmc31a42.github.io/react-wysiwyg-research/slate-0-72-8-android-chrome/examples/mentions.html
'한글테스트'를 천천히 입력 후 지우기, 빠르게 입력 후 지우기, 천천히 입력 후 지우기를 수행. 첫 천천히 입력시에 '한ㄱㅡㄹ테스트'로, 두 번째 이후로는 '한글테스트'로 정상적으로 입력됨

https://docs.slatejs.org/general/faq#what-browsers-and-devices-does-slate-support 에서 안드로이드는 지원이 요원..

https://github.com/ianstormtaylor/slate/issues/1720 에서 모바일 지원 현황이 2018년 이었는데, 아직도 완전히 해결하지 못한 것으로 보임. 여기서 Quill이 모바일 서포트라 되어있어서 quill을 써보기로 함

뱀발

Next.js에서 루트 디렉토리가 아닌 static 페이지 생성시
https://nextjs.org/docs/api-reference/next.config.js/basepath

Quill

잠재적 성공

예제: https://dmc31a42.github.io/react-wysiwyg-research/quill-2-0-0-beta-4-mention-3-1-0/index.html
'@한글 테스트 문구'를 입력할 때 스테이트의 변화가 정확히 반영되고, 멘션에서 일치하는 글자 찾기도 정확히 동작함

예제는 2.0.0-beta.4로 테스트 했지만 1.1.0도 정상적으로 동작함 (리액트 버전 17버전은 2.0.0-beta만 지원)
안드로이드 크롬에서도 정상동작
WSA에서만 약간 문제가 있지만 크게 문제있지는 않음

뱀발

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/RegExp정규 표현식과 Unicode 문자 라는게 있군요
https://caniuse.com/?search=Unicode%20property%20escape
IE11을 제외한 모든 브라우저에서 사용가능합니다.
IE11을 써야하는 상황이라도 위 링크의 '유니코드 속성 이스케이프'에서 'General_Category' 에 들어가보면 카테고리에 해당하는 문자를 추출할 수 있음

https://quilljs.com/guides/comparison-with-other-rich-text-editors/ 에서 에디터 비교

뱀발2

deplay cra to subdirectory
https://create-react-app.dev/docs/deployment/#building-for-relative-paths

Prosemirror

잠재적 성공

react-prosemirror: 2.0.3
prosemirror-mentions: 1.0.2
예제: https://dmc31a42.github.io/react-wysiwyg-research/prosemirror-2-0-3-mentions-1-0-2/index.html

'@한글 입력 인식'을 천천히 입력하고 ' 인식'을 지운 뒤 '한글 입력 인식 텍스트' suggestion을 누름, 첫 한 글자는 박스 처리가 제대로 되지 않아 getBoundingClientRect 오류, suggestion 목록이 한개라도 없으면 classList 오류 등 오류가 표시되긴 함

https://github.com/joelewis/prosemirror-mentions/blob/c8ee329b52a26769877a105802f99996e9a8fc28/src/mentionPlugin.js#L12-L14 에서 한글을 인식할 수 있도록

  var mention = allowSpace
    ? new RegExp("(^|\\s)" + mentionTrigger + "([\\w-\\+]+\\s?[\\w-\\+]*)$")
    : new RegExp("(^|\\s)" + mentionTrigger + "([\\w-\\+]+)$");

  var mention = allowSpace
    ? new RegExp("(^|\\s)" + mentionTrigger + "((?:\p{L}|[-\\+])+\\s?(?:\p{L}|[-\\+])*)$")
    : new RegExp("(^|\\s)" + mentionTrigger + "((?:\p{L}|[-\\+])+)$");

로 변경하고
플러그인에 소소한 예외 처리가 필요하지만 스테이트 반영은 정상적으로 됨

Trix

TinyMCE

https://www.tiny.cloud/docs/plugins/premium/mentions/

CKEditor

https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html

참고

https://www.w3.org/TR/ime-api/
https://www.w3.org/TR/input-events-2/
https://github.com/w3c/uievents/issues/202
https://ntalbs.github.io/2015/editor-ime/
https://w3c.github.io/input-events/#event-order-during-ime-composition
https://firefox-source-docs.mozilla.org/editor/IMEHandlingGuide.html
https://developer.mozilla.org/ko/docs/Web/API/MutationObserver
https://dvcs.w3.org/hg/d4e/raw-file/tip/key-event-test.html 키보드 입력시 이벤트를 보기 명확하게 확인할 수 있는 사이
https://github.com/StevenDevooght/tinyMCE-mention/issues/50
https://developer.mozilla.org/en-US/docs/Mozilla/IME_handling_guide
https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/
https://github.com/ianstormtaylor/slate/issues/2368
https://github.com/ianstormtaylor/slate/issues/2062
https://jheo.io/blog/a-tales-of-two-editor/ Quill, ProseMirror 비교
https://github.com/zurb/tribute no Dependency mention plugin

profile
한 발자국 성장하는 개발자

0개의 댓글