부제 : 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)으로 연락주시면 당장! 고치도록 하겠습니다.

저작자 표시 비영리 변경 금지
신고
블로그 이미지

웹오피스 개발자 피스티스

사이냅소프트에서 웹오피스를 개발하고 있습니다.

부제 : 한글 웹폰트는 메모리 돼지?


User Interaction이 많은 문서 편집 웹 애플리케이션을 개발 및 유지보수 하던 중 멘탈붕괴를 이르게 하는 문제를 만났다.


이름하야 돼지처럼 메모리를 점유하는 웹폰트 문제.(메모리 릭...의심된다.)


현재 개발중인 웹 애플리케이션에서는 한글 웹폰트(저작권 문제가 없는)를 설정하여 텍스트에 스타일 편집을 할 수 있도록 하는 기능이 있다.(지원되는 한글 웹폰트는 수십가지)




현상은 다음과 같다.


테스트 환경(VM) - 현상은 Native 환경에서도 동일하다.

OS : Window 10 Pro K (64bit)

Browser : Internet Explorer 11 (11.0.10240.16431)

CPU : Intel Core i7-4790 3.50GHz

Memory : 2GB


테스트 시나리오

한글 웹폰트를 적용한 컨텐츠(텍스트)가 있는 웹 애플리케이션을 지속적으로 새로고침한다. (10초 간격)


테스트 결과

지속적인 새로고침만 해도 IE11의 메모리 점유율이 무한정 누적되다가 약 10번~15번 정도 새로고침했을때 쯔음 약 1.5GB의 메모리까지 점유하다가 갑자기 죽는다.(crash 현상)



그 외에 다른 환경

동일 OS에서의 Edge, Chrome, FireFox 등의 브라우저

window 7, 8.1에서의 Internet Explorer 11, Chrome, FireFox 등의 브라우저

Internet Explorer 8,9,10 브라우저


등의 환경에서는 발생하지 않는다.


또한, 웹폰트를 설정하지 않으면(다운로드 하지 않으면) 몇시간씩 새로고침하여도(자동으로 하도록) 메모리 누적현상은 발생하지 않는다.



문제를 해결하기 위한 시도들 (문제가 발생한 환경에서...)

시도 1

- window unload/beforeunload 이벤트시 @font-face가 설정된 document.styleSheet개체의 cssRule과 style Node remove & cssText null 처리

결과

- 아무런 영향이 없다.


시도 2

window unload/beforeunload 이벤트시 웹폰트가 적용된 DOM Node remove

결과

- 아무런 영향이 없다.


시도 3

- 한글 웹폰트 몇개를 설정하고 마크업에 font-family 적용한 간단한 테스트 페이지를 작성 후

  웹폰트 서비스 업체에서 제공하는 웹폰트로 설정하여 테스트

결과

- 1 : 다운로드 하게 되는 웹폰트의 종류가 적거나 용량이 작으면 메모리 문제가 발생하지 않는다.

- 2 : 다운로드 하게 되는 웹폰트의 종류가 많거나 용량이 크면 메모리 문제가 발생한다.


시도 4

- 웹폰트가 설정된 웹페이지를 찾아서 동일한 테스트를 진행해 보았다.

결과

- 1 : http://www.typolink.co.kr/(웹폰트 서비스 사이트)의 한글 웹폰트 샘플페이지는 이러한 현상이 두드러지게 발생하지 않는다.(왜냐면 대부분의 샘플 페이지는 단 하나의 웹폰트만 로딩한다.)

- 2 : http://hangeul.naver.com/2014/nanum 네이버의 나눔 글꼴 사이트에서는 동일하게 메모리 누적현상 발생 후 crash 된다. 이페이지는 대략 4~5개의 용량이 큰 나눔글꼴 웹폰트를 로딩한다.

     만약 이 페이지에서 이러한 현상이 발생하지 않았다면,,, 개발자도구로 모든 소스를 뒤져서라도 해결방법에 대한 아이디어를 찾아보았을텐데 아쉽다...


그 외 시도들

- 엄청 무지 많음... 



결론

시도한 방법들이 너무 많아서 다 적을 순 없지만 그 테스트들로 인해 얻은 결론은

다운로드하는 (캐시가 되어 있어도 마찬가지다.) 한글 웹폰트의 용량이 크면

발생한다.

용량이 상대적으로 20배 이상 작은 영문 웹폰트는 아무리 많이 다운로드 하더라도 이 문제는 발생하지 않더라...OTL...

개수보다는 개별 웹폰트 파일의 용량이 이 문제를 유발하는 것 같다.


100% 해결할 수 있는 방법이 없다.

Window 10 Internet Explorer 11 버전의 리소스(웹폰트) 메모리 관리 버그로 판단된다.

OS와 IE11의 이 문제가 해결된 패치가 나오길 기다리는 수밖에...



혹시나 이러한 비슷한 문제를 겪었는데 해결하신 용자분이 계시다면 저에게 은총을 ... ㅠㅠ





그나저나 블로그에 글쓴게 어언 몇년만인지...




저작자 표시 비영리 변경 금지
신고
블로그 이미지

웹오피스 개발자 피스티스

사이냅소프트에서 웹오피스를 개발하고 있습니다.