Вставка изображения из буфера обмена в редактор TinyMCE
Некоторое время назад у нас на проекте возникла необходимость вставить картинки из буфера обменя прямо в редактор. Задача оказалась нетривиальной, и простых решений не имела. По факту поиска в интернете было найдено всего два пути решения проблемы – либо менять редактор целиком на флешовый, что привело бы к переписыванию большой части проекта, либо – ява-аплет. Собственно, о последнем и пойдет речь ниже.
Для решения проблемы мы использовали ява-аплет Supa.
Аплет без подписи работать не будет, соответственно его нужно подписать. Подписи выдают сертифицированные на это дело сервисы, которые требуют за это соответствующую плату. Но, для того чтобы оценить работоспособность, тратить деньги как то не хотелось. Поэтому был использован алгоритм, подсмотренный на сайте, указанном в конце статьи. Подпись дается на 8 мес, но для оценки эффективности работы – предостаточно.
Код для вставки аплета
Прошу прощения — пришлось убрать теги из кода — хабр понимал их буквально :)
Устанавливаем размер аплета 0х0 px, так как по-умолчанию аплет отображает изображение из буфера обмена без аплоуда на сервер, а нам нужно чтобы аплоуд происходил по нажатию кнопки в редакторе.
Интеграция в TinyMCE
Немного упростив код из примера для аплета получаем управляющую обертку на JS, состоящую из двух функций.
Добавление кнопки в TinyMCE
Код аплоуда на сервере
Материалы:
Supa — supa.sourceforge.net
Подпись аплетов — тут
Для решения проблемы мы использовали ява-аплет 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 комментарий