현재 Discourse에서 작성기에 일반 텍스트를 붙여넣으면, 일반적인 브라우저 동작에 따라 Ctrl+Z를 누르면 해당 붙여넣기가 실행 취소되어 붙여넣은 텍스트가 제거됩니다. 그러나 이처럼 굵은 글씨로 표시된 서식이 있는 텍스트를 붙여넣은 경우 실행 취소가 작동하지 않습니다. 마찬가지로, 링크를 텍스트 위에 붙여넣어 링크로 변환하는 작업도 실행 취소할 수 없으며, Ctrl+B와 같은 단축키를 통해 삽입된 마크다운이나 작성기 도구 모음 옵션에서 서식을 추가할 때 삽입된 마크다운도 실행 취소할 수 없습니다. 이상적으로는 Ctrl+Z가 정상적으로 작동하도록 가능한 한 많은 작업이 실행 취소 스택에 추가되어야 합니다.
자주 발생하는 상황에 대해 설명해 드리겠습니다.
다른 웹사이트에서 링크, 굵은 글씨, 헤더 등 서식이 적용된 텍스트를 복사합니다. (때로는 이 사실을 인지하고, 때로는 인지하지 못합니다.)
Discourse로 가서 이 텍스트를 이미 일부 작성한 게시글에 붙여넣습니다.
Ctrl+V를 눌러 서식이 있는 텍스트를 삽입합니다.
실수를 인지하고 Ctrl+Z를 누르지만 아무 일도 일어나지 않습니다.
실수로 삽입한 서식이 있는 텍스트를 수동으로 제거합니다. (대부분 실수로 붙여넣은 링크 버전이므로 단순히 # 같은 것을 제거하는 수준이 아닙니다.)
처음부터 서식이 없는 텍스트를 붙여넣기 위해 Ctrl+Shift+V를 눌러야 했었습니다.
물론 이는 부분적으로 사용자 실수이며, 실수를 하지 않을 때는 단 두 단계(다른 웹사이트에서 복사, Discourse에 일반 텍스트로 붙여넣기)로 끝납니다. 하지만 실수를 할 때(대부분의 웹사이트가 서식이 있는 붙여넣기를 하지 않으므로 Ctrl+V를 누르는 데 익숙해져 있어 자주 발생합니다) Ctrl+Z가 정상적으로 작동하여 시간을 절약할 수 있다면 좋겠습니다.
맞습니다, JavaScript를 사용해 입력값을 수정할 경우 기본적으로 실행 취소(undo) 기능이 작동하지 않습니다. 하지만 검색해 보니 document.execCommand를 사용하면 실행 취소 스택에 추가하면서 텍스트를 삽입할 수 있다는 것을 알게 되었습니다.
예를 들어 document.getElementById('myInput').value = 'asd'를 실행한 뒤 Ctrl+Z를 누르면 실행 취소가 되지 않습니다.
반면, 커서가 원하는 위치에 있는 상태에서(현재 Discourse 워크플로우에 따라 그렇게 되어 있어야 합니다) document.execCommand('insertText', false, 'asd')를 실행하면 텍스트가 올바르게 삽입되고, Ctrl+Z를 누르면 추가된 텍스트가 예상대로 제거됩니다.
결국, document.execCommand(또는 다른 접근 방식이 더 나은 것으로 판단될 경우 다른 프로세스)를 사용하여 실행 취소 스택에 추가함으로써 이러한 경우에도 Ctrl+Z가 정상적으로 작동하게 할 수 있는지 궁금합니다.
무언가를 놓치고 있는 것 같습니다. "브라우저 네이티브 텍스트 박스의 실행 취소 처리가 작동하도록 하는 것"이 정확히 무슨 의미인가요? 제가 파악한 바로는 Discourse에서 서식이 있는 텍스트의 실행 취소 기능이 전혀 작동하지 않는 것 같은데, 실행 취소가 작동하지 않는 것이 표준 웹사이트 동작 방식이라는 말씀인가요?
혼란스러운 이유는 Discourse를 제외하고는 Microsoft Word처럼 실행 취소가 작동하는 것들을 제외하면 서식이 있는 붙여넣기를 지원하는 웹사이트를 하나도 떠올릴 수 없기 때문입니다. 따라서 "표준"이 무엇인지 확인하기 위해 Discourse와 비교할 대상을 찾을 수 없습니다. 비교를 위해 몇 가지 웹사이트를 알려주시면 정말 도움이 될 것입니다.
제 이해로는 @seanblue 님이 textarea를 조작할 때 사용하는 브라우저 API를 수정하여, 브라우저가 undo(실행 취소)를 좀 더 잘 처리할 수 있도록 힌트를 줄 수 있는지 묻고 계신 것 같습니다. 따라서 이는 키보드 단축키, 도구 모음, 업로드 등에만 적용될 것입니다.
여기서 설정을 조정하는 것에 반대하지는 않지만, 일부 API는 많은 주의가 필요할 수 있으며, 회귀 오류(regression)가 발생할 위험이 분명히 있다고 우려합니다.
실험에는 반대하지 않습니다. 커뮤니티에서 이렇게 하는 방법을 보여줄 수 있는 PR을 보내주신다면 좋겠습니다.
하지만 그 텍스트 박스는 포맷된 텍스트를 처리하지 못하는데, 제가 말하는 건 그 문제가 아닙니다. 브라우저가 직접 입력하거나 붙여넣기한 텍스트의 되돌리기를 정상적으로 처리한다는 점은 알고 있습니다. 제가 지적하는 것은 Discourse가 붙여넣기한 포맷된 텍스트의 되돌리기를 처리하지 못한다는 것입니다. 제가 말하는 내용을 확인하려면 다음 단계를 따라 해보세요.
맞습니다. 자바스크립트로 직접 되돌리기를 처리하라고 제안하는 것이 아닙니다. 텍스트 영역을 조작할 때 브라우저에 알리도록 하여, 사용자가 ctrl+z를 누르면 브라우저가 변경 사항을 스스로 되돌릴 수 있도록 하자는 것입니다.
참고로, 포맷된 텍스트를 붙여넣은 후 ctrl+z가 작동하기만 하면 제 불만의 99%는 해결될 것입니다. 모든 단일 작업이 ctrl+z로 되돌려지는 것이 이상적이겠습니까? 물론 그렇습니다. 하지만 대부분의 다른 작업은 원래 작업을 반복함으로써 되돌릴 수 있습니다(예: ctrl+b는 굵은 글씨 마크다운을 추가하고 제거할 수 있습니다). 하지만 붙여넣기는 헤더, 링크, 심지어 테이블까지 포함하는 상당량의 예상치 못한 마크다운을 포함할 가능성이 있기 때문에, 그 경우 되돌리기가 작동하는 것이 매우 중요합니다.
범위를 포맷된 붙여넣기 케이스의 되돌리기 처리에만 한정하고 다른 단축키, 툴바 버튼 등은 무시한다면, 시도해 볼 만큼 위험을 줄일 수 있을까요?
아, 그렇군요. 당신과 @david님의 설명 덕분에 그 차이를 이해했습니다. 사실 저는 대부분 에디터에서 그 버튼들을 사용하지 않습니다. 컴퓨터 키보드(물리적 키보드든 화면 키보드든)를 이용해 텍스트 상자에 직접 입력하거든요. 이 과정은 브라우저가 매끄럽게 처리해 줍니다.
그 점은 충분히 이해합니다. 저도 툴바 버튼을 사용하는 대신 마크다운을 직접 입력하는 경향이 있어서, 그 부분은 저에게 큰 문제가 되지 않습니다. 처음 게시글에서 툴바 관련 내용을 언급한 것은, 서식이 있는 텍스트를 붙여넣을 때만 그런 현상이 발생하는 것이 아니라는 점을 지적하기 위해서였습니다. 툴바 작업을 실행 취소할 수 있는 기능은 사용자가 의도적으로 해당 작업을 수행하는 것이므로 그다지 중요하지 않습니다. 하지만 붙여넣기할 경우 서식은 종종 우발적이고 의도치 않게 적용되므로, 이를 실행 취소할 수 있다면 매우 편리할 것입니다.
조금 복잡한 문제이지만, 우리는 리치 에디터 실험이라는 영역에 진입하기를 원합니다. 이 작업이 바로 그 가능성을 열어줄 것입니다.
이 작업이 핵심 경로(critical path)에 있는 이유는, 우리의 내부 구조 전체가 특정 구현(TEXTAREA)에 강하게 결합되어 있기 때문입니다. 컴포저(composer)와 인터페이스를 위한 단일 함수가 있는 것이 아니라, 마치 20개의 다른 구현을 잘라 붙여 넣는 것과 같습니다.
우리가 하고 싶은 일은 다음과 같은 작은 “스켈레톤” 컴포넌트를 만드는 것입니다.
텍스트를 선택하는 방법
텍스트를 삽입하는 방법
그리고 그 밖의 것들… 이렇게 하면 스켈레톤을 contenteditable 또는 UNDO 기능이 지원되는 TEXTAREA 구현으로 재구현할 수 있습니다.
이것은 @sam이 설명한 장기적인 작업만큼 포괄적이지는 않습니다. 하지만 단기적으로는 도움이 될 것이라고 생각합니다. 이 변경 사항은 리치 텍스트를 붙여넣거나, 인용을 사용하거나, (대부분의) 작성기 버튼/키보드 단축키를 사용할 때 실행 취소(undo) 이력을 보존해야 합니다.