본문 바로가기
language/javascript

자바스크립트로 시스템 클립보드 접근하기 (Access to the system clipboard in JavaScript.)

by vamalboro 2015. 9. 22.

부제 : System Clipboard는 멋지지만 멋지지 않다.


부제가 섹시하다.


오늘은 OS의 System Clipboard를 자바스크립트로 다룰때의 몇가지 이슈에 대해 정리하고자 한다.


브라우저는 OS의 System Clipboard를 Access하기 위한 방법으로 clipboardData 개체를 지원한다.



clipboardData(DataTransfer) 개체

documentation

개요

clipboardData개체는 기본적으로 read-only 개체이며 DataTransfer interface의 구현체이다.


IE의 경우 window개체를 통해 window.clipboardData로 접근이 가능하며

다른 브라우저의 경우 copy, cut, paste 이벤트 리스너에 전달되는 event 개체의 clipboardData 속성으로 접근이 가능하다.


제공하는 메소드

setData(format, data)

clipboardData개체의 값을 설정하는 함수이다.

format은 mime-type이며 text 타입과 url타입을 지정할 수 있다.

data는 text의 경우 일반 text와 blob(@see HTML5의 File API 관련)데이터를 지정할 수 있다.

return value는 성공/실패값으로 boolean 값을 반환한다.


getData(format)

clipboardData개체의 값을 얻어오는 함수이다.

format은 setData와 같으며 정상적으로 동작시 클립보드에 저장되어 있는 데이터값이 반환된다.


clearData(format)

clipboardData개체의 값을 지우는 함수이다.

format은 test, url, file, html, image를 지정할 수 있다.




대충,,, 간단한 설명은 이쯤하고 자세한건 위의 documentation을 참고하는 걸로 한다.



테스트하려는 이슈는 다음과 같다.

  • 시스템 클립보드의 setData, getData를 이용하여 복사/붙여넣기 기능을 구현하고 싶다.
    1. 단축키(Ctrl+c,x,v)와 브라우저 contextmenu를 통한 방법
    2. 특정한 UI를 제공(복사/잘라내기/붙여넣기 버튼) 하는 방법



단축키(Ctrl+c,x,v)와 브라우저 contextmenu를 통한 방법

  1. document.body 또는 원하는 element에 copy, cut, paste 이벤트 리스너를 할당 한다.
  2. 이벤트 리스너 함수에서 event개체의 clipboardData 또는 window.clipboardData개체에 접근하여 제공되는 메소드를 통해 데이터를 설정하거나 얻어온다.
  3. 이렇게 설정하거나 값을 얻어와 복사/잘라내기/붙여넣기 기능을 구현할 수 있다.
  4. github source 참고 (테스트한 소스이며 간단히 clipboardData와 execCommand만 테스트)
테스트 해본 결과로는 별다른 문제가 없다.
단축키나 컨텍스트 메뉴를 통한 방식은 매우 깔끔하며 딱히 문제될 만한 부분이 없다.
(다만,,, 실제 크로스브라우징 처리를 하며 이 기능 개발을 하려면 당연히 고민해야 될 부분은 많다. 특히 IE 버전별 처리...)




특정한 UI를 제공(복사/잘라내기/붙여넣기 버튼) 하는 방법 (execCommand를 이용)

  1. 준비
    1. 임의의 iframe을 생성해 놓는다.(copy,cut,paste를 수행할 document)
    2. document.body의 contenteditable 속성을 true로 설정한다.
  2. copy, cut, paste 등의 button element를 만들어 mouse click 이벤트 리스너를 할당한다.
  3. copy or cut
    1. copy or cut 버튼의 mouse click 이벤트 리스너 함수에서 복사하거나 붙여넣기할 값을 iframe의 document.body에 innerHTML로 설정한다.
    2. 이벤트 리스너 함수에서 iframe의 document.execCommand('copy' or 'cut')를 사용하여 강제로 clipboard 액션을 트리거한다.
      1. 이때 복사하고자 설정한 iframe document.body의 값이 시스템 클립보드에 복사된다.
  4. paste
    1. paste 버튼의 mouse click 이벤트 리스너 함수에서 iframe의 document.execCommand('paste')를 사용하여 강제로 clipboard 액션 트리거한다.
      1. 이때 시스템 클립보드에 있는 값이 iframe의 document.body에 붙여넣어 진다.
    2. iframe의 document.body에 붙여넣어진 값을 가져온다.(innerHTML)
      1. 이 값을 붙여넣기 기능에 사용할 수 있다.
  5. 이렇게 설정하거나 값을 얻어와 복사/잘라내기/붙여넣기 기능을 구현할 수 있다.
  6. github source 참고 (테스트한 소스이며 간단히 clipboardData와 execCommand만 테스트)

바이너리 데이타인 이미지등을 복사/붙여넣기 하는 방법은 조금 다르다.
그 부분은 다음 기회에 따로 포스팅.


테스트 해본 결과로는 일단 브라우저별로 동작이 다르다.
이 부분이 문제이다.

Internet Explorer (가능)
  • execCommand를 호출하면 브라우저 자체에서 보안 프롬프트를 띄워 사용자에게 이 액션을 허용할 것인지를 묻는다.
  • 허용하게 되면 해당 웹페이지가 새로고침될때까지 다시 보안 프롬프트를 띄우지 않으며 execCommand가 제약 없이 실행된다.
    • copy, cut, paste 모두 동일
Chrome (불가능)
  • execCommand를 통한 copy, cut은 IE와 동일하게 잘 동작한다.
    • IE와 같이 보안 프롬프트 메시지는 뜨지 않는다.
    • Chrome 42+ version 부터 지원한다.
  • execCommand를 통한 paste는 동작하지 않는다.
    • 아예 동작하지 않으며 크롬 documentation에는 보안상 이유로 지원하지 않는다고 나와있다.
FireFox (불가능)
  • execCommand를 통해서는 copy, cut, paste 모두 보안상의 이유로 강제 트리거는 불가능하다.
Opera, Safari (모름)
  • 안해봄...



결론
위의 테스트가 완벽하다고 할 순 없으나 적당한 시간을 투자하여 나온 결론은
크롬이나 파이어폭스 브라우저에서 execCommand의 지원 한계로 인해 커스텀한 UI를 만들어 시스템 클립보드에 접근할 수 있는 방법은 찾지 못하였다.
popular한 웹에디터나 웹오피스들을 살펴보아도 위와 같이 IE에서는 시스템 클립보드를 이용한 복사/잘라내기/붙여넣기 기능을 제공한다.
물론, 단축키를 이용한 방식은 모든 브라우저에서 잘 동작한다.

etc...
그런데 Google Docs는 지원한다....OTL...
과연 API에도 지원안한다고 했는데 어떻게 했을까 싶어서 디버깅도 해보고 별짓을 다해봤지만 방법을 찾을 수 없었다...

오늘도 뭔가 멋진걸 되게하는 포스팅이 아닌 안되는걸 증명하는 포스팅이 되어버린 느낌적인 느낌에 기분이 좋지만은 않다 ..










이 내용은 지극히 경험적인 내용을 정리한 것입니다.

잘못된 내용이 있거나 문제가 될만한 부분이 있다면 댓글 또는 페이스북(https://www.facebook.com/vamalboro)으로 연락주시면 당장! 고치도록 하겠습니다.

'language > javascript' 카테고리의 다른 글

Euclidean Distance (유클리디안 거리)  (2) 2010.04.11
Google Closure Tools  (0) 2010.02.18
웹에디터 FCKeditor (J2EE 환경에서 사용)  (2) 2009.03.25