Вставка изображения из буфера обмена в редактор TinyMCE

Некоторое время назад у нас на проекте возникла необходимость вставить картинки из буфера обменя прямо в редактор. Задача оказалась нетривиальной, и простых решений не имела. По факту поиска в интернете было найдено всего два пути решения проблемы – либо менять редактор целиком на флешовый, что привело бы к переписыванию большой части проекта, либо – ява-аплет. Собственно, о последнем и пойдет речь ниже.

Для решения проблемы мы использовали ява-аплет Supa.

Аплет без подписи работать не будет, соответственно его нужно подписать. Подписи выдают сертифицированные на это дело сервисы, которые требуют за это соответствующую плату. Но, для того чтобы оценить работоспособность, тратить деньги как то не хотелось. Поэтому был использован алгоритм, подсмотренный на сайте, указанном в конце статьи. Подпись дается на 8 мес, но для оценки эффективности работы – предостаточно.

Код для вставки аплета

Прошу прощения — пришлось убрать теги из кода — хабр понимал их буквально :)

applet id="SupaApplet" archive="supa/Supa.jar" code="de.christophlinder.supa.SupaApplet" width="0" height="0"
 param name="imagecodec" value="png" /param
 param name="encoding" value="base64" /param
 param name="previewscaler" value="fit to canvas" /param
 param name="trace" value="true" /param
/applet


Устанавливаем размер аплета 0х0 px, так как по-умолчанию аплет отображает изображение из буфера обмена без аплоуда на сервер, а нам нужно чтобы аплоуд происходил по нажатию кнопки в редакторе.

Интеграция в TinyMCE

Немного упростив код из примера для аплета получаем управляющую обертку на JS, состоящую из двух функций.

function paste() 
 {
 var s = new supa();
 try 
 {
 var applet = document.getElementById( "SupaApplet" );
 
 if (!s.ping(applet)) throw "SupaApplet is not loaded (yet)";
 
 var err = applet.pasteFromClipboard(); 
 switch (err) 
 {
 case 0:
 break;
 case 1: 
 case 2:
 case 3:
 case 4:
 default:
 return false;
 }
 }
 catch (e) 
 {
 alert(e);
 throw e;
 }
 return upload();
 } 
 function upload() 
 {
 var s = new supa();
 var applet = document.getElementById("SupaApplet");
 
 try 
 { 
 var result = s.ajax_post(applet, "supa/upload.php", "screenshot", "screenshot.jpg", 
 { 
 form: document.forms["form"] 
 });
 if (result.match("^OK")) 
 {
 var url = result.substr(3);
 return url;
 } 
 else return false;
 } 
 catch (ex) { return false; } 
 return false;
 }


Добавление кнопки в TinyMCE

$(document).ready(function()
{
 $('#editor').tinymce(
 {
 script_url : '../js/tiny_mce/tiny_mce.js',
 theme : "advanced",
 plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",
 theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,formatselect,fontselect,fontsizeselect",
 theme_advanced_buttons2 : "search,|,bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,image,|,forecolor,backcolor",
 theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup",
 theme_advanced_buttons4 : "insert_image",
 theme_advanced_toolbar_location : "top",
 theme_advanced_toolbar_align : "left",
 theme_advanced_statusbar_location : "bottom",
 theme_advanced_resizing : false,
 setup : function(ed) 
 {
 ed.addButton('insert_image',
 {
 title: 'Insert Image',
 image: 'images/add.png',
 onclick: function()
 {
 tmp = paste();
 if (tmp !== false) 
 ed.selection.setContent('img src="upload/' + tmp + '" /');
 }
 });
 }
 });
});


Код аплоуда на сервере

<?php
 define('FILESTORE_PATH', "../include/tcpdf/upload");
 define('FILESTORE_URLPREFIX', "upload"); 

header('Content-Type: text/plain');

if (!$_FILES['screenshot']) 
 {
 echo "ERROR: NO FILE (screenshot)";
 exit;
 }
 if ($_FILES['screenshot']['error']) 
 {
 echo "PHP upload error: " . $_FILES['screenshot']['error'];
 exit;
 } 
 $filename = uniqid() . '.jpg'; 
 $file = FILESTORE_PATH . "/" . $filename;
 $fh = fopen($_FILES['screenshot']['tmp_name'], "r");
 if (!$fh) 
 {
 echo "ERROR: could not read temporary file";
 }
 $data = fread($fh, filesize($_FILES['screenshot']['tmp_name']));
 fclose($fh);
 $fh = fopen($file, "w");
 if (!$fh) 
 {
 echo "ERROR: could not open destination file";
 die();
 }
 fwrite($fh, base64_decode($data));
 fclose($fh);
 
 if (is_uploaded_file( $_FILES['screenshot']['tmp_name'])) 
 {
 unlink($_FILES['screenshot']['tmp_name']);
 }
 echo "OK:" . FILESTORE_URLPREFIX . "/" . $filename;
?>


Материалы:

Supa — supa.sourceforge.net

Подпись аплетов — тут


1 комментарий

комментарий был удален
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.