TITLE:JavaScriptでpreタグで囲まれたソースコードをtextareaにコピーする
#navi(../)
RIGHT:Posted by [[aterai]] at 2012-07-25
* JavaScriptでpreタグで囲まれたソースコードをtextareaにコピーする [#c270c144]

#contents

** 概要 [#f8b8ce13]
以下、Opera 12.50で、Clipboard API を使い、preタグで囲まれたソースコードを簡単にコピーする方法のテスト。

- ユーザーJavaScriptフォルダにコピー
- pre要素をダブルクリックすると、内容がtextareaに変換される
- Clipboard API が使用できる Opera 12.50 の場合、コピー、カットすると元のpreに戻る

** ソースコード [#v391264a]
#code{{
(function() {
  var listener = function(e) {
    var tx = document.createElement("textarea"),
        div = document.createElement("div"),
    closeListener = function(e) {
      switch(e.type) {
      case 'copy':
      case 'cut':
        var dataTransfer = e.clipboardData;
        dataTransfer.items.add(this.innerText, 'text/plain');
        this.parentNode.replaceChild(this.originalPre, this);
        e.preventDefault();
        break;
      }
    };

    tx.style.width  = parseInt(getComputedStyle(this,"").width).toString()+"px";
    tx.style.height = "240px";
    tx.originalPre  = this;

// ctrl-c 無しでコピーできるかもと思ったけど…
//       var event = new ClipboardEvent('copy', { bubbles: true, cancelable: true } );
//       var dataTransfer = event.clipboardData;
//       dataTransfer.items.add("aaaaaaaaaaaaaaaaaaaaaaa", "text/plain");
//       //this.parentNode.replaceChild(this.originalPre, this);
//       document.dispatchEvent(event);
//       //event.preventDefault();

    tx.addEventListener("keydown", function(e) {
      if(e.keyCode=="27") { // ESC
        this.parentNode.replaceChild(this.originalPre, this);
      }
    }, false);
    tx.addEventListener("dblclick", function(e) {
      this.parentNode.replaceChild(this.originalPre, this);
    }, false);
    div.innerHTML = this.innerHTML.replace(/<br[ \/]*>/ig, "\n").replace(/<.*?>/mg, "");
    tx.value = div.childNodes[0].nodeValue.replace(/\xA0/g, ' ');
    this.tx = tx;
    this.parentNode.replaceChild(this.tx, this);
    this.tx.focus();
    this.tx.select();

    tx.addEventListener('copy', closeListener, false);
    tx.addEventListener('cut',  closeListener, false);
  },
  pre = document.getElementsByTagName("pre"),
  i = 0, len = pre.length;
  for(; i<len; i++) {
    pre[i].addEventListener("dblclick", listener, false);
  }
}());
}}

** 参考リンク [#led8cfb3]
- [http://sybian99.googlepages.com/preToTextarea.user.js]
- %%[http://d.hatena.ne.jp/Sybian/20070815/p2:title=preをtextareaに - Sybianの日記]%%
-- %%via: [http://kawatarou.info/note/opera/opera_userjs.htm:title=Shishimushi - User JavaScript]%%
- [http://d.hatena.ne.jp/aterai/20080725/1216954636 preタグで囲まれたソースコードを簡単にコピーする方法 - てんぷらメモ@はてな]
- [http://www.w3.org/TR/clipboard-apis/ Clipboard API and events]
- [http://my.opera.com/desktopteam/blog/2012/07/06/marlin-1250-swim Opera Desktop Team - First bite of 12.50 ‘Marlin’: Clipboard API, redesigned key event handling, -webkit- CSS, and Notification Center]
- [http://domes.lingua.heliohost.org/webapi/intro-webplatform1.html#section-1-3 クリップボード API - Introduction to the Web Platform - DOM ECMAScripting]

** コメント [#vf0fac74]
#comment