Compatibilidade com SVG para a API Async Clipboard

A interface Clipboard da API Async Clipboard oferece acesso de leitura e gravação ao conteúdo da área de transferência do sistema. Isso permite que um aplicativo da Web implemente recursos de recorte, cópia e colagem. É possível colar dados da área de transferência em um aplicativo chamando o método read() e copiar dados para a área de transferência chamando o método write(). Além de texto, imagens no formato Portable Network Graphics (PNG), HTML limpo e não limpo e formatos personalizados da Web, a API Async Clipboard agora também oferece suporte à cópia e inserção de imagens SVG, o que significa que você pode interagir com softwares de edição de imagens que lidam com SVGs de forma mais natural, copiando e colando imagens SVG como imagens em vez de texto ou usando soluções alternativas hackeadas.

Recurso de detecção de suporte a SVG

Detecte o suporte a imagens SVG (e qualquer outro tipo MIME) chamando o método ClipboardItem.supports() estático e transmitindo o tipo MIME desejado.

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

Copiar uma imagem SVG

Copie uma imagem SVG preenchendo o ClipboardItem com um objeto. O blob com os dados da imagem SVG é o valor, e o tipo do blob ('image/svg+xml', neste caso) é a chave.

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);
  }
});

Colar uma imagem SVG

Para colar uma imagem SVG, leia o ClipboardItem de volta da área de transferência e peça o tipo desejado (neste caso, 'image/svg+xml') com o método getType(). Isso retorna um blob que, depois de convertido em um URL de blob, pode ser atribuído ao atributo src de um <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;
});

Limpeza

O SVG é um formato poderoso que, por exemplo, permite scripts incorporados. Isso pode ser perigoso quando o usuário cola conteúdo de fontes desconhecidas. Por isso, o navegador executa uma etapa de limpeza. Quando os dados são copiados, a API Async Clipboard produz um documento SVG bem formado e o grava na área de transferência. Quando os dados são colados, um fragmento SVG estritamente processado é produzido pelo analisador de fragmentos. Portanto, antes da operação de colagem, os atributos do manipulador de eventos onclick ainda estão lá, mas, ao colar, eles são removidos.

App Clipboard Viewer no macOS inspecionando o conteúdo da área de transferência. Ele mostra
que os atributos do listener de eventos onclick no SVG ainda estão lá.
App Clipboard Viewer no macOS inspecionando o conteúdo da área de transferência. Ele mostra que os atributos do listener de eventos onclick no SVG ainda estão lá.

Demonstração

Confira como copiar e colar SVGs na demonstração no Glitch. Confira o código-fonte para saber como ele funciona. Tente clicar em qualquer um dos círculos antes e depois de copiar e colar. Depois de colar, os atributos do gerenciador de eventos onclick potencialmente perigosos são removidos.

Agradecimentos

O suporte SVG para a API Async Clipboard no Chromium foi implementado pela equipe do Microsoft Edge. Esta postagem foi revisada por Rachel Andrew e Anupam Snigdha.