Как стать автором
Обновить

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

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


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

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

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

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


Устанавливаем размер аплета 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 + '" /');
                                }
                        });
                }
        });
});
</script>


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

<?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

Подпись аплетов — тут.
Теги:
Хабы:
Всего голосов 38: ↑37 и ↓1+36
Комментарии17

Публикации

Истории

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область