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 cortar, copiar e colar. Você pode 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 higienizado e não higienizado e formatos personalizados da Web, a API Async Clipboard agora também oferece suporte à cópia e colagem de imagens SVG. Isso significa que você pode interagir com softwares de edição de imagens que trabalham com SVGs de maneira mais natural, copiando e colando imagens SVG como imagens em vez de texto ou usando soluções alternativas.

Detectar suporte a SVG

Para detectar a compatibilidade com imagens SVG (e qualquer outro tipo MIME), chame o método estático ClipboardItem.supports(), 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 (ou seja, '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 receba o tipo desejado (ou seja, 'image/svg+xml' neste caso) 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 eficiente que permite, por exemplo, scripts incorporados. Isso pode ser perigoso quando o usuário cola conteúdo de fontes desconhecidas, então 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 são removidos ao colar.

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

Demonstração

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

Agradecimentos

O suporte a 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.