Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 명세는 텍스트 및 관련 입력 이벤트에 대한 확장 기능을 정의하여, 텍스트 편집기 애플리케이션 및 텍스트 입력과 서식을 처리하는 기타 애플리케이션에서 기본 브라우저 동작을 모니터링하고 조작할 수 있도록 합니다. 이 명세는 UI 이벤트 명세 [UI-EVENTS]를 기반으로 합니다.
이 섹션은 본 문서가 공개된 시점의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.
입력 이벤트 레벨 2는 Input Events의 첫 번째 버전 [INPUT-EVENTS]을 대체하며 다음을 포함합니다:
입력 이벤트 명세를 위한 테스트 스위트 및 구현 보고서는 아직 작업 중입니다.
이 문서는 웹 편집 작업 그룹에서 권고안 트랙을 사용하여 작업 초안으로 발행되었습니다.
작업 초안으로 발행된 것은 W3C 및 회원의 지지를 의미하지 않습니다.
이 문서는 초안이며 언제든지 업데이트, 대체, 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 부적절합니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 공개 특허 공개 목록을 유지합니다. 이 목록에는 그룹 산출물과 관련하여 제출된 특허 공개가 있으며, 특허 공개 방법에 대한 지침도 포함되어 있습니다. 개인이 특정 특허가 필수 청구항을 포함한다고 판단할 경우, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.
이 문서는 2023년 11월 3일 W3C 프로세스 문서를 따릅니다.
이 문서는 편집과 관련된 2가지 이벤트 - input 및 beforeinput에 대한 확장 사항을 설명하며, 이는 UI 이벤트 명세 [UI-EVENTS]에 정의되어 있습니다. 이러한 이벤트의 목적은 저자가 편집이 발생하기 전후에 기본 편집 동작을 이해하거나 재정의할 수 있도록 하는 것입니다.
비규범적으로 표시된 섹션뿐만 아니라, 이 명세서의 모든 작성 지침, 다이어그램, 예시, 참고 사항은 비규범적입니다. 그 외의 모든 내용은 규범적입니다.
이 문서에서 MAY, MUST, MUST NOT라는 핵심 단어는 BCP 14 [RFC2119] [RFC8174] 에서 설명된 대로, 이와 같이 모두 대문자로 표시된 경우에만 해당 의미로 해석되어야 합니다.
이 정의는 규범적이지 않습니다.
킬 버퍼는 클립보드와 분리된 리치텍스트 콘텐츠의 메모리 저장소로, 특정 삭제 명령을 통해 삭제된 콘텐츠를 임시 저장할 수 있습니다. 사용자는 킬 버퍼에 저장된 콘텐츠로 현재 선택 영역을 yank 명령을 통해 대체할 수 있습니다.이 섹션은 규범적이지 않습니다.
웹 기반 텍스트 에디터를 만들기 위해서는 브라우저 코드 외에도 상당한 양의 JavaScript가 필요합니다. 그 이유는 다음과 같습니다:
이 명세는 웹 개발자가 beforeinput 이벤트를 통해 텍스트 편집과 관련된 모든 사용자 입력에 대한 브라우저 처리 방식을 재정의하고, input 이벤트를 통해 사용자 입력으로 인해 브라우저가 DOM에 변경한 내용을 모니터링할 수 있는 간단한 방법을 제공하여 이러한 문제를 완화하고자 합니다.
이 섹션은 규범적이지 않습니다.
입력 이벤트는 사용자가 마크업을 편집하려고 시도하기 전(beforeinput 이벤트)과 후(input 이벤트)에 전송됩니다. 여기에는 콘텐츠 삽입 및 삭제, 서식 변경이 포함됩니다.
입력 이벤트는 디스패치되어 편집 호스트
역할을 하는 요소(예: contenteditable 속성이 설정된 요소,
textarea
요소,
input
요소 중 텍스트 입력이 허용되는 요소)에서 발생합니다.
WebIDLpartial interface InputEvent {
readonly attribute DataTransfer? dataTransfer
;
sequence<StaticRange> getTargetRanges
();
};
partial dictionary InputEventInit {
DataTransfer? dataTransfer
= null;
sequence<StaticRange> targetRanges
= [];
};
inputType
, dataTransfer
및
targetRanges
속성은 InputEventInit
객체의 해당 속성을 초기화합니다.
이 섹션은 규범적이지 않습니다.
아래 표는 data
및
dataTransfer
속성에 값이 들어있는 경우와 null인
경우,
그리고 getTargetRanges()
메서드가 inputType에
따라
빈 배열 또는 비어있지 않은 배열을 반환하는 경우를 요약합니다.
편집 호스트 | inputType | data | dataTransfer | getTargetRanges() |
---|---|---|---|---|
Contenteditable |
"insertText" ,
"insertCompositionText" ,
"formatSetBlockTextDirection" ,
"formatSetInlineTextDirection" ,
"formatBackColor" ,
"formatFontColor" ,
"formatFontName" , "insertLink"
|
있음 | null | 비어있지 않은 배열 |
Contenteditable |
"insertFromPaste" ,
"insertFromPasteAsQuotation" ,
"insertFromDrop" ,
"insertReplacementText" ,
"insertFromYank"
|
null | 있음 | 비어있지 않은 배열 |
<textarea> , <input
type="text">
|
"insertText" ,
"insertCompositionText" ,
"insertFromPaste" ,
"insertFromPasteAsQuotation" ,
"insertFromDrop" ,
"insertReplacementText" ,
"insertFromYank" ,
"formatSetBlockTextDirection" ,
"formatSetInlineTextDirection" ,
"formatBackColor" ,
"formatFontColor" ,
"formatFontName" , "insertLink"
|
있음 | null | 빈 배열 |
모든 호스트 |
"historyUndo" , "historyRedo"
|
null | null | 빈 배열 |
Contenteditable | 나머지 모두 | null | null | 비어있지 않은 배열 |
<textarea> , <input
type="text">
|
나머지 모두 | null | null | 빈 배열 |
beforeinput 이벤트의 취소 가능성은 inputType에 따라 달라집니다.
선택되는 inputType은 사용자의 의도 표현, IME 조합 중 편집이 이루어지는지 여부, 그리고 선택 상태에 따라 결정됩니다.
이 명세서에서는 아래 표의 inputType 열의 값을 inputType 값으로 정의합니다.
inputType | 사용자의 의도 표현 | IME 조합의 일부 | beforeinput 취소 가능 | 선택 상태 |
---|---|---|---|---|
"insertText"
|
입력한 평문 텍스트 삽입 | 아니오 | 예 | 임의 |
"insertReplacementText"
|
맞춤법 검사기, 자동 교정, 오타 제안 등으로 기존 콘텐츠 삽입 또는 교체 | 아니오 | 예 | 임의 |
"insertLineBreak"
|
줄 바꿈 삽입 | 아니오 | 예 | 임의 |
"insertParagraph"
|
단락 구분 삽입 | 아니오 | 예 | 임의 |
"insertOrderedList"
|
번호 매김 목록 삽입 | 아니오 | 예 | 임의 |
"insertUnorderedList"
|
글머리표 목록 삽입 | 아니오 | 예 | 임의 |
"insertHorizontalRule"
|
수평선 삽입 | 아니오 | 예 | 임의 |
"insertFromYank"
|
현재 선택 영역을 킬 버퍼에 저장된 콘텐츠로 대체 | 아니오 | 예 | 임의 |
"insertFromDrop"
|
드롭으로 콘텐츠 삽입 | 아니오 | 예 | 임의 |
"insertFromPaste"
|
클립보드에서 콘텐츠 붙여넣기 또는 클라이언트 이미지 라이브러리에서 이미지 붙여넣기 | 아니오 | 예 | 임의 |
"insertFromPasteAsQuotation"
|
클립보드에서 콘텐츠를 인용으로 붙여넣기 | 아니오 | 예 | 임의 |
"insertTranspose"
|
마지막으로 입력한 두 그래프 클러스터 교환 | 아니오 | 예 | 임의 |
"insertCompositionText"
|
현재 조합 문자열 대체 | 예 | 아니오 | 임의 |
"insertLink"
|
링크 삽입 | 아니오 | 예 | 임의 |
"deleteWordBackward"
|
캐럿 위치 바로 앞의 단어 삭제 | 아니오 | 예 | 축소됨 |
"deleteWordForward"
|
캐럿 위치 바로 뒤의 단어 삭제 | 아니오 | 예 | 축소됨 |
"deleteSoftLineBackward"
|
캐럿 위치에서 가장 가까운 시각적 줄 바꿈 전까지 삭제 | 아니오 | 예 | 축소됨 |
"deleteSoftLineForward"
|
캐럿 위치에서 가장 가까운 시각적 줄 바꿈 후까지 삭제 | 아니오 | 예 | 축소됨 |
"deleteEntireSoftLine"
|
캐럿 위치 전후의 가장 가까운 시각적 줄 바꿈 사이 전체 삭제 | 아니오 | 예 | 축소됨 |
"deleteHardLineBackward"
|
캐럿 위치에서 가장 가까운 블록 요소 또는
br
요소 전까지 삭제
|
아니오 | 예 | 축소됨 |
"deleteHardLineForward"
|
캐럿 위치에서 가장 가까운 블록 요소 또는
br
요소 후까지 삭제
|
아니오 | 예 | 축소됨 |
"deleteByDrag"
|
드래그로 DOM에서 콘텐츠 제거 | 아니오 | 예 | 임의 |
"deleteByCut"
|
잘라내기의 일환으로 현재 선택 영역 제거 | 아니오 | 예 | 임의 |
"deleteContent"
|
삭제 방향을 지정하지 않고 선택 영역을 삭제하며, 이 의도가 다른 inputType에 포함되지 않은 경우 | 아니오 | 예 | 축소되지 않음 |
"deleteContentBackward"
|
캐럿 바로 앞의 콘텐츠를 삭제하며, 이 의도가 다른 inputType에 포함되지 않거나 삭제 후 선택이 시작 위치로 축소되는 경우 | 아니오 | 예 | 임의 |
"deleteContentForward"
|
캐럿 바로 뒤의 콘텐츠를 삭제하며, 이 의도가 다른 inputType에 포함되지 않거나 삭제 후 선택이 끝 위치로 축소되는 경우 | 아니오 | 예 | 임의 |
"historyUndo"
|
마지막 편집 작업 실행 취소 | 아니오 | 예 | 임의 |
"historyRedo"
|
마지막 취소된 편집 작업 다시 실행 | 아니오 | 예 | 임의 |
"formatBold"
|
굵게 서식 시작 | 아니오 | 예 | 임의 |
"formatItalic"
|
이탤릭 서식 시작 | 아니오 | 예 | 임의 |
"formatUnderline"
|
밑줄 서식 시작 | 아니오 | 예 | 임의 |
"formatStrikeThrough"
|
취소선 서식 시작 | 아니오 | 예 | 임의 |
"formatSuperscript"
|
위 첨자 서식 시작 | 아니오 | 예 | 임의 |
"formatSubscript"
|
아래 첨자 서식 시작 | 아니오 | 예 | 임의 |
"formatJustifyFull"
|
현재 선택 영역 전체 정렬 | 아니오 | 예 | 임의 |
"formatJustifyCenter"
|
현재 선택 영역 가운데 정렬 | 아니오 | 예 | 임의 |
"formatJustifyRight"
|
현재 선택 영역 오른쪽 정렬 | 아니오 | 예 | 임의 |
"formatJustifyLeft"
|
현재 선택 영역 왼쪽 정렬 | 아니오 | 예 | 임의 |
"formatIndent"
|
현재 선택 영역 들여쓰기 | 아니오 | 예 | 임의 |
"formatOutdent"
|
현재 선택 영역 내어쓰기 | 아니오 | 예 | 임의 |
"formatRemove"
|
현재 선택 영역의 모든 서식 제거 | 아니오 | 예 | 임의 |
"formatSetBlockTextDirection"
|
텍스트 블록 방향 설정 | 아니오 | 예 | 임의 |
"formatSetInlineTextDirection"
|
텍스트 인라인 방향 설정 | 아니오 | 예 | 임의 |
"formatBackColor"
|
배경색 변경 | 아니오 | 예 | 임의 |
"formatFontColor"
|
글자색 변경 | 아니오 | 예 | 임의 |
"formatFontName"
|
글꼴 변경 | 아니오 | 예 | 임의 |
inputTypes
가 모두 지원된다는 의미는 아닙니다.
특정 브라우저가 DOM 변경을 초래할 수 있는 편집 작업을 지원한다면 반드시 해당 beforeinput
및 input
이벤트를
발생시켜야 합니다.
"deleteContentBackward"
는 사용자가 텍스트 노드 내에서 텍스트 삭제를 요청할 때뿐만 아니라
더 복잡한 요소 삭제 또는 문단 병합 의도가 있을 때(캐럿이 텍스트 노드 시작에 있을 때)에도 사용됩니다.
"deleteContentForward"
는 사용자가 텍스트 노드 내에서 텍스트 삭제를 요청할 때뿐만 아니라
더 복잡한 요소 삭제 또는 문단 병합 의도가 있을 때(캐럿이 텍스트 노드 끝에 있을 때)에도 사용됩니다.
data
속성은 문서에 추가될 평문 데이터 정보를 담고 있습니다.
inputType | 편집 호스트 | data |
---|---|---|
"insertText" 또는
"insertCompositionText"
|
임의 | 삽입될 평문 문자열 |
"insertFromPaste" ,
"insertFromPasteAsQuotation" ,
"insertFromDrop" ,
"insertTranspose" ,
"insertReplacementText" 또는
"insertFromYank"
|
input
또는
textarea
|
삽입될 평문 문자열 |
"formatSetInlineTextDirection" 또는
"formatSetBlockTextDirection"
|
임의 |
"ltr" , "rtl" , "auto"
또는 "null"
|
"formatBackColor" 또는
"formatFontColor"
|
임의 | 제안된 색상의 CSS 컴포넌트 값 직렬화 문자열 [CSSOM] |
"formatFontName"
|
임의 | font-family CSS 속성의 제안 값 |
"insertLink"
|
임의 | 제안된 링크의 url |
나머지 모두 | 임의 | null |
dataTransfer
속성은 관련 데이터가 있을 경우
DataTransfer
객체에서 문서에 추가되거나 가져올 리치텍스트 및 평문 데이터 정보를 담고 있습니다.
inputType | 편집 호스트 | dataTransfer |
---|---|---|
"insertFromPaste" ,
"insertFromPasteAsQuotation" ,
"insertFromDrop" ,
"insertTranspose" ,
"insertReplacementText" 또는
"insertFromYank"
|
contenteditable
|
사전 채워진 DataTransfer
객체로서:
|
나머지 모두 | 임의 | null |
getTargetRanges()
는 이벤트가 취소되지 않으면 이벤트가 수정할
콘텐츠를 나타내는 StaticRanges 배열을 반환하며, 편집 호스트가
contenteditable 노드 또는
EditContext 편집 호스트인 경우에 해당합니다. 그 외에는 아무것도 반환하지 않습니다. 반환되는 StaticRanges는 브라우저가 일반적으로 교체할 코드 포인트만을 반드시 포함해야 하며, 코드 포인트가 그래프 클러스터 일부일지라도 해당합니다.
inputType | 편집 호스트 |
getTargetRanges() 의 응답
|
---|---|---|
"historyUndo" 또는 "historyRedo"
|
임의 | 빈 배열 |
나머지 모두 |
contenteditable
|
이벤트와 연결된 StaticRanges [DOM] 배열 |
나머지 모두 |
input
또는
textarea
|
빈 배열 |
inputType이 "historyUndo"
또는
"historyRedo"
이거나 편집 호스트가
contenteditable 요소가 아닌 경우에는 빈 배열을 반환합니다. 그렇지 않은 경우 배열을 반환합니다.
beforeinput
타입 |
beforeinput
|
---|---|
인터페이스 |
InputEvent
|
동기/비동기 | 동기 |
버블링 | 예 |
신뢰된 타겟 |
편집 호스트 인
모든 Element
|
기본 동작 [UI-EVENTS] |
|
컨텍스트 (신뢰된 이벤트) |
|
사용자 에이전트는 사용자가 contenteditable 요소에 입력을 시도하면 반드시 이 이벤트를 디스패치해야 합니다. 반드시 사용자 에이전트가 DOM을 업데이트한다는 의미는 아닙니다.
사용자 에이전트는 사용자가 입력을 시도하지 않은 이벤트(예: 시스템 이벤트)로 인해 이 이벤트를 디스패치해서는 안 됩니다.
input
타입 |
input
|
---|---|
인터페이스 |
InputEvent
|
동기/비동기 | 동기 |
버블링 | 예 |
신뢰된 타겟 |
contenteditable 속성이 활성화된 모든 Element
|
기본 동작 [UI-EVENTS] | 없음 |
컨텍스트 (신뢰된 이벤트) |
|
사용자 에이전트는 사용자가 문서 내용을 변경하려는 의도를 표현하고 브라우저가 이를 처리하여 DOM이 업데이트된 직후 반드시 이 이벤트를 디스패치해야 합니다. 브라우저가 DOM을 변경하지 않은 경우, 예를 들어 편집 호스트가 EditContext 편집 호스트이거나(자동 DOM 변경을 하지 않음), 사용자 에이전트가 DOM 변경이 필요 없다고 판단한 경우에는 반드시 이 이벤트를 디스패치해서는 안 됩니다.
조합의 시작은 compositionstart 이벤트를 디스패치하여 표시됩니다.
조합 세션 동안 텍스트 조합 시스템이 활성 텍스트 구절을 업데이트할 때마다 compositionupdate 이벤트가 디스패치됩니다.
각 compositionupdate
이벤트 이후에 beforeinput
과 input
이벤트 쌍이 디스패치됩니다.
beforeinput
및 input
이벤트는:
inputType
이
"insertCompositionText"
로 설정됨
data
속성이 compositionupdate
이벤트의 값과 동일함
targetRange
가 조합의 활성 텍스트 구절을 둘러쌈
활성 텍스트 구절의 DOM 내용은 beforeinput
이벤트가 디스패치된 후, input
이벤트가 디스패치되기 전에 업데이트됩니다.
조합 세션의 끝은 compositionend 이벤트를 디스패치하여 표시됩니다.
"insertFromPaste"
beforeinput
이벤트가 디스패치될 때, 반드시 그 전에
paste
[CLIPBOARD-APIS] 이벤트가 있어야 합니다.
이 섹션은 규범적이지 않습니다.
이 기능은 기존 이벤트(예: keydown
및 keypress
[UI-EVENTS]
이벤트)를 통해 이미 이용 가능한 지문 채취
[fingerprinting-guidance]
기법 외에는 알려진 보안 또는 개인정보 영향이 없습니다.
만약 이 기능이 기존 이벤트를 대체한다면, 사용자의 의도가 기록되고, 사용자가 이 의도를 표현하는 데 사용한 특정 하드웨어 유형이 기록되지 않으므로 지문 채취 [fingerprinting-guidance] 기법의 감소로 이어질 수 있습니다.
Michael Aufreiter, Adrian Bateman, Oliver Buchtala, Robin Berjon, Enrica Casucci, Bo Cupp, Domenic Denicola, Emil Eklund, Olivier Forget, Aryeh Gregor, Marijn Haverbeke, Yoshifumi Inoue, Koji Ishii, Gary Kacmarcik, Ian Kilpatrick, Frederico Caldeira Knabben, Takayoshi Kochi, Piotrek Koszuliński, Travis Leithead, Grisha Lyukshin, Miles Maxfield, Chaals McCathie Nevile, Masayuki Nakano, Ryosuke Niwa, Julie Parent, Ben Peters, Florian Rivoal, Morgan Smith, Hallvord R. M. Steen, Johan Sörlin, Cristian Talau, Dave Tapuska, Ojan Vafai, Léonie Watson, Xiaoqian Wu, Chong Zhang, Joanmarie, 그리고 Editing Taskforce의 모든 분들께 의견과 피드백에 감사드립니다.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: