JavaScript/pre2textarea のバックアップの現在との差分(No.9)
TITLE:JavaScriptでpreタグで囲まれたソースコードをtextareaにコピーする
Posted by aterai at 2012-07-25
JavaScriptでpreタグで囲まれたソースコードをtextareaにコピーする
- title: JavaScriptでpreタグで囲まれたソースコードをtextareaにコピーする author: aterai pubdate: 2012-07-24T18:09:17+09:00 description: JavaScriptを使用して、preタグで囲まれたソースコードを簡単にコピーするためのBookmarkletを作成する
概要
以下、Opera 12.50で、Clipboard API を使い、preタグで囲まれたソースコードを簡単にコピーする方法のテスト。- オリジナルはpre to textarea for Greasemonkey
- preタグをtextareaにしてコピーするという方法を引用
- preタグで囲まれたソースコードを簡単にコピーする方法 - てんぷらメモ@はてなから移動の予定
- ユーザーJavaScriptフォルダにコピー pre2textarea.js
- pre要素をダブルクリックすると、内容がtextareaに変換される
- Clipboard API が使用できる Opera 12.50 の場合、コピー、カットすると元のpreに戻る
概要
pre
タグで囲まれたソースコードを簡単にコピーする
ソースコード
#spanend
#spandel
// ==UserScript==
#spanend
#spandel
// @name <pre> to <textarea>
#spanend
#spandel
// @namespace http://terai.xrea.jp/
#spanend
#spandel
// @include http://*
#spanend
#spandel
// @exclude http://*.google.*
#spanend
#spandel
// @description pre <-> textarea
#spanend
#spandel
// @version 1.0.4
#spanend
#spandel
// ==/UserScript==
#spanend
#spandel
// Double Click <PRE>, open <TEXTAREA>
#spanend
#spandel
// Test: Clipboard API and events
#spanend
- オリジナルは、[http://sybian99.googlepages.com/preToTextarea.user.js pre to textarea for Greasemonkey]
-- `pre`タグをtextareaにして簡単にコピーできるようにする
- [https://ateraimemo.com/data/javascript/pre2textarea.user.js pre2textarea.user.js]
- `pre`要素をダブルクリックすると、内容が`textarea`に変換される
- ダウンロード用のリンクを作成(`Java`のソースコードの場合は自動的にファイル名を取得)し、保存ダイアログを開く
-- [[JavaScriptでソースコードからJavaのファイル名を取得する>JavaScript/JavaFileName]]
#spandel
// Fork of <pre> to <textarea> http://userscripts.org/scripts/show/11438
#spanend
#spandel
// original author is Sybian http://d.hatena.ne.jp/Sybian/
#spanend
#spanadd
* ソースコード [#sourcecode]
#spanend
#spanadd
#gist(5441120)
#spanend
#spandel
// _@name <pre> to <textarea>
#spanend
#spandel
// _@namespace http://d.hatena.ne.jp/Sybian/
#spanend
#spandel
// _@include http://*
#spanend
#spandel
// _@description pre <-> textarea
#spanend
#spandel
// _@version 1.0.2
#spanend
#spandel
// Ctrl+Click <PRE>, become <TEXTAREA>
#spanend
#spandel
// ESC or Ctrl+[ or Ctrl+Shift+Click in <TEXTAREA>, restore <PRE>
#spanend
#spandel
#spanend
#spandel
(function() {
#spanend
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;
}
};
#spandel
#spanend
tx.style.width = parseInt(getComputedStyle(this,"").width).toString()+"px";
tx.style.height = "240px";
tx.originalPre = this;
#spandel
#spanend
#spandel
// ctrl-c 無しでコピーできるかもと思ったけど…
#spanend
#spandel
// var event = new ClipboardEvent('copy', { bubbles: true, cancelable: true } );
#spanend
#spandel
// var dataTransfer = event.clipboardData;
#spanend
#spandel
// dataTransfer.items.add("aaaaaaaaaaaaaaaaaaaaaaa", "text/plain");
#spanend
#spandel
// //this.parentNode.replaceChild(this.originalPre, this);
#spanend
#spandel
// document.dispatchEvent(event);
#spanend
#spandel
// //event.preventDefault();
#spanend
#spandel
#spanend
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();
#spandel
#spanend
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);
}
#spandel
}());
#spanend
#spandel
Bookmarklet版
Bookmarklet版
- 名前
- pre2textarea
- アドレス(YUI Compressor で圧縮)
javascript:(function(){var d=document.getElementsByTagName("pre"),b=0,a=d.length,c=function(g){var f=document.createElement("textarea"),h=document.createElement("div");f.style.width=parseInt(getComputedStyle(this,"").width).toString()+"px";f.style.height="240px";f.originalPre=this;f.addEventListener("keydown",function(i){if(i.keyCode=="27"){this.parentNode.replaceChild(this.originalPre,this)}},false);f.addEventListener("dblclick",function(i){this.parentNode.replaceChild(this.originalPre,this)},false);h.innerHTML=this.innerHTML.replace(/<br[ \/]*>/ig,"\n").replace(/<.*?>/mg,"");f.value=h.childNodes[0].nodeValue.replace(/\xA0/g," ");this.tx=f;this.parentNode.replaceChild(this.tx,this);this.tx.focus();this.tx.select()};for(;b<a;b++){d[b].addEventListener("dblclick",c,false)}}());
-
pre2textarea
-
- アドレス(
YUI Compressor
で圧縮)(function(){window.URL=window.URL||window.webkitURL;function h(l,k,m){var j=new Blob([l],{type:k+";charset=UTF-8"}),i=document.createElement("a");i.innerHTML="Download: "+m;i.setAttribute("download",m);i.href=window.URL.createObjectURL(j);return i}function d(j){var i=j.match(/public(?:\s|final)+(?:class|interface|enum)\s+([^<{\s]+)/m);return(i?i[1]:"Unknown")+".java"}function e(i){var j=document.createElement("div");j.innerHTML=i.innerHTML.replace(/<br[ \/]*>/gi,"\n").replace(/<.*?>/gm,"");return j.childNodes[0].nodeValue.replace(/\xA0/g," ")}function c(j){var i=j.downloadLink;j.parentNode.replaceChild(j.originalPre,j);if(i!=null&&i.parentNode){window.URL.revokeObjectURL(i.href);i.parentNode.removeChild(i)}}var f=function(l){var k=function(m){switch(m.type){case"keydown":if(m.key==="Escape"){c(this)}break;case"dblclick":c(this)}},j=this.getBoundingClientRect(),i=document.createElement("textarea");i.addEventListener("keydown",k,false);i.addEventListener("dblclick",k,false);i.style.width=j.width+"px";i.style.height=(j.height>240?240:j.height)+"px";i.originalPre=this;i.value=e(this);this.tx=i;this.parentNode.replaceChild(this.tx,this);this.tx.focus();this.tx.select();i.downloadLink=h(i.value,"text/plain",d(i.value));i.parentNode.insertBefore(i.downloadLink,i.nextSibling);i.downloadLink.click()},g=document.getElementsByTagName("pre"),b=0,a=g.length;for(;b<a;b++){g[b].addEventListener("dblclick",f,false)}}());
メモ: ローカルにドロップして保存(ファイル名付き)
メモ: ローカルにドロップして保存(ファイル名付き)
- FutureSoftware開発日誌 Ver2.0 » HTML5のドラッグ&ドロップによるファイル保存
- Operaで動作しない
-
Chrome
でのみ動作 - ファイルとしてダウンロード可能
function makeDraggableDownloadLink(text, mimeType, fileName) {
var blob = new Blob([text], {type: mimeType}),
a = document.createElement('a');
a.appendChild(document.createTextNode("download"));
a.setAttribute('download', fileName);
if(window.createObjectURL) {
a.href = window.createObjectURL(blob);
}else if(window.createBlobURL) {
a.href = window.createBlobURL(blob);
}else if(window.URL && window.URL.createObjectURL) {
a.href = window.URL.createObjectURL(blob);
}else if(window.webkitURL && window.webkitURL.createObjectURL) {
a.href = window.webkitURL.createObjectURL(blob);
}
window.URL = window.URL || window.webkitURL;
a.href = window.URL.createObjectURL(blob);
a.addEventListener("dragstart", function(e) {
e.dataTransfer.setData("DownloadURL", [mimeType,fileName,this.href].join(':'));
}, false);
return a;
}
参考リンク
メモ: 直接クリップボードにコピー
- クリップボードにコピー - 素人がプログラミングを勉強していたブログ
- markdown形式でリンクをクリップボードにコピーするchrome-extension作った - fukayatsu.dev()
//ie, chrome-extension??? document.execCommand("copy");
メモ: Clipboard API
-
Clipboard API
が使用できるChrome
やOpera 12.50
の場合、コピー、カットすると自動的に元のpre
に戻すことが可能
#spanend
#spanadd
var listener = function(e) {
#spanend
var tx = document.createElement("textarea"),
rect = this.getBoundingClientRect(),
name, ret,
closeListener = function(e) {
switch(e.type) {
case 'copy':
case 'cut':
var dataTransfer = e.clipboardData;
dataTransfer.items.add(this.innerText, 'text/plain');
cleanup(this);
e.preventDefault();
break;
case 'keydown':
if(e.key==="Escape") {
cleanup(this);
}
break;
case 'dblclick':
cleanup(this);
}
};
tx.addEventListener('copy', closeListener, false);
tx.addEventListener('cut', closeListener, false);
tx.addEventListener("keydown", closeListener, false);
tx.addEventListener("dblclick", closeListener, false);
#spanadd
// ...
#spanend
#spanadd
参考リンク
- pre to textarea for Greasemonkey
- Clipboard API and events
- Opera Desktop Team - First bite of 12.50 ‘Marlin’: Clipboard API, redesigned key event handling, -webkit- CSS, and Notification Center
- クリップボード API - Introduction to the Web Platform - DOM ECMAScripting