Supporto SVG per l'API Async Clipboard

L'interfaccia Clipboard dell'API Async Clipboard fornisce l'accesso in lettura e scrittura ai contenuti degli appunti di sistema. In questo modo, un'applicazione web può implementare le funzionalità di taglio, copia e incolla. Puoi incollare i dati dagli appunti in un'applicazione chiamando il metodo read() e copiare i dati negli appunti chiamando il metodo write(). Oltre al testo, alle immagini in formato Portable Network Graphics (PNG), al codice HTML sanificato e non e ai formati personalizzati web, l'API Clipboard asincrona ora supporta anche la copia e il colla delle immagini SVG, il che significa che finalmente puoi interagire con il software di modifica delle immagini che gestisce gli SVG in modo più naturale copiando e incollando le immagini SVG come immagini anziché come testo o utilizzando soluzioni alternative poco efficaci.

Supporto di SVG per il rilevamento di funzionalità

Rileva il supporto delle immagini SVG (e di qualsiasi altro tipo MIME) chiamando il metodo statico ClipboardItem.supports(), passandogli il tipo MIME desiderato.

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

Copiare un'immagine SVG

Copia un'immagine SVG compilando il ClipboardItem con un oggetto. Il blob con i dati dell'immagine SVG è il valore e il tipo del blob (in questo caso 'image/svg+xml') come chiave.

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

Incollare un'immagine SVG

Per incollare un'immagine SVG, leggi ClipboardItem dalla clipboard e recupera il tipo desiderato (in questo caso 'image/svg+xml') con il metodo getType(). Viene restituito un blob che, una volta convertito in un URL del blob, puoi assegnare all'attributo src di un <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;
});

Purificazione

SVG è un formato potente che, ad esempio, consente gli script incorporati. Ciò può essere pericoloso quando l'utente incolla contenuti da origini sconosciute, pertanto il browser esegue un passaggio di sanificazione. Quando i dati vengono copiati, l'API Async Clipboard produce un documento SVG ben formato e lo scrive negli appunti. Quando i dati vengono incollati, l'analizzatore dei frammenti produce un frammento SVG sottoposto a un'elaborazione rigorosa. Pertanto, prima dell'operazione di incollaggio, gli attributi del gestore eventi onclick sono ancora presenti, ma vengono rimossi al momento dell'incollaggio.

App Clipboard Viewer su macOS che controlla i contenuti degli appunti. Mostra
che gli attributi dell&#39;ascoltatore di eventi onclick in SVG sono ancora presenti.
App Clipboard Viewer su macOS che controlla i contenuti degli appunti. Mostra che gli attributi dell'ascoltatore di eventi onclick in SVG sono ancora presenti.

Demo

Scopri come copiare e incollare gli SVG nella demo su Glitch. Visualizza il codice sorgente per scoprire come funziona. Assicurati di provare a fare clic su uno dei cerchi prima e dopo la copia e l'incollaggio. Dopo l'incollaggio, gli attributi di gestore degli eventi onclick potenzialmente pericolosi vengono rimossi.

Ringraziamenti

Il supporto SVG per l'API Async Clipboard in Chromium è stato implementato dal team di Microsoft Edge. Questo post è stato esaminato da Rachel Andrew e Anupam Snigdha.