Thief of Wealth

오늘은 코드 작업량이 조금 많았습니다.

 

1. textarea의 link부분을 자동으로 하이퍼링크 처리하기

 

- 원래는 div contenteditable 이었다.

 

원래 다라쓰는 나중에 작업할 수도 있는 markdown 문법을 위해서,

댓글입력요소를 textarea가 아니라,  div contenteditable로 관리하고 있었습니다.

div contenteditable은 입력하는 요소들이 html 로 변환되어 들어가는데요.

 

그래서 textContent로 text 문자만 추출해서 댓글로 쓰고 있었습니다.

그러다보니 엔터입력이 무시되었고, 이는 사용자에게 조금 불편할 수 있는 요소였습니다.

 

그래서 innerHTML를 사용하여 사용자가 엔터를 입력시에 들어가는 <br>태그를 그대로 넣어서, 그대로 렌더링하면 엔터가 정상적으로 동작했습니다.

하지만, DB에 html이 저장되는 것이고,

XSS위협이 있을수도있고,

<>태그들이 댓글이 카운팅이 되기 때문에 3000자 글자제한을 정확하게 측정하기 어려웠습니다. (엔터한번에 글자수6개 카운팅됨...)

https://github.com/woowacourse-teams/2021-darass/pull/749

 

[FE][댓글모듈] 댓글 생성 입력시, 엔터입력 무시되는 이슈 수정 by zereight · Pull Request #749 · woowacou

댓글입력을 div의 contenteditable로 구현되어있습니다. 그래서 입력을 html로 받았는데, textContent으로 안전하게 관리하다보니 엔터값들이 입력값에서 항상 무시되었었는데요. 이제 textContent대신 innerH

github.com

 

이렇게 엔터입력이 정상적으로 동작하게 되었습니다!

 

- 문제점

html 요소들이 삽입가능하다보니, 다양한 이미지들도 복붙을 할 수 있었습니다. 그리고 조금 복잡한 svg를 복붙하면 이미지 1개에 3000자가 넘어서 등록할 수 없다는 에러를 띄우기도 했습니다.

그리고, a태그에 링크를 자동으로 삽입하려면 하이퍼링크를 복붙해야만 했습니다.

그리고 div contenteditable 은 크로스 브라우징 이슈가 있었습니다. (사파리, 파이어폭스, 크롬간의 동작에 차이가 있었습니다.)

이건 좀 아니다 싶어서 textarea로 전면 교체하게 되었습니다.

https://github.com/woowacourse-teams/2021-darass/pull/750

 

[FE][댓글모듈] 댓글 입력창을 div contenteditable에서 textarea로 변경 by zereight · Pull Request #750 · woowacou

div contenteditable에 엔터를 추가하도록 html이 삽입가능하게 했더니, 크로스 브라우징 이슈가 있어서 textarea로 변경했습니다. 편집 비밀번호 입력란, 다크모드에서 색상 안보이는 이슈 해결했습니

github.com

 

-  textarea로 입력란들이 모두 교체한 후...

1. textarea의 길이를 가변으로 주기

textarea의 크기가 내용의 크기에 맞추어서 길어지게하는 로직이 필요했습니다.

 

onChange나 렌더링을 할때

$textarea.current.style.height = "inherit";
$textarea.current.style.height = `${$textarea.current.scrollHeight}px`;

위 코드를 이용하면 textarea의 높이를 가변적으로 늘릴 수 있었습니다.

주의) 처음에 inherit을 해주지 않으면 원하는 대로 동작하지 않을때가 있었습니다. (정확한 상황이 기억이 안나네요 ㅜㅜ)

 

 

2. 링크 text에 하이퍼링크를 어떻게 걸어줄지가 문제였습니다.

textarea의 value에는 a태그가 안들어갈것이기 때문입니다.

 

아무리 찾아봐도 마땅한 방법이 떠오르지 않아서,

textarea를 edit하지 않는 경우에는 span태그로 바꾸어서 그 안에 link문자를 잡아서 a태그로 감싸주는 방식으로 바꾸었습니다.

 

https://github.com/woowacourse-teams/2021-darass/pull/754

 

[FE][댓글모듈] 댓글 내용에 link가 있는경우 하이퍼링크처리 by zereight · Pull Request #754 · woowacourse-t

textarea에서 a태그를 삽입할 수 없으므로, editmode가 아닐때는 div태그로 변경. dangerouslySetInnerHTML으로 a태그를 삽입하도록 수정.

github.com

 

로직은 아래와 같이 바뀌었고

      {contentEditable ? (
        <Text
          ref={textAreaRef}
          value={content}
          readOnly={!contentEditable}
          disabled={!contentEditable}
          editable={contentEditable}
          isSecretComment={isSecretComment}
          isSubComment={isSubComment}
          isReadable={isReadable}
          onChange={onChangeTextArea}
          data-testid="comment-text-box-contenteditable-input"
        />
      ) : (
        <Text
          as="span"
          isSubComment={isSubComment}
          editable={contentEditable}
          isSecretComment={isSecretComment}
          isReadable={isReadable}
          dangerouslySetInnerHTML={{ __html: parseLinkTextToHTML(content) }}
        />
      )}

2번째 식을 보면 as로 태그를 span으로 바꿔주는것을 볼 수 있습니다.

그리고 HTML를 삽입하는 것이기 때문에 dangerouslySetInnerHTML를 사용했습니다.

 

그리고 content에서 link를 감지하여 a태그로 감싸주는 함수는 다음과 같이 생겼습니다.

export const parseLinkTextToHTML = (text: string) => {
  const regURL = new RegExp("(http|https|ftp|telnet|news|irc)://([-/.a-zA-Z0-9_~#%$?&=:200-377()]+)", "gi");
  const regEmail = new RegExp("([xA1-xFEa-z0-9_-]+@[xA1-xFEa-z0-9-]+.[a-z0-9-]+)", "gi");

  return text
    .replace(regURL, "<a href='$1://$2' target='_blank'>$1://$2</a>")
    .replace(regEmail, "<a href='mailto:$1'>$1</a>");
};

 

 

 

2. simple-react-query 라이브러리 배포

드디어 react-query가 불편한 사람들을 위한 라이브러리

https://github.com/zereight/simple-react-query

 

GitHub - zereight/simple-react-query: Is react-query heavy? Use simple react-query!

Is react-query heavy? Use simple react-query! Contribute to zereight/simple-react-query development by creating an account on GitHub.

github.com

를 배포했습니다.

 

react-query의 기능들을 간단하게 제공할 수 있도록 계속 업데이트하겠습니다.

profile on loading

Loading...