Не так давно мы подробно рассказывали новые аттачи в Яндекс.Почте. В декабре в у нас появился новый просмоторщик картинок. Работать с изображениями в Почте благодаря этим нововведениям стало действительно проще и удобнее.
Тем не менее, оставалась ещё одна сложность: в связи с браузерными ограничениями изображения нельзя было вставлять прямо в тело письма. Картинку нужно было сохранить на своём компьютере и уже оттуда прикрепить к письму, как любой другой файл.
Мы долго думали над этой проблемой. Можно было использовать java-апплет или flash, но у этих решений были существенные ограничения. Например, при использовании java-апплета нужно будет обязательно разрешать выполнение апплета в браузере. В итоге мы решили использовать новые возможности современных браузеров, такие как Clipboard API, File API и Drag n Drop.
Читайте в нашем посте о том, как вставлять в письмо картинки из буфера обмена или по публичному URL и как добавлять их в тело письма простым перетягиванием с рабочего стола.
Вставка картинок из буфера обмена
До недавнего времени полноценная работа с буфером обмена в веб-приложениях казалась невозможной. Но затем появился новый API, специально предназначенный именно для этого (Clipboard API). Он представляет собой интерфейс для работы с данными из буфера обмена при копировании, вырезании и вставке. Интерфейс достаточно универсальный и работает не только с текстовыми данными, но и с файлами в разных форматах. Но, как это обычно бывает, поддерживается он не всеми браузерами и в разном объёме.
Наиболее полная поддержка на сегодняшний день реализована только в WebKit-браузерах (Safari, Chrome, Яндекс.Браузер). В этих браузерах для событий copy, cut и paste в объекте события есть доступ к объекту clipboardData. У clipboardData есть свойства items (элементы в буфере обмена) и types (типы информации в буфере обмена). Получать или менять информацию из буфера можно при помощи методов getData и setData.
В Chrome (c 18 версии) и Яндекс.Браузере есть доступ к картинкам в буфере обмена при вставке. Делается это примерно так:
// Элемент с contentEditable
var el = document.getElementById('editor');
el.addEventListener('paste', function(e) {
var clipboard = e.clipboardData;
if (clipboard && clipboard.items) {
// В буфере обмена может быть только один элемент
var item = clipboard.items[0];
if (item && item.type.indexOf('image/') > -1) {
// Получаем картинку в виде блоба
var blob = item.getAsFile();
if (blob) {
// Читаем файл и вставляем его в data:uri
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(event) {
var img = new Image();
img.src = event.target.result;
el.appendChild(img);
}
}
}
}
});
Кроме браузеров на движке WebKit, вставка картинкок из буфера обмена также работает в Firefox: там картинки в designMode сразу вставляются в data:uri.
Вставка картинок по публичному URL
Одно из самых простых и привычных действий — скопировать картинку со страницы в интернете и вставить её в письмо — не поддерживается браузерами по умолчанию. В Safari 5+ в объекте clipboardData нет свойства items, но есть массив types, содержащий типы копируемой иформации. И если копируемая картинка уже есть в интернете по публичному урлу, то её тоже получится вставить. При обычной вставке картинок в designMode Safari создает элемент img с фейковым значением аттрибута src (webkit-fake-url://416873AC...). К этому ресурсу никак нельзя получить доступ из JS, поэтому, чтобы фейковая картинка не вставлялась нужно делать preventDefault у объекта события.
// Элемент с contentEditable
var el = document.getElementById('editor');
el.addEventListener('paste', function(e) {
var clipboard = e.clipboardData;
if (clipboard && clipboard.types) {
var types = clipboard.types;
if (types.indexOf('public.url') > -1) {
// Останавливаем действие по умолчанию, чтобы не вставлялась картинка с фейковым урлом (webkit-fake-url://416873AC...)
e.preventDefault();
// Вставляем картинку
var img = new Image();
img.src = clipboard.getData('public.url');
el.appendChild(img);
}
}
});
Вставка по публичному урлу по умолчанию работает в IE9 и выше.
Вставка перетягиванием
Помимо прямого копирования картинок из буфера обмена или по публичному урлу, в некоторых браузерах есть возможность вставлять картинки драг-н-дропом. Это очень удобно, потому что можно добавить к письму несколько картинок сразу.
// Элемент с contentEditable
var el = document.getElementById('editor');
el.addEventListener('drop', function(e) {
var dataTransfer = e.dataTransfer;
if (dataTransfer && dataTransfer.files) {
var files = dataTransfer.files;
var len = files.length;
if (len) {
for (var i = 0; i < len; i++) {
var file = files[i];
// Вставляем только картинки
if (file.type.indexOf('image/') < 0) continue;
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(event) {
var img = new Image();
img.src = event.target.result;
el.appendChild(img);
};
}
e.preventDefault();
}
}
});
Это работает в Firefox, Safari 5.1+, Chrome и Яндекс.Браузере.
В Яндекс.Почте для написания писем с оформлением используется WYSIWYG-редактор TinyMCE. Мы написали для него плагин, объединяющий все решения из этой статьи. Он доступен по адресу github.com/Panya/tinymce_pasteimage.
Автор: Panya