Поддержка SVG для API Async Clipboard.

Интерфейс Clipboard API Async Clipboard обеспечивает доступ для чтения и записи к содержимому системного буфера обмена. Это позволяет веб-приложению реализовать функции вырезания, копирования и вставки. Вы можете вставить данные из буфера обмена в приложение, вызвав метод read() , и скопировать данные в буфер обмена, вызвав метод write() . Помимо текста , изображений в формате PNG, очищенного и необработанного HTML и пользовательских веб-форматов , API Async Clipboard теперь также поддерживает копирование и вставку изображений SVG, что означает, что вы, наконец, можете взаимодействовать с программным обеспечением для редактирования изображений, которое занимается SVG становится более естественным за счет копирования и вставки изображений SVG в виде изображений, а не текста, или использования хакерских обходных путей .

Функция обнаружения поддержки SVG

Обнаружьте поддержку изображений SVG (и любого другого типа MIME), вызвав статический метод ClipboardItem.supports() , передав ему нужный тип MIME.

const supportsSVG = () => {
  if (
    !('supports' in window.ClipboardItem) ||
    !window.ClipboardItem.supports('image/svg+xml')
  ) {
    return false;
  }
  return true;
};

Скопируйте изображение SVG

Скопируйте изображение SVG, заполнив ClipboardItem объектом. Большой двоичный объект с данными изображения SVG — это значение и тип большого двоичного объекта (то есть в данном случае 'image/svg+xml' ) в качестве его ключа.

copyButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  try {
    const blob = await fetch(img.src).then((response) => response.blob());
    await navigator.clipboard.write([
      new window.ClipboardItem({
        [blob.type]: blob,
      }),
    ]);
  } catch (err) {
    console.error(err.name, err.message);
    alert(err.message);
  }
});

Вставьте изображение SVG

Чтобы вставить изображение SVG, прочитайте ClipboardItem обратно из буфера обмена и получите нужный тип (то есть в данном случае 'image/svg+xml' ) с помощью метода getType() . Это возвращает большой двоичный объект, который после преобразования в URL-адрес большого двоичного объекта можно назначить атрибуту src <img> .

pasteButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  const [clipboardItem] = await navigator.clipboard.read();
  const svgBlob = await clipboardItem.getType('image/svg+xml');
  if (!svgBlob) {
    alert('No SVG in the clipboard.');
    return;
  }
  const image = document.createElement('img');
  const blobURL = URL.createObjectURL(svgBlob);
  image.addEventListener('load', () => {
    URL.revokeObjectURL(blobURL);
  });
  image.src = blobURL;
});

Санитарная обработка

SVG — мощный формат, который, например, позволяет использовать встроенные скрипты. Это может быть опасно, когда пользователь вставляет контент из неизвестных источников, поэтому браузер выполняет этап очистки. При копировании данных API Async Clipboard создает правильно сформированный документ SVG, а затем записывает его в буфер обмена. При вставке данных анализатором фрагментов создается строго обработанный фрагмент SVG. Таким образом, перед операцией вставки атрибуты обработчика событий onclick все еще присутствуют, но после вставки они удаляются.

Приложение Clipboard Viewer на macOS, проверяющее содержимое буфера обмена. Это показывает, что атрибуты прослушивателя событий onclick в SVG все еще присутствуют.
Приложение Clipboard Viewer на macOS, проверяющее содержимое буфера обмена. Это показывает, что атрибуты прослушивателя событий onclick в SVG все еще присутствуют.

Демо

Изучите копирование и вставку SVG в демо- версии Glitch. Просмотрите исходный код , чтобы увидеть, как он работает. Обязательно попробуйте щелкнуть любой из кружков до и после копирования и вставки. После вставки потенциально опасные атрибуты обработчика событий onclick удаляются.

Благодарности

Поддержка SVG для API Async Clipboard в Chromium была реализована командой Microsoft Edge. Этот пост рассмотрели Рэйчел Эндрю и Анупам Снигдха.