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

Интерфейс Clipboard API Async Clipboard обеспечивает доступ для чтения и записи к содержимому системного буфера обмена. Это позволяет веб-приложению реализовывать функции вырезания, копирования и вставки. Вы можете вставлять данные из буфера обмена в приложение, вызывая метод read() , и копировать данные в буфер обмена, вызывая метод write() . Помимо текста , изображений в формате Portable Network Graphics (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 объектом. Blob с данными изображения SVG является значением, а тип blob (то есть '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() . Это возвращает blob, который после преобразования в URL blob можно назначить атрибуту 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 в демо . Просмотрите исходный код, чтобы увидеть, как это работает. Обязательно попробуйте нажать на любой из кругов до и после копирования и вставки. После вставки потенциально опасные атрибуты обработчика событий onclick удаляются.

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

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