이전에 개발한 미리보기 토글 버튼 뿐만 아니라 TIL를 많이 작성하는 입장에서 템플릿이 있으면 좋겠다라는 생각을 하였다.
유저가 선택하여 템플릿을 넣는 것 뿐만 아니라 유저가 템플릿을 저장할 수도 있어야 하고 얼마든지 본인이 만든 템플릿을 수정할 수 있어야 한다.
앞으로의 목표는 다음과 같다.
우선, 에디터에 템플릿을 사용자가 작성을 하면 어떻게 해당 데이터를 가져와서 로컬 스토리지에 저장할 수 있을 것인지를 같이 익스텐션을 개발할 사람과 의논을 해봤다.
velog 페이지를 같이 분석해본 결과 사용자가 에디터에서 작성한 내용은 그냥 text형식으로 저장되는 것이 아닌 여러 line과 그 안 text로 구성돼 있다.
위 그림은 현재 에디터를 작성하면서 생기는 code mirror 라이브러리가 동작하는 모습이다. 한 줄마다 각각의 text를 span tag 내부에 입력이 돼있다.
단순하게 해당 에디터에 있는 모든 태그들과 그 내부 내용을 가져와서 다시 code editor에 붙이면 된다고 생각했다.
해당 기능을 구현하기 위해서 내부 내용을 가져와서 innerHTML를 이용하여 에디터에 붙였는데 code mirror 라이브러리에서 동작하게 만든 이벤트들을 전부 사용을 할 수 없었다.말 그대로 현재 로컬 스토리지에 저장된 값은 그저 string일뿐 그 이상 그 이하도 아니었다.
다른 접근 방법이 필요했고, 의논을 하던 중에 문득 그런 생각이 들어서 물어봤다.
"사용자가 복사 붙여넣기를 하면 괜찮지 않아요? 그럼 js에서 사용자 처럼 복사 붙여넣기를 하면 해당 문제를 해결할 수 있지 않을까요?"
사실 위 과정에서 막힐뻔 했는데 저 생각 하나로 모든 실마리가 풀린 기분이었다. 중요한 것은 paste 이벤트를 어떻게 동작시킬 것인지였다.
많은 검색과 여러 시도 끝에 dispatchEvent라는 등록된 이벤트를 시킬 수 있는 메서드와 새로운 이벤트를 만들 수 있다는 것을 알아냈다.
제대로 실행되는지를 확인하기 위해서 시도 해볼 코드는 다음과 같았다.
const div = document.createElement('div');
div.onpaste = (e) => {
console.log('hello world!');
}
let pasteEvent = new ClipboardEvent('paste');
div.dispatchEvent(pasteEvent); // hello world!
정상적으로 작동되는 것을 확인했다. 그리고 paste Event에는 clipboardData를 이용하여 클립보드에 저장돼 있는 데이터를 가지고 올 수 있는데 이것을 이용하여 데이터를 붙여 넣으면 될 것이라고 생각했는데 새로 만든 ClipboardEvent는 clipboardData에 null이 설정이 돼서 해당 값을 이용할 수 없었다.
여기서 또 한참을 고민을 해보다가 clipboardData를 이미 생성이 완료된 인스턴스에서 변경을 하지 못하게 하지 않았을까라는 생각에 처음에 생성을 할 때 옵션에다가 해당 clipboardData에 데이터를 넣어서 생성을 하자라는 생각까지 미치게 됐다. 이 과정에서 많은 글을 참고했는데 아래와 같은 사진들을 참고하였다.
정리하자면 다음과 같다. ClipboardEvent의 생성자에는 DataTransfer 형식을 가진 clipboardData에 null을 기본값으로 세팅을 한다. 생성자에 값을 넣는 방식이 안나와 있어서 고민을 했는데 그냥 type과 뒤에 객체 형식으로 넣으니 잘 동작을 했다.
const data = new DataTransfer();
data.items.add('hello world','text/plain');
let pasteEvent = new ClipboardEvent('paste',{clipboardData: data});
const div = document.createElement('div');
div.onpaste = (e) => {
console.log(e.clipboardData.getData('text/plain'));
}
div.dispatchEvent(pasteEvent) // 'hello word'
이제 마지막 단계로 현재 velog에서 pasteEvent를 동작시켰을 때 제대로 동작되는지를 확인하면 됐다. 현재 velog에서 paste관련된 이벤트들이 걸린 태그를 찾아보니 하나가 있었다.
이 textarea를 지정하고 pasteEvent를 동작시키니까 잘 동작되는
것을 확인했다.
해당 과정을 거쳐서 결국 다음의 영상처럼 사용을 할 수 있게 됐다.
사실 이벤트 리스너를 등록해서 사용하는 방법은 많이 해봣지만 이렇게 커스텀 이벤트를 만들어서 실행시킬 수 있다라는 것은 이번 일로 처음알게 됐다. 점점 더 자바스크립트가 매력적인 언어라는 것을 느끼게 됐고 조금 더 다양하게 이벤트를 활용할 수 있겠다라는 자신감을 얻었다.