아이디어 및 접근 방식
사용자가 블로그 에디터에 다른 아티클의 URL을 붙여넣으면, 해당 URL이 아티클의 제목으로 자동 변환되어 하이퍼링크가 걸리는 것이 핵심 아이디어입니다. 이를 위해 Trix 에디터의 trix-paste
이벤트를 Stimulus 컨트롤러로 처리하는 방식을 채택했습니다.
Trix 및 Stimulus를 활용한 구현 단계
- Stimulus 컨트롤러 바인딩:
Trix 에디터(
form.rich_text_area
)에data-controller="url-link"
와data-action="trix-paste->url-link#handlePaste"
를 추가하여 붙여넣기 이벤트를url-link
컨트롤러의handlePaste
메서드에 연결합니다. - 붙여넣기 이벤트 처리 (
handlePaste
):event.paste
객체에서getPlainTextFromPaste
헬퍼를 통해 순수 텍스트를 추출합니다. 추출된 텍스트가 현재 애플리케이션의 도메인(window.location.origin
)으로 시작하는 URL인지 확인하여 외부 링크는 처리하지 않습니다. 사용자가 붙여넣은 내용을 시각적으로 인지할 수 있도록 100ms의setTimeout
을 사용하여replacePastedUrl
함수를 비동기적으로 호출합니다. - URL을 링크로 교체 (
replacePastedUrl
):fetchTitle
함수를 호출하여 URL에 해당하는 아티클의 제목을 비동기적으로 가져옵니다. Trix 에디터의 현재 선택 범위(editor.getSelectedRange()
)와 붙여넣은 URL의 길이를 이용하여 URL 텍스트의 정확한 범위를 계산합니다.editor.setSelectedRange(range)
를 통해 URL 텍스트를 선택한 후,editor.activateAttribute("href", url)
로 링크 속성을 활성화하고,editor.insertString(title)
로 아티클 제목을 삽입합니다. 마지막으로editor.deactivateAttribute("href")
를 호출하여 링크 속성 적용을 완료합니다. - 아티클 제목 가져오기 (
fetchTitle
):fetch(url)
을 사용하여 대상 URL의 HTML 콘텐츠를 가져옵니다.DOMParser().parseFromString(html, "text/html")
을 통해 HTML 문자열을 DOM 객체로 파싱합니다.doc.querySelector("title")?.textContent?.trim()
을 사용하여<title>
태그의 텍스트 내용을 추출합니다. 제목이 없으면 원본 URL을 반환합니다. - 붙여넣기 콘텐츠 정규화 (
getPlainTextFromPaste
): 붙여넣기 이벤트의paste
객체는string
또는html
속성을 가질 수 있습니다. 이 헬퍼 함수는paste.string
이 존재하면 이를 반환하고,paste.html
이 존재하면 임시div
요소를 생성하여 HTML을 삽입한 후textContent
또는innerText
를 추출하여 항상 순수 텍스트를 반환하도록 합니다.