1. 소개
이 섹션은 규범적이지 않습니다.
이 명세서는 시스템 클립보드가 웹 애플리케이션에 어떻게 노출되는지 정의합니다.
이 명세서에는 두 가지 일반적인 API가 설명되어 있습니다:
-
클립보드 이벤트 API - 이 API는 잘라내기, 복사, 붙여넣기와 같은 일반적인 클립보드 작업에 연결하여 웹 애플리케이션이 필요에 따라 클립보드 데이터를 조정할 수 있는 방법을 제공합니다.
-
비동기 클립보드 API - 이 API는 클립보드 데이터를 직접 읽고 쓸 수 있는 접근을 제공합니다. 이는 강력한 기능으로 간주되기 때문에, 이 API에 대한 접근은 권한에 의해 제어됩니다.
2. 사용 사례
이 섹션은 규범적이지 않습니다.
2.1. 기본 클립보드 동작 변경
기본 클립보드 작업(잘라내기/복사/붙여넣기)을 변경하고 싶은 다양한 시나리오가 있습니다. 몇 가지 예시를 들면 다음과 같습니다:
- 메타데이터 문서 저장소에서 텍스트를 복사할 때, 복사된 텍스트에 원본 콘텐츠에 대한 메타데이터를 포함시키는 것이 유용할 수 있습니다.
- 서식 있는 콘텐츠 편집 하이퍼링크나 기타 구조를 포함한 텍스트를 복사할 때, 중요한 정보를 보존하기 위해 콘텐츠를 다시 포맷하는 기능이 종종 필요합니다.
- 내장 의미를 가진 그래픽 웹 애플리케이션에서 서식 있는 텍스트 또는 [SVG11]과 같은 그래픽 콘텐츠를 조작할 수 있도록, 렌더링된 콘텐츠만 복사하는 것이 아니라 더 많은 정보를 복사할 수 있는 메커니즘을 제공하는 것이 유용합니다.
- 수학적 정보 수학과 같은 콘텐츠의 경우, 단순히 렌더링된 텍스트를 복사하여 다른 애플리케이션에 붙여넣으면 대부분의 의미가 손실됩니다. 예를 들어 MathML을 평문 텍스트로 복사할 때는 "^" 기호로 거듭제곱을 표시하는 등 변환이 필요합니다. XML 소스를 클립보드에 넣고, 붙여넣기 시점에 적절한 변환이 이루어질 수도 있습니다.
2.2. 원격 클립보드 동기화
원격 기기와 통신하는 웹 애플리케이션(예: 원격 액세스 또는 원격 셸 애플리케이션)에서는 클립보드 데이터가 두 기기 간에 동기화되어야 할 필요가 자주 있습니다.
이 사용 사례에서 중요한 점은 사용자 제스처나 상호작용 없이도 클립보드에 접근해야 한다는 것입니다.
write()
메서드를 통해 로컬 클립보드에 데이터를 씁니다. clipboardchange
이벤트를 감지하고, 클립보드가 업데이트될 때마다 read()
메서드로 클립보드에서 새로운 데이터를 읽은 후, 그 데이터를 원격 기기로 전송합니다. 2.3. 클립보드 작업 트리거
사용자 에이전트에 대체 인터페이스를 제공하는 애플리케이션은 때때로 사용자 에이전트에서 클립보드 작업을 트리거할 필요가 있습니다.
예를 들어, 보다 접근성 높은 인터페이스를 제공하는 화면 판독기 애플리케이션을 생각해 볼 수 있습니다. 이 판독기는 콘텐츠를 표시하고 사용자가 상호작용할 수 있도록 하지만, 클립보드 복사와 같은 작업은 브라우저에서 수행되어야 클립보드 콘텐츠가 올바르게(브라우저가 복사 시 추가하는 메타데이터 포함) 설정됩니다.
3. 용어 정리
editable context는 editing host이거나 textarea 요소, 또는 type 속성이 "text", "search", "tel", "url", "email", "password", "number" 중 하나로 설정된 input 요소를 의미합니다.
4. 모델
플랫폼은 시스템 클립보드를 제공합니다.
시스템 클립보드는 여러 시스템 클립보드 아이템의 목록을 가지고 있으며, 이들은 총칭해서 시스템 클립보드 데이터라 부릅니다.
각 시스템 클립보드 아이템은 여러 시스템 클립보드 표현의 목록을 가집니다.
각 시스템 클립보드 표현은 문자열인 name과 바이트 시퀀스인 data를 가집니다.
5. 클립보드 이벤트
5.1. 클립보드 이벤트 인터페이스
ClipboardEvent 인터페이스는 Event
인터페이스를 확장합니다.
dictionary :
ClipboardEventInit EventInit {DataTransfer ?=
clipboardData null ; };
- clipboardData
-
이 이벤트와 관련된 데이터 및 메타데이터를 저장하는
DataTransfer
객체입니다.
[Exposed =Window ]interface :
ClipboardEvent Event {(
constructor DOMString ,
type optional ClipboardEventInit = {});
eventInitDict readonly attribute DataTransfer ?; };
clipboardData
- clipboardData
-
clipboardData 속성은
DataTransfer
인터페이스의 인스턴스로, 스크립트가 사용자가 복사, 잘라내기, 붙여넣기 작업을 할 때 시스템 클립보드의 값을 읽고 조작할 수 있도록 합니다. 관련 drag data store는 시스템 클립보드의 필터링된 실시간 뷰로, 구현체가 스크립트가 안전하게 접근할 수 있다고 아는 필수 데이터 타입만 노출합니다. 합성 이벤트에서는 drag data store에 이벤트를 생성한 스크립트가 추가한 데이터만 포함됩니다.clipboardData 객체의
items
및files
속성을 통해 클립보드에서 다중 파트 혹은 비텍스트 데이터를 처리할 수 있습니다.
이 인터페이스는 이벤트를 생성하는 데 사용할 수 있습니다. 아래는 예시입니다:
var pasteEvent = new ClipboardEvent('paste'); pasteEvent.clipboardData.items.add('My string', 'text/plain'); document.dispatchEvent(pasteEvent);
참고: 합성 클립보드 이벤트는 실제로 클립보드나 문서를 변경하지 않습니다. 즉, 위의 스크립트는 paste 이벤트를 발생시키지만, 데이터가 문서에 붙여넣어지지는 않습니다.
5.2. 클립보드 이벤트
5.2.1.
clipboardchange
이벤트
clipboardchange
이벤트는 시스템 클립보드의 내용이 변경될
때마다 발생합니다. 이러한 변경은 다음과 같은 원인(포괄적이지 않음)일 수 있습니다:
-
사용자가 직접 잘라내기나 복사 작업을 수행
-
스크립트가 § 7 비동기 클립보드 API를 사용하여 클립보드에 쓰기
-
사용자 에이전트 외부에서 클립보드가 갱신되는 작업
클립보드 내용이 사용자 에이전트 외부에서 변경된 경우, 사용자 에이전트가 다시 포커스를 얻을 때 clipboardchange
이벤트가 반드시 발생해야 합니다.
합성 cut
및 copy
이벤트는 시스템 클립보드를 갱신하지
않으므로,
"clipboardchange" 이벤트를 트리거하지 않습니다.
5.2.2. copy
이벤트
사용자가 복사 작업을 시작하면, 사용자 에이전트는 클립보드 이벤트 copy
를
발생시킵니다.
이 이벤트가 취소되지 않으면, 현재 선택된 데이터가 시스템 클립보드에 복사됩니다. 현재 문서의 선택 영역은 영향을 받지 않습니다.
copy
이벤트는 버블링되며, 취소 가능하고, composed입니다.
이 이벤트의 처리 모델에 대한 자세한 설명은 § 8.1 복사 동작을 참고하세요.
합성 copy
이벤트를 수동으로 생성하여 디스패치할 수 있지만,
시스템 클립보드의 내용에는 영향을 주지
않습니다.
5.2.3. cut
이벤트
사용자가 잘라내기 작업을 시작하면, 사용자 에이전트는 클립보드 이벤트 cut
를
발생시킵니다.
editable context에서,
이벤트가 취소되지 않으면 선택된 데이터가 시스템
클립보드에 저장되고 문서에서 선택 영역이 제거됩니다.
cut
이벤트는 선택 영역이 제거되기 전에 발생합니다. 잘라내기 작업이 완료되면 선택이 접힙니다.
비-editable context에서는
clipboardData
가 빈 리스트입니다. 이 경우에도 cut
이벤트는 여전히 발생합니다.
cut
이벤트는 버블링되며, 취소 가능하고, composed입니다.
이 이벤트의 처리 모델에 대한 자세한 설명은 § 8.2 잘라내기 동작을 참고하세요.
합성 cut
이벤트를 수동으로 생성하여 디스패치할 수 있지만,
문서나 시스템 클립보드의 내용에는 영향을
주지 않습니다.
5.2.4.
paste
이벤트
사용자가 붙여넣기 작업을 시작하면, 사용자 에이전트는 클립보드 이벤트 paste
를
발생시킵니다.
이 이벤트는 클립보드 데이터가 문서에 삽입되기 전에 발생합니다.
커서가 editable context에 있으면, 붙여넣기 동작은 해당 컨텍스트에서 지원하는 가장 적합한 포맷(있는 경우)으로 클립보드 데이터를 삽입합니다.
비-editable context에서는
붙여넣기 동작이 아무런 영향을 미치지 않지만,
paste
이벤트는 항상 발생합니다.
paste
이벤트는 버블링되며, 취소 가능하고, composed입니다.
이 이벤트의 처리 모델에 대한 자세한 설명은 § 8.3 붙여넣기 동작을 참고하세요.
합성 paste
이벤트를 수동으로 생성하여 디스패치할 수 있지만,
문서의 내용에는 영향을 주지 않습니다.
5.3. 다른 스크립트 및 이벤트와의 통합
5.3.1. 클립보드 수정을 허용하는 이벤트 핸들러
다음 조건 중 하나라도 true이면, 이벤트 핸들러는 클립보드에 쓸 수 있습니다:
-
이벤트를 트리거하는 동작이 사용자 에이전트의 자체 UI(예: "복사" 메뉴 항목이나 바로가기 키)에서 시작된 경우
-
이벤트를 트리거하는 동작이 팝업 표시가 허용된 스크립팅 스레드에서 시작된 경우
구현체는 해당 이벤트 타입이 사용자 의도를 반영한다고 판단될 경우, 다른 신뢰할 수 있는 이벤트 타입에도 클립보드 수정 권한을 허용할 수 있습니다. 또한 구현체가 특정 사이트나 앱에 원천 스레드와 무관하게 클립보드 수정을 신뢰하도록 구성할 수도 있습니다.
합성 cut
및 copy
이벤트는 시스템 클립보드의 데이터를 수정해서는 안 됩니다.
5.3.2. 클립보드 읽기를 허용하는 이벤트 핸들러
다음 조건 중 하나라도 true이면, 이벤트 핸들러는 시스템 클립보드에서 데이터를 읽을 수 있습니다:
-
이벤트를 트리거하는 동작이 사용자 에이전트의 자체 UI(예: "붙여넣기" 메뉴 항목이나 바로가기 키)에서 시작된 경우
-
동작을 트리거하는 스크립트가 구현체에 따라 클립보드 데이터를 읽을 권한을 부여받은 사이트에서 실행 중인 경우
-
동작을 트리거하는 이벤트가 클립보드 읽기 권한이 있는 앱에서 발생한 경우
합성 paste
이벤트는 스크립트에 실제 시스템 클립보드의 데이터 접근 권한을 주어서는 안 됩니다.
5.3.3. 서식 있는 텍스트 편집 API와의 통합
구현체가 스크립트를 통해 클립보드 명령을 실행하는 방법을 지원하는 경우, 예를 들어 document.execCommand()
메서드에 "cut", "copy",
"paste" 명령을 넘기는 방식이라면, 구현체는 반드시 해당 동작을 트리거하고, 그에 따라 관련 클립보드 이벤트를 디스패치해야 합니다.
스크립팅 API를 통해 복사, 잘라내기, 붙여넣기 동작을 트리거할 때 따라야 할 단계는 다음과 같습니다:
-
해당 동작을 동기적으로 실행합니다.
-
동작의 반환값을 API 호출의 반환값으로 사용합니다.
참고: 스크립팅 API를 통해 트리거된 복사 및 잘라내기 명령은 이벤트가 신뢰되고 사용자가 트리거한 경우 또는 구현체가 이를 허용하도록 설정된 경우에만 실제 클립보드 내용을 변경합니다. 붙여넣기 명령은 구현체가 허용하도록 설정된 경우에만 paste 이벤트를 발생시키고 클립보드 내용에 접근할 수 있습니다. 구현체가 클립보드 읽기 및 쓰기 접근을 허용하도록 구성하는 방법은 이 명세서의 범위에 포함되지 않습니다.
5.3.4. 다른 이벤트와의 상호작용
클립보드 작업이 키보드 입력에 의해 트리거된 경우, 구현체는 반드시 해당 클립보드 작업을 시작하는 이벤트를 발생시켜야 합니다. 이 이벤트는 비동기적이지만, 반드시 관련 키의 keyup 이벤트 전에 디스패치되어야 합니다.
잘라내기 및 붙여넣기 작업은 구현체가 지원하는 다른 이벤트(예: textInput, input, change, validation 이벤트, DOMCharacterDataModified, DOMNodeRemoved / DOMNodeInserted 등)를 발생시킬 수 있습니다. 이러한 이벤트는 cut/paste 이벤트 처리 후에 큐에 따라 발생합니다.
구현체는 복사 작업에 대해 textInput, input, change, validation과 같은 다른 입력 관련 이벤트를 발생시켜서는 안 됩니다.
5.3.5. 선택 영역이나 포커스를 수정하는 이벤트 리스너
이벤트 리스너가 선택 영역이나 포커스 가능한 영역을 수정한 경우, 클립보드 동작은 반드시 수정된 선택 영역에서 완료되어야 합니다.
6. 클립보드 이벤트 API
클립보드 이벤트 API를 사용하면 사용자 에이전트의 기본 잘라내기, 복사, 붙여넣기 동작을 오버라이드할 수 있습니다.
클립보드 접근은 표준 DataTransfer
메서드를 사용하여 items
를 변형합니다. 이 작업은 ClipboardEvent
의
clipboardData
속성을 통해 이루어집니다.
이 API들은 ClipboardEvent
핸들러의 컨텍스트 내에서만 클립보드 데이터에 접근할 수 있습니다.
참고: 클립보드 이벤트 핸들러 외부에서 클립보드에 접근해야 한다면 § 7 비동기 클립보드 API를 참고하세요.
참고: 클립보드 이벤트 API는 동기적이므로, 할 수 있는 작업에 제한이 있습니다. 권한 요청이나 이미지 트랜스코딩 같은 잠재적으로 블로킹되는 동작은 지원하지 않습니다. 블로킹 또는 시간이 오래 걸리는 작업을 지원하는 더 강력한 API는 § 7 비동기 클립보드 API를 참고하세요.
6.1. 복사 이벤트 오버라이드
기본 copy
이벤트 동작을 오버라이드하려면 copy
이벤트 핸들러를 추가하고, 이 핸들러에서 preventDefault()
를 호출하여 이벤트를 취소해야 합니다.
이벤트를 취소해야만 시스템 클립보드가
clipboardData
의 데이터로 업데이트됩니다. ClipboardEvent
가 취소되지 않으면, 현재 문서 선택 영역의 데이터가 복사됩니다.
// 클립보드에 복사되는 내용을 덮어쓰는 예시 document.addEventListener('copy', function(e) { // e.clipboardData는 처음에 비어 있지만, 복사하려는 데이터를 직접 설정할 수 있습니다. e.clipboardData.setData('text/plain', 'Hello, world!'); e.clipboardData.setData('text/html', '<b>Hello, world!</b>'); // 현재 문서 선택 영역이 클립보드에 기록되는 것을 막기 위해 반드시 필요합니다. e.preventDefault(); });
6.2. 잘라내기 이벤트 오버라이드
기본 cut
이벤트 동작을 오버라이드하려면 cut
이벤트 핸들러를 추가하고, 이 핸들러에서 preventDefault()
를 호출하여 이벤트를 취소해야 합니다.
이벤트를 취소해야만 시스템 클립보드가
clipboardData
의 데이터로 업데이트됩니다. ClipboardEvent
가 취소되지 않으면, 현재 문서 선택 영역의 데이터가 복사됩니다.
또한 cut
이벤트를 취소하면 문서가 갱신되지 않습니다(즉, 선택 영역이 제거되지 않습니다). 이벤트 핸들러에서 직접 선택된 텍스트를 문서에서 제거하는 작업을 해야 합니다.
// 클립보드에 복사되는 내용을 덮어쓰는 예시 document.addEventListener('cut', function(e) { // e.clipboardData는 처음에 비어 있지만, 잘라내기 작업의 일부로 클립보드에 복사할 데이터를 직접 설정할 수 있습니다. // 클립보드에 복사할 데이터를 직접 작성합니다. e.clipboardData.setData('text/plain', 'Hello, world!'); e.clipboardData.setData('text/html', '<b>Hello, world!</b>'); // 잘라내기 작업을 취소할 것이므로, 선택된 텍스트를 직접 문서에서 제거해야 합니다. deleteCurrentDocumentSelection(); // 현재 문서 선택 영역이 클립보드에 기록되는 것을 막기 위해 반드시 필요합니다. e.preventDefault(); });
6.3. 붙여넣기 이벤트 오버라이드
기본 paste
이벤트 동작을 오버라이드하려면 paste
이벤트 핸들러를 추가하고, 이 핸들러에서 preventDefault()
를 호출하여 이벤트를 취소해야 합니다.
이벤트를 취소해야만 사용자 에이전트가 시스템 클립보드의 데이터로 문서를 갱신하지 않습니다.
또한 paste
이벤트를 취소하면 문서가 갱신되지 않습니다(즉, 아무것도 문서에 붙여넣어지지 않습니다). 이벤트 핸들러에서 직접 데이터를 문서에 붙여넣는 작업을 해야 합니다.
붙여넣기 시 drag data store mode 플래그가 읽기 전용이므로, setData()
를 paste
이벤트 핸들러에서 호출해도 삽입되는 데이터나 클립보드 데이터에는 영향을 주지 않습니다.
// 클립보드에 붙여넣는 내용을 덮어쓰는 예시 document.addEventListener('paste', function(e) { // e.clipboardData에는 곧 붙여넣을 데이터가 들어 있습니다. if (e.clipboardData.types.indexOf('text/html') > -1) { var oldData = e.clipboardData.getData('text/html'); var newData = '<b>Ha Ha!</b> ' + oldData; // 붙여넣기 작업을 취소할 것이므로, 직접 데이터를 문서에 붙여넣어야 합니다. pasteClipboardData(newData); // 기본 붙여넣기 동작을 막기 위해 반드시 필요합니다. e.preventDefault(); } });
6.4. 필수 데이터 타입
구현체는 아래 데이터 타입에 대해 운영체제의 기본 클립보드 포맷 설명을 인식해야 하며, DataTransferItemList
및 ClipboardItem
에서 붙여넣기 이벤트에 올바른 설명을 제공하고, 복사/잘라내기 이벤트에 대해 OS 클립보드에 올바른 데이터 포맷을 설정해야 합니다.
6.4.1. 클립보드에서 읽기
아래 데이터 타입은 클립보드에 해당하는 네이티브 타입이 있으면 붙여넣기 이벤트에서 노출되어야 합니다:
-
text/plain
-
text/html
-
image/png
6.4.2. 클립보드에 쓰기
아래 데이터 타입은 복사 및 잘라내기 이벤트에서 DataTransfer
객체에 추가될 때, 해당 네이티브 타입 설명과 함께 클립보드에 저장되어야 합니다.
-
text/plain
-
text/html
-
image/png
경고! 신뢰되지 않은 스크립트가 클립보드에 쓸 수 있는 데이터 타입은 보안 예방 차원에서 제한되어 있습니다. 신뢰되지 않은 스크립트가 클립보드에 로컬 소프트웨어의 보안 취약점을 유발하는 데이터를 넣으려 시도할 수 있습니다.
6.5. 선택적 데이터 타입
구현체는 아래 데이터 타입에 대해 운영체제의 기본 클립보드 포맷 설명을 인식할 수 있으며, ClipboardItem
에서 붙여넣기 이벤트에 올바른 설명을 제공하고, 복사/잘라내기 이벤트에 대해 OS 클립보드에 올바른 데이터 포맷을 설정할 수 있습니다.
아래 데이터 타입은 클립보드에 해당하는 네이티브 타입이 있으면 UA에서 노출할 수 있습니다:
-
text/uri-list
-
image/svg+xml
-
커스텀 포맷 "web "("web" 뒤에 U+0020 SPACE)로 시작하는 prefix와 suffix(끝부분에서 "web " 제거 후)가 MIME 타입 파싱 체크를 통과하는 경우
6.6. 비정제 데이터 타입
이 섹션은 규범적이지 않습니다.아래 데이터 타입은 UA가 반드시 정제(sanitize)하지 않아야 합니다:
-
image/png
아래 데이터 타입은 UA가 정제하지 않을 수도 있습니다:
선택적 비정제 데이터 타입은 웹 저자가 지정한 mime type 중 UA가 반드시 정제하지 않을 수도 있는 타입입니다. 선택적 비정제 데이터 타입의 유효 목록은 아래와 같습니다:
-
text/html
선택적 비정제 데이터 타입은 프라이버시 요구로 인해 UA에서 지원하지 않을 수 있습니다.
7. 비동기 클립보드 API
7.1. Navigator 인터페이스
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute Clipboard ; };
clipboard
7.2. ClipboardItem 인터페이스
typedef Promise <(DOMString or Blob )>; [
ClipboardItemData SecureContext ,Exposed =Window ]interface {
ClipboardItem constructor (record <DOMString ,ClipboardItemData >,
items optional ClipboardItemOptions = {});
options readonly attribute PresentationStyle presentationStyle ;readonly attribute FrozenArray <DOMString >types ;Promise <Blob >getType (DOMString );
type static boolean supports (DOMString ); };
type enum {
PresentationStyle ,
"unspecified" ,
"inline" };
"attachment" dictionary {
ClipboardItemOptions PresentationStyle = "unspecified"; };
presentationStyle
clipboardItem = new ClipboardItem([items, options])
-
새로운
ClipboardItem
객체를 생성합니다. items는 표현 목록을 나타내며, 각 표현은 mime type과Promise
(해당 mime type에 맞는Blob
또는DOMString
)를 가집니다. options는ClipboardItemOptions
를 채우는 데 사용할 수 있습니다. 아래 예시 참고.const format1= 'text/plain' ; const promise_text_blob= Promise. resolve( new Blob([ 'hello' ], { type: format1})); const clipboardItemInput= new ClipboardItem( {[ format1] : promise_text_blob}, { presentationStyle: "unspecified" }); clipboardItem.getType(type)
- mime type type에 해당하는
Promise
(그Blob
)를 반환합니다. clipboardItem.types
- clipboard item 객체에 포함된 mime type 목록을 반환합니다.
ClipboardItem
.supports(type)- type이 필수 데이터 타입 또는 선택적 데이터 타입에 있으면 true, 아니면 false를 반환합니다.
예를 들어, 사용자가 네이티브 앱의 스프레드시트에서 셀 범위를 복사하면 하나의 clipboard item이 생성됩니다. 사용자가 데스크톱에서 여러 파일을 복사하면, 그 파일 목록은 여러 clipboard item으로 표현됩니다.
일부 플랫폼은 클립보드에 한 번에 둘 이상의 clipboard item을 허용할 수 있고, 다른 플랫폼은 이전 clipboard item을 새 항목으로 대체합니다. clipboard item은 표현 목록을 가지며, 각 표현에는 mime type (MIME 타입), isCustom 플래그(초기값 false, 해당 representation이 웹 커스텀 포맷인지 여부), data (ClipboardItemData
)가
있습니다.
웹 커스텀 포맷은 isCustom이
true로 설정된 것입니다.
예시에서 사용자가 스프레드시트에서 셀 범위를 복사할 때, 이미지(image/png), HTML 테이블(text/html), 평문(text/plain), 웹 커스텀 포맷(web text/csv) 등 다양한 형태로 표현될 수 있습니다.
각 MIME 타입은 동일한 clipboard item의 다른 표현을 설명하며, 다양한 fidelity 수준에서 붙여넣기 대상 애플리케이션이 더 쉽게 활용할 수 있게 합니다.셀 범위를 이미지로 제공하면 사용자가 사진 편집 앱에 붙여넣을 수 있고, text/plain 포맷은 텍스트 편집 앱에서 사용할 수 있습니다.
clipboard item은 프레젠테이션 스타일 (PresentationStyle
)을
가지고, 이는 붙여넣기하는 앱이 clipboard
item의 적절한 표현을 붙여넣기
위치에 인라인으로 삽입해야 할지, 첨부파일로 처리해야 할지 구분하는 데 도움을 줍니다.
단일 clipboard item만 지원하는 웹
앱은 첫 번째 clipboard item을
사용해야 합니다.
write()
는 마지막 clipboard item을
선택합니다.
ClipboardItem
객체에는 clipboard item이 연결되어 있으며, 이는 clipboard item입니다.
ClipboardItem
객체에는 types array가 연결되어 있으며, 이는 FrozenArray
<DOMString
>
ClipboardItem
객체 생성을 위해 clipboard
item clipboardItem과 Realm realm이 주어지면, 다음 단계를 실행합니다:
-
clipboardItemObject를 new
ClipboardItem
로 realm과 함께 생성합니다. -
clipboardItemObject의 clipboard item을 clipboardItem으로 설정합니다.
new ClipboardItem(items, options)
생성자 단계:
-
items가 비어 있으면
TypeError
를 던진다. -
options가 비어 있으면 options["presentationStyle"] = "unspecified"로 설정한다.
-
this의 clipboard item을 새로운 clipboard item으로 설정한다.
-
this의 clipboard item의 presentation style을 options["
presentationStyle
"]로 설정한다. -
types를
DOMString
의 리스트로 한다. -
items의 각 (key, value)에 대해:
-
representation을 새로운 representation으로 한다.
-
isCustom을 false로 한다.
-
key가 "web " prefix로 시작하면,
-
"web " prefix를 제거하고 남은 문자열을 key에 할당한다.
-
isCustom을 true로 설정한다.
-
-
representation의 isCustom 플래그를 isCustom으로 설정한다.
-
mimeType을 MIME 타입 파싱 결과(key 기준)로 한다.
-
mimeType이 실패이면
TypeError
를 던진다. -
this의 clipboard item의 list of representations이 representation 중 MIME type이 mimeType이고 [representation/isCustom]이 isCustom인 항목을 포함하면
TypeError
를 던진다.
위 단계는 사용자 에이전트가 잘 아는 mime-type과 저자가 커스텀 타입으로 다루길 원하는 타입 간의 충돌을 방지합니다. 예를 들어 저자의 items 목록에 "text/html" 과 "web text/html" 두 representation이 들어가는 것도 가능합니다.
-
representation의 MIME type을 mimeType으로 설정한다.
-
representation의 data를 value로 설정한다.
-
representation을 this의 clipboard item의 list of representations에 추가한다.
-
mimeTypeString을 MIME 타입 직렬화(mimeType 기준) 결과로 한다.
-
isCustom이 true이면 mimeTypeString 앞에 "web "을 붙인다.
-
mimeTypeString을 types에 추가한다.
-
-
this의 types array를 create a frozen array(types 기준) 결과로 설정한다.
7.2.1. presentationStyle
presentationStyle
getter의 단계는 this의
clipboard item의 presentation style을 반환하는 것이다.
7.2.2. types
types
getter의 단계는 this의
types
array를 반환하는 것이다.
7.2.3. getType(type)
이 메서드는 아래 단계를 실행해야 한다:
-
realm을 this의 relevant realm으로 한다.
-
isCustom을 false로 한다.
-
type이 "web " prefix로 시작하면:
-
"web " prefix를 제거하고 남은 문자열을 type에 할당한다.
-
isCustom을 true로 설정한다.
-
-
mimeType을 MIME 타입 파싱(type 기준) 결과로 한다.
-
mimeType이 실패이면
TypeError
를 던진다. -
itemTypeList를 this의 clipboard item의 list of representations로 한다.
-
p를 새로운 promise(realm 기준)로 한다.
-
itemTypeList의 각 representation에 대해:
-
representation의 MIME type이 mimeType이고, representation의 isCustom이 isCustom이면:
-
representationDataPromise를 representation의 data로 한다.
-
representationDataPromise가 settle되면 반응:
-
representationDataPromise가 값 v로 fulfilled되면:
-
representationDataPromise가 reject되면:
-
p를 reject한다. 값은
"NotFoundError"
DOMException
(realm 기준).
-
-
-
p를 반환한다.
-
-
-
p를 reject한다. 값은
"NotFoundError"
DOMException
(realm 기준). -
p를 반환한다.
7.2.4. supports(type)
이 메서드는 아래 단계를 실행해야 한다:
-
type이 필수 데이터 타입 또는 선택적 데이터 타입에 포함되어 있으면 true를 반환한다.
-
그렇지 않으면 false를 반환한다.
7.3. Clipboard 인터페이스
typedef sequence <ClipboardItem >; [
ClipboardItems SecureContext ,Exposed =Window ]interface :
Clipboard EventTarget {Promise <ClipboardItems >read (optional ClipboardUnsanitizedFormats = {});
formats Promise <DOMString >readText ();Promise <undefined >write (ClipboardItems );
data Promise <undefined >writeText (DOMString ); };
data dictionary {
ClipboardUnsanitizedFormats sequence <DOMString >; };
unsanitized
Clipboard
인터페이스의 일부 메서드는 여러 ClipboardItem
객체를 인자로 받거나 반환합니다. 하지만 모든 플랫폼이 둘 이상의 클립보드 아이템을 지원하는 것은 아닙니다. 이러한 플랫폼에서는 아래 알고리즘에서 ClipboardItem
객체 중 첫 번째 이후의 객체는 write()
호출 시 무시되고, read()
와 readText()
는 OS에서 클립보드 아이템 하나만 가져옵니다.
클립보드 아이템들 객체는 sequence 타입의 클립보드 아이템 목록입니다.
웹 저자는 data라는 ClipboardItem
배열을 생성하여 시스템 클립보드에
write(data)
메서드로 콘텐츠를 쓸 수 있습니다. read()
는 클립보드 아이템들 객체를 나타내는 Promise
를 반환하며, 시스템 클립보드 데이터의 내용을 나타냅니다.
unsanitized
는 저자가 선택적 비정제 데이터 타입으로 다루고자 하는 mime type에 해당하는 DOMString
시퀀스입니다.
unsanitized
옵션은 UA에서 지원되지 않을 수 있습니다. 웹 저자는 unsanitized
에 명시된 MIME 타입의 콘텐츠가 실제로 정제되지 않을 것이라 가정해서는 안 됩니다. 프라이버시 모드 등에서 이 옵션이 허용되지 않을 수 있습니다.
클립보드 태스크 소스 는 시스템 클립보드 데이터 읽기 또는 쓰기에 대한 응답으로 트리거됩니다.
7.3.1. read(formats)
read(formats)
메서드는 아래 단계를 실행해야 합니다:
-
realm을 this의 relevant realm으로 한다.
-
p를 새로운 promise(realm 기준)로 한다.
-
formats가 비어 있지 않으면:
-
formats["
unsanitized
"]의 각 format에 대해:-
format이 선택적 비정제 데이터 타입에 포함되지 않으면 p를 reject한다. 값은 format과
"NotAllowedError"
DOMException
(realm 기준).
-
-
-
아래 단계를 병렬로 수행한다:
-
r을 클립보드 읽기 권한 확인 알고리즘 결과로 한다.
-
r이 false이면:
-
글로벌 태스크를 큐에 추가한다. 대상은 permission task source, realm의 global object를 주고, p를 reject한다. 값은
"NotAllowedError"
DOMException
(realm 기준). -
이 단계들을 중단한다.
-
-
data를 시스템 클립보드 데이터의 복사본으로 한다.
-
data의 각 systemClipboardItem에 대해:
-
item을 새로운 클립보드 아이템으로 한다.
-
systemClipboardItem의 각 systemClipboardRepresentation에 대해:
-
mimeType을 운영체제별 포맷에서 알려진 MIME 타입 알고리즘(systemClipboardRepresentation의 name 기준) 결과로 한다.
-
mimeType이 null이면 루프를 계속한다.
-
representation을 새로운 representation으로 한다.
-
representation의 MIME type을 mimeType으로 설정한다.
-
isUnsanitized를 false로 한다.
-
formats가 비어 있지 않으면:
-
formats["
unsanitized
"]의 각 format에 대해:-
format이 MIME type과 같으면 isUnsanitized를 true로 한다.
-
-
-
representation의 data를 systemClipboardRepresentation의 data로 resolve한다.
getType 호출 이후 시스템 클립보드에서 데이터를 비동기적으로 읽을 수 있어야 하지만, 이 단계는 read 시점에 데이터가 제공됨을 의미합니다.
-
UA는 representation의 data를 정제할 수 있습니다. 단, representation의 MIME type이 "image/png" 본질이면 메타데이터 보존을 위해 정제하지 않아야 하며, 또는 아래 조건을 만족하면 정제하지 않을 수 있습니다:
-
representation의 MIME type이 비정제 데이터 타입 목록에 포함된 경우
-
isUnsanitized가 true인 경우
-
-
representation을 item의 list of representations에 추가한다.
-
isUnsanitized를 false로 한다.
-
-
item의 list of representations 길이가 0보다 크면 item을 items에 추가한다.
-
-
items 크기가 0보다 크면:
-
firstItem을 items[0]으로 한다.
-
웹 커스텀 포맷 읽기 알고리즘을 firstItem에 대해 실행한다.
-
-
그렇지 않으면:
-
customItem을 새로운 클립보드 아이템으로 한다.
-
웹 커스텀 포맷 읽기 알고리즘을 customItem에 대해 실행한다.
-
customItem의 list of representations 길이가 0보다 크면 customItem을 items에 추가한다.
-
-
글로벌 태스크를 큐에 추가한다. 대상은 클립보드 태스크 소스, realm의 global object를 주고, 아래 단계를 수행한다:
-
clipboardItems를 sequence<
ClipboardItem
>로 한다. -
items의 각 클립보드 아이템 underlyingItem에 대해:
-
clipboardItem을 ClipboardItem 객체 생성 알고리즘 결과(underlyingItem, realm 기준)로 한다.
-
clipboardItem을 clipboardItems에 추가한다.
-
-
p를 clipboardItems로 resolve한다.
-
-
-
p를 반환한다.
const items= await navigator. clipboard. read(); const textBlob= await items[ 0 ]. getType( "text/plain" ); const text= await ( new Response( textBlob)). text();
7.3.2. readText()
readText()
메서드는 다음 단계를 실행해야 한다:
-
realm을 this의 relevant realm으로 한다.
-
p를 새로운 promise(realm 기준)로 한다.
-
아래 단계를 병렬로 수행한다:
-
r을 클립보드 읽기 권한 확인 알고리즘 결과로 한다.
-
r이 false이면:
-
글로벌 태스크를 큐에 추가한다. 대상은 permission task source, realm의 global object를 주고, p를 reject한다. 값은
"NotAllowedError"
DOMException
(realm 기준). -
이 단계들을 중단한다.
-
-
data를 시스템 클립보드 데이터의 복사본으로 한다.
일부 OS는 여러 클립보드를 포함(Linux, "primary", "secondary", "selection" 등)합니다. 어느 클립보드에서 데이터를 읽는지 정의해야 합니다.
-
글로벌 태스크를 큐에 추가한다. 대상은 클립보드 태스크 소스, realm의 global object를 주고, 아래 단계를 수행한다:
-
data의 각 systemClipboardItem에 대해:
-
systemClipboardItem의 각 systemClipboardRepresentation에 대해:
-
mimeType을 운영체제별 포맷에서 알려진 MIME 타입 알고리즘(systemClipboardRepresentation의 name 기준) 결과로 한다.
-
mimeType이 null이면 루프를 계속한다.
-
representation을 새로운 representation으로 한다.
-
representation의 MIME type의 essence가 "text/plain"이면:
-
representation의 MIME type을 mimeType으로 설정한다.
-
representationDataPromise를 representation의 data로 한다.
-
representationDataPromise가 settle되면 반응:
-
representationDataPromise가 값 v로 fulfilled되면:
-
representationDataPromise가 reject되면:
-
p를 reject한다. 값은
"NotFoundError"
DOMException
(realm 기준). -
p를 반환한다.
-
-
-
-
-
-
p를 reject한다. 값은
"NotFoundError"
DOMException
(realm 기준). -
p를 반환한다.
-
-
navigator. clipboard. readText(). then( function ( data) { console. log( "Your string: " , data); });
7.3.3. write(data)
write(data)
메서드는 다음 단계를 실행해야 한다:
-
realm을 this의 relevant realm으로 한다.
-
p를 새로운 promise(realm 기준)로 한다.
-
아래 단계를 병렬로 수행한다:
-
r을 클립보드 쓰기 권한 확인 알고리즘 결과로 한다.
clipboard-write는 https://github.com/w3c/clipboard-apis/pull/164에서 제거되었습니다.
-
r이 false이면:
-
글로벌 태스크를 큐에 추가한다. 대상은 permission task source, realm의 global object를 주고, p를 reject한다. 값은
"NotAllowedError"
DOMException
(realm 기준). -
이 단계들을 중단한다.
-
-
글로벌 태스크를 큐에 추가한다. 대상은 클립보드 태스크 소스, realm의 global object를 주고, 아래 단계를 수행한다:
-
dataList를 sequence<
ClipboardItem
>로 한다. -
data의 size가 1보다 크고, 현재 OS가 시스템 클립보드에 여러 네이티브 클립보드 아이템을 지원하지 않으면 data[0]을 dataList에 추가하고, 그렇지 않으면 dataList를 data로 설정한다.
data가 여러 아이템을 포함하고 운영체제가 여러 네이티브 클립보드 아이템을 지원할 경우, 현재 알고리즘은 아이템을 순차적으로 시스템 클립보드에 쓰지만, 집합적으로 쓰는 것이 아닙니다.
-
dataList의 각 clipboardItem에 대해:
-
clipboardItem의 clipboard item의 list of representations의 각 representation에 대해:
-
representationDataPromise를 representation의 data로 한다.
-
representationDataPromise가 settle되면 반응:
-
representationDataPromise가 값 v로 fulfilled되면:
-
representationDataPromise가 reject되면:
-
p를 reject한다. 값은
"NotAllowedError"
DOMException
(realm 기준). -
이 단계들을 중단한다.
-
-
-
-
itemList의 각 blob에 대해:
-
type을 blob의
type
으로 한다. -
type이 필수 데이터 타입 또는 선택적 데이터 타입 목록에 없으면 p를 reject한다. 값은
"NotAllowedError"
DOMException
(realm 기준)이며, 이 단계들을 중단한다. -
cleanItem을 blob의 선택적으로 정제된 복사본으로 한다.
-
정제 시도가 있었으나 성공적으로 완료되지 않았다면 아래 단계를 따른다:
-
p를 reject한다. 값은
"NotAllowedError"
DOMException (realm 기준). -
이 단계들을 중단한다.
-
-
cleanItem을 cleanItemList에 추가한다.
-
-
option을 clipboardItem의 presentation style으로 한다.
-
클립보드에 blob과 option 쓰기를 cleanItemList와 option을 주고 실행한다.
-
-
p를 resolve한다.
-
-
p를 반환한다.
var data= [ new ClipboardItem({ "text/plain" : Promise. resolve( new Blob([ "Text data" ], { type: "text/plain" })) })]; navigator. clipboard. write( data). then( function () { console. log( "Copied to clipboard successfully!" ); }, function () { console. error( "Unable to write to clipboard. :-(" ); });
7.3.4. writeText(data)
writeText(data)
메서드는 다음 단계를 실행해야 한다:
-
realm을 this의 relevant realm으로 한다.
-
p를 새로운 promise(realm 기준)로 한다.
-
아래 단계를 병렬로 수행한다:
-
r을 클립보드 쓰기 권한 확인 알고리즘 결과로 한다.
clipboard-write는 https://github.com/w3c/clipboard-apis/pull/164에서 제거되었습니다.
-
r이 false이면:
-
글로벌 태스크를 큐에 추가한다. 대상은 permission task source, realm의 global object를 주고, p를 reject한다. 값은
"NotAllowedError"
DOMException (realm 기준). -
이 단계들을 중단한다.
-
-
글로벌 태스크를 큐에 추가한다. 대상은 클립보드 태스크 소스, realm의 global object를 주고, 아래 단계를 수행한다:
-
textBlob을 새로운
Blob
으로 생성한다.type
속성은 "text/plain;charset=utf-8
"이고, 내부 바이트 시퀀스는 UTF-8 인코딩(data 기준) 결과로 한다.참고: Windows에서는 data에서 `\n` 문자를 `\r\n`으로 대체한 후 textBlob을 생성한다.
-
textBlob을 itemList에 추가한다.
-
option을 "unspecified"로 설정한다.
-
클립보드에 blob과 option 쓰기를 itemList와 option을 주고 실행한다.
-
p를 resolve한다.
-
-
p를 반환한다.
await navigator. clipboard. writeText( "Howdy, partner!" );
8. 클립보드 동작
이 섹션은 클립보드 동작과 이벤트 디스패치 처리 모델을 정의합니다.
각 클립보드 동작은 스크립트-트리거됨 및 스크립트-클립보드-접근-허용이라는 두 개의 플래그를 가집니다.
스크립트-트리거됨
플래그는 동작이 스크립트로 인해 실행될 때(예: document.execCommand()
호출) 설정됩니다.
클립보드와 상호작용하는 향후 스크립팅 API도 이 플래그를 사용해야 하며,
스크립트-트리거됨 플래그가 올바르게
설정되어야 합니다.
스크립트-클립보드-접근-허용 플래그는 다음과 같이 설정됩니다:
-
동작이 복사 또는 잘라내기이고, 스크립트 스레드가 클립보드 수정 허용이면,
-
동작의 스크립트-클립보드-접근-허용 플래그를 설정한다
-
-
동작이 붙여넣기이고, 스크립트 스레드가 클립보드 읽기 허용이면,
-
동작의 스크립트-클립보드-접근-허용 플래그를 설정한다.
-
8.1. 복사 동작
복사 동작은 다음 단계로 구성됩니다:
-
스크립트-트리거됨 플래그가 설정되어 있으면,
-
스크립트-클립보드-접근-허용 플래그가 설정되어 있지 않으면,
-
복사 동작에서 false를 반환하고, 알고리즘을 종료한다
-
-
-
이 이벤트가 취소되지 않았으면,
-
선택된 콘텐츠(있는 경우)를 클립보드에 복사한다. 구현체는 웹 페이지에서 선택된 콘텐츠가 있을 때 text/html 및 text/plain 클립보드 포맷을 대체로 생성해야 한다.
-
-
그렇지 않고 이벤트가 취소되었다면,
-
클립보드에 콘텐츠 쓰기 알고리즘을 호출한다.
DataTransferItemList
리스트 items, clear-was-called 플래그, types-to-clear 리스트를 전달한다.
-
-
복사 동작에서 true를 반환한다
8.2. 잘라내기 동작
잘라내기 동작은 다음 단계로 구성됩니다:
-
스크립트-트리거됨 플래그가 설정되어 있으면,
-
스크립트-클립보드-접근-허용 플래그가 설정되어 있지 않으면,
-
잘라내기 동작에서 false를 반환하고, 알고리즘을 종료한다
-
-
-
이 이벤트가 취소되지 않았으면,
-
editable context에서 잘라내기가 허용되고 선택 영역이 존재한다면,
-
선택된 콘텐츠(있는 경우)를 클립보드에 복사한다. 구현체는 웹 페이지에서 선택된 콘텐츠가 있을 때 text/html 및 text/plain 클립보드 포맷을 대체로 생성해야 한다.
-
선택 영역의 콘텐츠를 문서에서 제거하고, 선택 영역을 접는다.
-
수정으로 인해 발생해야 하는 이벤트들을 큐에 추가한다. 자세한 내용은 § 5.3 다른 스크립트 및 이벤트와의 통합을 참고한다.
-
-
그렇지 않고 선택이 없거나 컨텍스트가 편집 가능하지 않으면,
-
false를 반환한다
-
-
-
그렇지 않고 이벤트가 취소되었다면,
-
클립보드에 콘텐츠 쓰기 알고리즘을 호출한다.
DataTransferItemList
리스트 items, clear-was-called 플래그, types-to-clear 리스트를 전달한다.
-
-
잘라내기 동작에서 true를 반환한다
8.3. 붙여넣기 동작
붙여넣기 동작에서 스크립트-클립보드-접근-허용 플래그는 어떤 사이트나 앱이 클립보드에서 읽을 수 있는지 결정하기 위한 구현체별 권한 메커니즘에 따라 달라집니다. 붙여넣기 동작이 스크립트로 트리거될 때, 구현체는 사용자의 허락 없이 클립보드 내용을 노출해서는 안 됩니다. 권한이 미리 부여되지 않은 경우, 권한 프롬프트에는 스크립트 스레드에 연결된 문서의 호스트명이 반드시 포함되어야 합니다.
붙여넣기 동작은 다음 단계로 구성됩니다:
-
스크립트-트리거됨 플래그가 설정되어 있으면,
-
스크립트-클립보드-접근-허용 플래그가 설정되어 있지 않으면,
-
붙여넣기 동작에서 false를 반환하고, 알고리즘을 종료한다
-
-
-
이 이벤트가 취소되지 않았으면,
-
editable context에서 붙여넣기가 허용된 선택 영역이나 커서가 존재하면,
-
클립보드에서 찾은 가장 적합한 콘텐츠(있는 경우)를 해당 컨텍스트에 삽입한다.
-
수정으로 인해 발생해야 하는 이벤트들을 큐에 추가한다. 자세한 내용은 § 5.3 다른 스크립트 및 이벤트와의 통합을 참고한다.
-
-
그렇지 않으면
-
false를 반환한다
-
-
-
그렇지 않고 이벤트가 취소되었다면
-
false를 반환한다
-
-
동작에서 true를 반환한다
9. Permissions API 연동
[permissions] API는 웹사이트가 강력한 기능(예: 클립보드)에 접근할 수 있는 통합 방식을 제공합니다. 웹사이트는 사용자의 권한을 요청하고, 어떤 권한을 가지고 있는지 조회할 수 있습니다.
클립보드의 경우, 하나의 권한이 정의되어 있습니다: "clipboard-write"
참고: 클립보드 권한은 현재 비동기 클립보드 API에만 적용됩니다. 향후 이 명세의 버전에서는 다른 클립보드 상호작용에도 이 권한이 적용될 수 있습니다.
다음과 같이 클립보드 권한은 강력한 기능이며, 권한 관련 알고리즘과 타입은 다음과 같이 정의됩니다:
- permission descriptor type
-
dictionary
:ClipboardPermissionDescriptor PermissionDescriptor {boolean
=allowWithoutGesture false ; };
클립보드 권한은 4가지가 있습니다:
-
{ name: "clipboard-write", allowWithoutGesture: false }
-
{ name: "clipboard-write", allowWithoutGesture: true }
관계는 다음과 같습니다:
-
{ "clipboard-write" + true }
는{ "clipboard-write" + false }
보다 더 강력합니다.
사용자 에이전트는 반드시 명세서에 설명된 대로 ClipboardPermissionDescriptor
를 지원해야 하지만,
기본 설정과 사용자에게 어떻게 노출하는지는 완전히 제어할 수 있습니다.
-
{ "clipboard-write" + false }
는 사용자 제어용으로 노출됨 -
{ "clipboard-write" + true }
는 항상거부됨
9.1. 클립보드 읽기 권한
9.1.1. 클립보드 읽기 권한 확인
-
hasGesture를 relevant global object가 this에서 일시적 활성화(transient activation)를 가지고 있으면 true, 그렇지 않으면 false로 한다.
-
hasGesture이면,
-
현재 스크립트가 사용자 에이전트나 OS가 생성한 "Paste" 요소와의 사용자 상호작용 결과로 실행되고 있다면 true를 반환한다.
-
-
false를 반환한다.
9.2. 클립보드 쓰기 권한
9.2.1. 클립보드 쓰기 권한 확인
-
writeWithoutGesture를 permission state({ name: "clipboard-write", allowWithoutGesture: true } 권한 기준)로 한다.
-
writeWithoutGesture가
granted
이면 true를 반환한다. -
hasGesture를 relevant global object가 this에서 일시적 활성화(transient activation)를 가지고 있으면 true, 그렇지 않으면 false로 한다.
-
hasGesture이면,
-
현재 스크립트가 사용자 에이전트나 OS가 생성한 "cut" 또는 "copy" 요소와의 사용자 상호작용 결과로 실행되고 있다면 systemCopy를 true로 한다.
-
systemCopy가 true이면 true를 반환한다.
-
request permission to use({ name: "clipboard-write", allowWithoutGesture: false } 권한 기준) 결과를 반환한다.
참고: 사용자 에이전트는 더 강력한 권한을 요청하여 이 권한을 암묵적으로 업데이트할 수도 있습니다.
-
-
request permission to use({ name: "clipboard-write", allowWithoutGesture: true } 권한 기준) 결과를 반환한다.
10. 보안 고려사항
저자가 사용자가 복사하는 내용을 변경하거나, 선택된 적이 없는 내용을 자동으로 복사하거나, 정보 붙여넣기를 제한 없이 호출할 수 있도록 하면 다양한 보안 문제가 발생할 수 있습니다.
예시 시나리오:
-
사용자가 링크를 선택하고 복사했으나, 실제로 다른 링크가 클립보드에 복사됨. 이는 붙여넣기 시 예상치 못한 결과에서 피싱 공격 시도까지 이어질 수 있습니다.
-
(Self-XSS) 셸 명령어나 실행 가능한 스크립트가 클립보드에 삽입되어 사용자가 붙여넣은 후 실행할 수 있습니다.
-
OS의 이미지 처리 코드의 버그를 악용하도록 특별히 제작된 이미지를 클립보드에 쓸 수 있습니다.
10.1. HTML 및 멀티파트 데이터 붙여넣기
이 섹션은 규범적이지 않습니다.
서식 있는 데이터나 멀티파트 데이터를 붙여넣는 데에는 특정 보안 위험이 있습니다.
-
사용자가 보이지 않는 데이터를 인지하지 못한 채 붙여넣을 수 있습니다. 예를 들어, 마크업에 <input type="hidden"> 태그나 HTML 주석이 포함된 경우. 이러한 숨겨진 데이터에는 민감한 정보가 포함될 수 있습니다.
-
사용자가 신뢰하는 페이지에 악성 JavaScript를 붙여넣을 수 있습니다.
-
구현체가 사용자가 공개를 의도하지 않은 로컬 파일에 대한 스크립트 접근을 허용할 수 있습니다.
어떤 정책을 사용할지 결정하기 위해 고려하는 요소는 다음과 같습니다:
-
붙여넣는 데이터의 출처
-
참조된 이미지 등 부분 데이터의 출처
-
실행 중인 스크립트의 출처
각 시나리오와 적용 가능한 보안 정책 개요:
데이터 출처 | 스크립트 출처 | 규칙 |
---|---|---|
온라인 소스에서 기원 | 데이터와 동일 | HTML을 정제하지 않음. 로컬 파일 접근 불가. |
다른 출처 | 콘텐츠 선택적 정제. 로컬 파일 접근 불가. | |
로컬 애플리케이션에서 기원 | 상관 없음 | HTML을 정제하지 않음. 로컬 파일 접근 허용 |
일부 구현체는 서식 있는 텍스트 붙여넣기 관련 위험을 완화하기 위해, 기본적으로 SCRIPT 요소나 javascript: 링크 등 잠재적으로 악성인 콘텐츠를 제거하지만, paste 이벤트 핸들러에서는 원본, 비정제 데이터를 처리할 수 있도록 허용합니다.
10.2. 일반 보안 정책
구현체는 온라인에서 참조된 리소스를 다운로드하거나, 그 내용을 files
리스트나 DataTransferItemList
에 노출해서는 안 됩니다.
클립보드 데이터가 로컬 애플리케이션 출신이 아니라면, 구현체는 참조된 로컬 파일에 대한 접근을 허용해서는 안 됩니다. 예를 들면, 데이터에 <img src="file://localhost/example.jpg">가 포함되어 있고 데이터 출처가 온라인 리소스라면, 구현체는 clipboardData.items 리스트에 example.jpg 항목을 추가해서는 안 됩니다.
10.3. 이미지 트랜스코딩
악성 이미지 데이터가 클립보드에 저장되는 것을 방지하기 위해, 이미지 데이터를 안전한 버전으로 트랜스코딩할 수 있습니다. 이를 통해 웹사이트가 다른 애플리케이션의 보안 취약점을 악용하는 것을 막을 수 있습니다.
구현체는 클립보드에서 읽는 이미지를 트랜스코딩해서는 안 됩니다. 트랜스코딩하면 이미지의 물리적 해상도와 같은 중요한 메타데이터가 손실될 수 있습니다. 이는 <input type=file> 등 웹사이트에서 이미지를 공유하는 다른 방식과도 일치합니다.
10.4. 방해 고려사항
스크립트는 DataTransfer
API를 사용하여 복사 및 잘라내기 이벤트에서 시스템 클립보드의 데이터를 변경함으로써 사용자를 혼란스럽게 하거나 괴롭힐 수 있습니다. 이 명세서는 이런 방해를 방지하려고 하지 않지만, 구현체는
추가 제한을 둘 수 있습니다.
구현체는 스크립트가 클립보드에 과도한 양의 데이터를 저장하려는 시도를 우아하게 처리해야 합니다.
11. 프라이버시 고려사항
이 API들은 사용자의 클립보드 데이터에 접근할 수 있으므로, 이름, 주소, 비밀번호 등 개인정보(PII)가 클립보드에 저장될 수 있어 심각한 프라이버시 문제가 있습니다.
일반적으로, 사용자 에이전트는 신뢰되지 않은 스크립트가 이러한 API를 통해 사용자의 클립보드 데이터를 무제한으로 접근하지 못하도록 반드시 보장해야 합니다.
11.1. 프라이버시와 클립보드 이벤트 API
클립보드 이벤트 API는 클립보드 이벤트 핸들러 컨텍스트에서 실행되는 스크립트가 시스템 클립보드의 복사본에 접근하고, 클립보드에 쓰이는 데이터를 수정할 수 있도록 허용합니다.
사용자 에이전트는 클립보드 이벤트 API를 통해 접근하는 데이터 보안을 위해 다음 요구사항을 인지해야 합니다:
-
DataTransfer
인터페이스를 구현하여 클립보드 데이터를 반환하는 객체는 해당 ClipboardEvent 이벤트 핸들러 외부에서는 노출되어서는 안 됩니다. -
스크립트가 ClipboardEvent 이벤트 핸들러 외부에서 사용하기 위해 DataTransfer 인터페이스를 구현한 객체의 참조를 저장한 경우, 그 모든 메서드는 예상된 컨텍스트 외부에서는 동작하지 않아야(no-op) 합니다.
-
구현체는 스크립트가 합성 클립보드 이벤트를 생성해서 실제 클립보드 데이터에 접근하는 것을 허용해서는 안 됩니다 (사용자가 직접 설정한 경우는 예외).
클립보드 이벤트 API는 클립보드 권한에 적용되지 않지만, 사용자 에이전트는 사용자가 이 API를 비활성화하거나 특정 사이트에만 접근을 허용하도록 설정할 수 있는 방법을 제공할 수 있습니다.
11.2. 프라이버시와 비동기 클립보드 API
비동기 클립보드 API는 강력한 기능입니다. 이벤트 핸들러 컨텍스트에 국한되지 않고, 모든 스크립트가 클립보드 데이터에 접근할 수 있으며, 사용자 제스처 없이도 데이터에 접근할 수 있습니다.
남용을 막기 위해, 이 API는 문서가 포커스를 가지고 있을 때만 사용할 수 있어야 합니다.
11.2.1. 프라이버시와 클립보드 권한
클립보드 권한은 이 API 접근을 제한하지만, 사용자 에이전트는 권한의 기본값과 어떤 권한 설정을 사용자가 조정할 수 있을지 선택할 수 있습니다. 예를 들어, 사용자 에이전트는 사용자 제스처가 있는 경우에만 비동기 클립보드 API 접근을 허용하고, 제스처 없는 스크립트 요청은 항상 거부할 수 있습니다.
사용자 에이전트는 사용자가 권한을 부여한 후 권한이 자동으로 만료되도록 선택할 수 있습니다. 예를 들어, 권한 만료 조건은 다음과 같습니다:
-
권한 부여 후 일정 시간이 지나면
-
사용자가 사이트를 마지막으로 방문한 후 일정 시간이 지나면
-
사용자가 페이지를 벗어나면
11.3. 기타 프라이버시 우려
사용자 에이전트가 document.execCommand("paste")
를 통해 클립보드 데이터를 읽을 수 있게 허용하는 경우, 반드시 사용자가 명시적으로 접근을 허용했는지
확인해야 합니다.
12. 감사의 글
이 섹션은 규범적이지 않습니다.
에디터들은 이전 에디터들의 기여를 인정합니다. 그들은 이 명세가 지금의 형태에 이르기까지 다양한 회의와 메일링 리스트 논의를 통해 발전시켜 주었습니다.
-
Hallvord R. M. Steen
에디터들은 또한 Microsoft의 Data Transfer 기능 문서 [MICROSOFT-CLIP-OP]와 [HTML5] 명세의 이전 초안에 지적 빚을 졌음을 인정합니다. 또한 Paul Libbrecht의 "safe copy and paste" 초안에도 감사드립니다 (이 초안은 현재 웹에서 제공되지 않습니다).
마지막으로 다음 분들의 기여에 감사드립니다:
Adam Barth, Shawn Carnell, Daniel Cheng, Daniel Dardailler, Domenic Denicola, Al Gilman, James Graham, James Greene, Ian Hickson, Darwin Huang, Lachlan Hunt, Philip Jägenstedt, Anne van Kesteren, Marijn Kruisselbrink, Aaron Leventhal, Jim Ley, Paul Libbrecht, "Martijn", Glenn Maynard, Chris Mills, ms2ger, Ryosuke Niwa, Robert O’Callahan, Dave Poehlman, "ROBO Design", Janina Sajka, Rich Schwerdtfeger, Jonas Sicking, Maciej Stachowiak, Mihai Sucan, Dmitry Titov, Ojan Vafai, Tarquin Wilton-Jones, Tom Wlodkowski, Bo Cupp, mbrodesser 그리고 Boris Zbarsky.
부록 A: 알고리즘
클립보드에 콘텐츠 쓰기
- 입력
-
items :
DataTransferItemList
클립보드에 쓸 아이템 리스트clear-was-called : boolean 값
types-to-clear : 리스트
- 출력
-
없음
-
items 리스트가 비어 있지 않으면,
-
클립보드를 비운다
-
리스트의 각 파트에 대해,
-
데이터 타입이 text/plain이면,
-
OS 및 로캘 관례에 따라 인코딩이 올바른지 확인
-
플랫폼 관례에 따라 줄바꿈을 정규화
-
OS 클립보드 포맷 설명에 맞게 텍스트를 클립보드에 넣는다
-
-
그 외, 데이터가 필수 데이터 타입 리스트에 포함된 타입이면,
-
OS 클립보드 포맷 설명에 맞게 파트를 클립보드에 넣는다
-
-
그 외의 경우
-
-
-
그 외, items 리스트가 비어 있다면, 아래와 같이 클립보드를 비울지 결정한다:
클립보드에 blob과 option 쓰기
- 입력
-
presentationStyle : 클립보드 아이템의 presentation style
- 출력
-
없음
-
items의 각 item에 대해:
-
formatString을 OS별 알려진 포맷 알고리즘(item의
type
기준) 결과로 한다. -
formatString이 비어 있다면 아래 단계를 따른다:
-
webCustomFormatString을 item의
type
값으로 한다. -
webCustomFormat을 빈
type
으로 한다. -
webCustomFormatString이 "web " prefix로 시작하면 "web " prefix를 제거하고 남은 문자열을 webMimeTypeString에 저장한다.
-
webMimeType을 MIME 타입 파싱(webMimeTypeString 기준) 결과로 한다.
-
webMimeType이 실패이면 모든 단계를 중단한다.
-
item의
type
을 webCustomFormat으로 설정한다. -
webCustomFormat을 webCustomFormats에 추가한다.
-
-
payload를 UTF-8 디코딩(item의 바이트 시퀀스 기준) 결과로 한다.
-
payload와 presentationStyle을 시스템 클립보드에 formatString을 네이티브 클립보드 포맷으로 사용하여 삽입한다.
일부 OS는 여러 클립보드를 가짐(Linux: "primary", "secondary", "selection" 등). 어느 클립보드에 데이터를 쓰는지 정의해야 함.
-
-
웹 커스텀 포맷 쓰기 알고리즘(webCustomFormats 기준)을 실행한다.
OS별 알려진 포맷
- 입력
-
mimeType :
type
- 출력
-
wellKnownFormat : 플랫폼별 문자열 타입 (Mac: NSPasteboardType, Windows: LPCWSTR, Linux: const char*)
Windows: https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats 및 https://docs.microsoft.com/en-us/windows/win32/dataxchg/about-atom-tables?redirectedfrom=MSDN Mac: https://developer.apple.com/documentation/appkit/nspasteboardtype
-
wellKnownFormat을 빈 문자열로 한다.
-
mimeType의 essence가 "text/plain"이면,
Windows에서는 다음과 같이:
-
wellKnownFormat에 CF_UNICODETEXT 할당
MacOS에서는 다음과 같이:
-
wellKnownFormat에 NSPasteboardTypeString 할당
Linux, ChromeOS, Android에서는 다음과 같이:
-
wellKnownFormat에 "text/plain" 할당
-
-
그 외, mimeType의 essence가 "text/html"이면,
Windows에서는 다음과 같이:
-
wellKnownFormat에 CF_HTML 할당
MacOS에서는 다음과 같이:
-
wellKnownFormat에 NSPasteboardTypeHTML 할당
Linux, ChromeOS, Android에서는 다음과 같이:
-
wellKnownFormat에 "text/html" 할당
-
-
그 외, mimeType의 essence가 "image/png"이면,
Windows에서는 다음과 같이:
-
wellKnownFormat에 "PNG" 할당
MacOS에서는 다음과 같이:
-
wellKnownFormat에 NSPasteboardTypePNG 할당
Linux, ChromeOS, Android에서는 다음과 같이:
-
wellKnownFormat에 "image/png" 할당
-
-
그 외, mimeType의 essence가 "image/svg+xml"이면,
Windows에서는 다음과 같이:
-
wellKnownFormat에 CFSTR_MIME_SVG_XML 할당
MacOS에서는 다음과 같이:
-
wellKnownFormat에 UTTypeSVG 할당
Linux, ChromeOS, Android에서는 다음과 같이:
-
wellKnownFormat에 "image/svg+xml" 할당
-
-
wellKnownFormat을 반환한다.
OS별 포맷에서 알려진 MIME 타입
- 입력
-
osFormatName : 플랫폼별 문자열 타입 (Mac: NSPasteboardType, Windows: LPCWSTR, Linux: const char*)
- 출력
-
mimeType : MIME type
Windows: https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats 및 https://docs.microsoft.com/en-us/windows/win32/dataxchg/about-atom-tables?redirectedfrom=MSDN Mac: https://developer.apple.com/documentation/appkit/nspasteboardtype
Windows에서는 다음과 같이:
-
osFormatName이 "UnicodeText"면 mimeTypeString을 "text/plain"으로 설정
-
그 외, osFormatName이 "HTML Format"이면 mimeTypeString을 "text/html"로 설정
-
그 외, osFormatName이 "PNG"이면 mimeTypeString을 "image/png"로 설정
-
그 외, osFormatName이 CFSTR_MIME_SVG_XML이면 mimeTypeString을 "image/svg+xml"로 설정
MacOS에서는 다음과 같이:
-
osFormatName이 NSPasteboardTypeString이면 mimeTypeString을 "text/plain"으로 설정
-
그 외, osFormatName이 NSPasteboardTypeHTML이면 mimeTypeString을 "text/html"로 설정
-
그 외, osFormatName이 NSPasteboardTypePNG이면 mimeTypeString을 "image/png"로 설정
-
그 외, osFormatName이 UTTypeSVG이면 mimeTypeString을 "image/svg+xml"로 설정
Linux, ChromeOS, Android에서는 다음과 같이:
-
osFormatName이 "text/plain"이면 mimeTypeString을 "text/plain"으로 설정
-
그 외, osFormatName이 "text/html"이면 mimeTypeString을 "text/html"로 설정
-
그 외, osFormatName이 "image/png"이면 mimeTypeString을 "image/png"로 설정
-
그 외, osFormatName이 "image/svg+xml"이면 mimeTypeString을 "image/svg+xml"로 설정
-
mimeType을 MIME 타입 파싱(mimeTypeString 기준) 결과로 한다.
-
mimeType을 반환한다.
웹 커스텀 포맷 읽기
- 입력
-
item, 클립보드 아이템
-
webCustomFormatMap을 OS별 커스텀 포맷 맵 이름으로 한다.
-
webCustomFormatMap을 시스템 클립보드에서 읽는다.
-
webCustomFormatMap이 비어 있으면 item을 반환한다.
-
webCustomFormatMapString을 webCustomFormatMap에서 역직렬화한 JSON 문자열로 한다.
참고: webCustomFormatMap의 내용을 역직렬화할 JSON 리더 필요.
-
webCustomFormatMapString의 각 (key, value)에 대해:
-
mimeType을 MIME 타입 파싱(key 기준) 결과로 한다.
-
mimeType이 실패이면 루프 계속.
-
representation을 새로운 representation으로 한다.
-
representation의 MIME type을 mimeType으로 설정.
-
representation의 isCustom 플래그를 true로 설정.
-
webCustomFormat을 시스템 클립보드에서 value로 읽는다.
-
읽기 성공 시 representation의 data를 시스템 클립보드에서 가져온 데이터로 설정, 실패 시 루프 계속.
-
representation을 item의 list of representations에 추가.
-
웹 커스텀 포맷 쓰기
-
idx를 0으로 초기화.
-
webCustomFormatMap을 OS별 커스텀 포맷 맵 이름으로 한다.
-
webCustomFormatMapString을 빈 JSON 문자열로 한다.
-
items의 각 item에 대해:
-
webCustomFormat을 OS별 커스텀 포맷 이름으로 한다.
-
webCustomFormatIdx를 idx를 webCustomFormat에 붙인 결과로 한다.
-
item의
type
을 key로, webCustomFormatIdx을 value로 하여 webCustomFormatMapString에 JSON serializer로 삽입.참고: webCustomFormatMapString으로 직렬화할 JSON writer 필요.
-
item을 시스템 클립보드에 webCustomFormatIdx 포맷으로 삽입.
-
idx를 증가.
-
idx가 100보다 크면 루프 종료.
-
-
webCustomFormatMapString을 시스템 클립보드에 webCustomFormatMap 포맷으로 삽입.
OS별 커스텀 포맷 맵 이름
- 출력
-
webCustomFormatMap, 문자열
Windows에서는 다음과 같이:
-
webCustomFormatMap에 "Web Custom Format Map" 할당.
-
webCustomFormatMap 반환.
MacOS에서는 다음과 같이:
-
webCustomFormatMap에 "org.w3.web-custom-format.map" 할당.
-
webCustomFormatMap 반환.
Linux, ChromeOS, Android에서는 다음과 같이:
-
webCustomFormatMap에 "application/web;type=\"custom/formatmap\"" 할당.
-
webCustomFormatMap 반환.
운영체제별 커스텀 이름
- 출력
-
webCustomFormat, 문자열
Windows에서는 다음 기준을 따른다:
-
webCustomFormat에 "Web Custom Format"을 할당한다.
-
webCustomFormat을 반환한다.
MacOS에서는 다음 기준을 따른다:
-
webCustomFormat에 "org.w3.web-custom-format.type-"을 할당한다.
-
webCustomFormat을 반환한다.
Linux, ChromeOS, Android에서는 다음 기준을 따른다:
-
webCustomFormat에 "application/web;type="custom/format"을 할당한다.
-
webCustomFormat을 반환한다.
클립보드 이벤트 발생시키기
- 입력
-
e,
ClipboardEvent
발생시킬 이벤트 - 출력
-
없음
-
clear-was-called을 false로 한다.
-
types-to-clear를 빈 리스트로 한다.
-
clipboard-event-data를 새로운
DataTransfer
객체로,items
리스트는 빈 값으로 생성한다. -
clipboard-entry를 현재 클립보드 콘텐츠의 시퀀스 번호로 하거나, OS 클립보드가 시퀀스 번호를 지원하지 않는 경우 null로 한다.
-
trusted를 이벤트가 사용자 에이전트에 의해 생성된 경우 true, 그렇지 않으면 false로 한다.
-
target을 다음과 같이 설정한다:
-
이벤트를 다음과 같이 처리한다:
-
e가 "paste"이면,
-
clipboard-event-data의 내부 drag data store mode 플래그를 read-only로 설정한다.
-
trusted가 true이거나, 구현체가 스크립트 생성 이벤트에 OS 클립보드 읽기 권한을 부여하도록 설정된 경우,
-
OS 클립보드의 각 clipboard-part에 대해 아래를 수행한다:
-
clipboard-part가 평문 텍스트를 포함하면,
-
텍스트가 스크립트 엔진 내부 인코딩에 맞는지 확인한다.
-
new-data를 새로운
DataTransferItem
으로, drag data item kind는 string, drag data item type string은 text/plain으로 한다. -
new-data의 데이터를 평문 텍스트로 설정한다.
-
new-data를 clipboard-event-data의
items
리스트에 추가한다.
-
-
clipboard-part가 파일 참조를 나타내면, 각 파일 참조에 대해:
-
참조된 파일의 MIME 타입을 결정한다.
-
new-data를 새로운
DataTransferItem
으로, drag data item kind는 file, drag data item type string은 해당 MIME 타입(모르면application/octet-stream
)으로 한다. -
new-data의 데이터를 파일 참조 데이터로 설정한다.
-
new-data를 clipboard-event-data의
items
리스트에 추가한다.
-
-
clipboard-part가 HTML 또는 XHTML 형식의 텍스트를 포함하면(OS 클립보드 포맷 설명 기준),
-
구현체가 HTML 붙여넣기를 지원하면, HTML 붙여넣기 이벤트 처리(clipboard-part, clipboard-event-data)를 호출한다.
-
-
clipboard-part가 다른 지원되는 바이너리 혹은 텍스트 기반 포맷(see 필수 데이터 타입)의 데이터를 포함하면,
-
데이터의 MIME 타입 결정
-
new-data를 새로운
DataTransferItem
으로, drag data item kind는 file, drag data item type string은 해당 MIME 타입으로 한다. -
new-data의 데이터를 바이너리 또는 텍스트 기반 데이터로 설정한다.
-
new-data를 clipboard-event-data의
items
리스트에 추가한다.
-
-
-
-
clipboard-event-data의
files
속성을 clipboard-event-data의items
항목에 맞게 갱신한다. -
clipboard-event-data의
types
속성을 clipboard-event-data의items
항목에 맞게 갱신한다.
-
-
e가 "copy" 또는 "cut"이면,
-
해당
DataTransfer
객체의 내부 drag data store mode 플래그를 read/write로 한다.
-
-
-
e의
clipboardData
를 clipboard-event-data로 설정한다. -
e의
isTrusted
를 trusted로 설정한다. -
e의
composed
를 true로 설정한다. -
이벤트 e를 target에 버블링되고 취소 가능한 이벤트로,
ClipboardEvent
인터페이스로 디스패치한다.이벤트 디스패치 중 데이터 접근에 대한 구현 요구사항은 [HTML]에 정의되어 있다. 추가적인 클립보드 이벤트 전용 처리 규칙은 아래와 같다:
왜 여기서 정의하는가? 왜 HTML 명세에 포함되지 않는가?
-
스크립트가 clearData() 또는
clear()
를 호출하고,DataTransfer
객체 내부 drag data store mode 플래그가 read/write이면,-
clear-was-called 플래그를 true로 설정한다. 인자가 주어지면 해당 인자를 types-to-clear 리스트에 추가한다.
-
-
스크립트가 setData()를 호출하거나 아이템을 수정하고, clear-was-called 플래그가 true이면,
-
types-to-clear 리스트가 비어있으면,
-
clear-was-called 플래그를 false로 한다.
-
-
그 외, setData()의
type
인자 또는 새 아이템의 drag data item type string이 types-to-clear 리스트에 있다면,-
리스트에서 해당 항목을 제거하고, 리스트가 비어있으면 clear-was-called 플래그를 false로 한다.
-
-
-
스크립트가 getData()를 호출하거나
DataTransferItemList
에 접근하고 clipboard-entry가 설정되어 있으면,-
클립보드 데이터의 시퀀스 번호가 clipboard-entry와 일치하는지 확인한다. 클립보드가 더 이상 동일한 항목을 포함하지 않으면
DataTransferItemList
객체의 내부 drag data store mode를 protected로 설정한다.
-
경고! paste 이벤트를 감시하는 악성 스크립트가 사용자가 미래에 클립보드에 넣는 것을 무한 반복 루프를 통해 읽을 수 있습니다. 클립보드 시퀀스 번호를 지원하지 않는 플랫폼에서는 추가 제한이 필요합니다.
-
HTML 붙여넣기 이벤트 처리
- 입력
-
clipboard-part, 처리할 클립보드 파트
clipboard-event-data, 이 이벤트용
DataTransfer
객체 - 출력
-
없음
-
new-data를 새로운
DataTransferItem
으로, drag data item kind는 Plain Unicode string, drag data item type string은 text/html 또는 application/xhtml+xml로 한다. -
clipboard-part에서 마크업을 추출하고, 관련 파서를 사용해 DOM 트리를 생성한다.
-
마크업의 소스 URL이 알려져 있다면, HREF와 SRC 속성의 상대 URL을 소스 URL을 기준으로 모두 절대 URL로 변환해 해당 속성에 설정한다.
-
마크업의 출처가 로컬 애플리케이션이라면, 로컬 파일이나 OS 클립보드의 다른 부분을 참조하는지 확인한다. 참조가 있다면, 서브파트 참조는 반드시 cid: URL 스킴([RFC2392])을 활용해 content-id 참조로 바꿔야 한다. 이를 위해 아래 단계를 따른다:
이 단계가 필요한가? 내부 참조가 있는 다중 파트 지원 네이티브(플랫폼) 클립보드 구현이 존재하는가?
이 기능은 꼭 필요한지, 그리고 크로스 플랫폼 테스트가 어렵기 때문에 위험에 처해있음.
-
clipboard-event-data의
items
에 이미 참조된 파일 또는 클립보드 파트에 대한 항목이 있으면,-
itemNumber를 해당 항목의 인덱스로 설정한다.
-
-
그렇지 않으면,
-
new-file-data를 새
DataTransferItem
객체로 하고, drag data item kind는 "file"로, drag data item type string은 파일 또는 클립보드 파트의 MIME 타입(알 수 없다면application/octet-stream
)으로 설정한다. -
file-info를 새
File
객체로 하며,name
은 HTML 속성 값의 이름 부분으로,lastModified
는 참조된 파일의 타임스탬프 또는 클립보드 파트라면 0으로 설정한다. -
new-file-data의 내부
File
객체를 file-info로 설정한다. -
new-file-data를 clipboard-event-data의
items
에 추가하고, itemNumber를DataTransferItemList
에서 해당 항목의 인덱스로 한다.
-
-
로컬 파일 또는 클립보드 파트를 참조하는 DOM 속성을 'cid:'와 itemNumber로 갱신한다.
-
-
처리된 DOM을 직렬화하여 new-data에 생성된 HTML 코드로 갱신한다.
-
new-data를 clipboard-event-data의
items
에 추가한다.