Formati web personalizzati per l'API Async Clipboard

Finora, l'API Async Clipboard supportava un insieme limitato di tipi MIME da copiare e incollare dagli appunti di sistema, in particolare: text/plain, text/html e image/png. Il browser in genere esegue questa operazione, ad esempio, per rimuovere gli elementi script o i link javascript: incorporati da una stringa HTML oppure per impedire attacchi di tipo bomba di decompressione PNG.

In alcuni casi, tuttavia, può essere utile salvare negli appunti contenuti non sottoposti a sanitizzazione:

  • Situazioni in cui l'applicazione si occupa della sanitizzazione stessa.
  • Situazioni in cui è fondamentale che i dati copiati siano identici a quelli incollati.

In questi casi, l'API Async Clipboard ora supporta formati personalizzati per il web che consentono agli sviluppatori di scrivere dati arbitrari negli appunti.

Supporto del browser

L'API Async Clipboard in sé con supporto di immagini è supportata a partire da Chromium 76. I formati web personalizzati per l'API Async Clipboard sono supportati su desktop e su Chromium per dispositivi mobili a partire dalla versione 104.

Scrittura di formati personalizzati per il web negli appunti

La scrittura di formati personalizzati per il web negli appunti è quasi identica alla scrittura di formati corretti, tranne per il requisito di anteporre la stringa "web " (incluso lo spazio finale) al tipo MIME del blob.

// Fetch remote JPEG and GIF images and obtain their blob representations.
const [jpegBlob, gifBlob] = await Promise.all([
  fetch('image.jpg').then((response) => response.blob()),
  fetch('image.gif').then((response) => response.blob()),
]);

try {
  // Write the image data to the clipboard, prepending the blobs' actual
  // types (`"image/jpeg"` and "image/gif") with the string `"web "`, so
  // they become `"web image/jpeg"` and `"web image/gif"` respectively.
  // The code elegantly makes use of computed property names:
  // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names.
  const clipboardItem = new ClipboardItem({
    [`web ${jpegBlob.type}`]: jpegBlob,
    [`web ${gifBlob.type}`]: gifBlob,
  });
  await navigator.clipboard.write([clipboardItem]);
} catch (err) {
  console.error(err.name, err.message);
}

Lettura di formati personalizzati per il web dagli appunti

Come per la scrittura, la lettura di formati personalizzati per il web dagli appunti è quasi identica alla lettura di formati personalizzati. L'unica differenza è che l'app ora deve cercare gli elementi negli appunti il cui tipo inizia con "web ".

try {
  // Iterate over all clipboard items.
  const clipboardItems = await navigator.clipboard.read();
  for (const clipboardItem of clipboardItems) {
    for (const type of clipboardItem.types) {
      // Discard any types that are not web custom formats.
      if (!type.startsWith('web ')) {
        continue;
      }
      const blob = await clipboardItem.getType(type);
      // Sanitize the blob if you need to, then process it in your app.
    }
  }
} catch (err) {
  console.error(err.name, err.message);
}

Interoperabilità con app specifiche per piattaforma

I formati personalizzati per il web come web image/jpeg non sono compresi dalle tipiche applicazioni specifiche della piattaforma (dato che si aspettano image/jpeg). Nel tempo, si prevede che le app preoccupate aggiungano il supporto per questi formati, ad esempio un'attivazione, se i loro sviluppatori ritengono che il supporto per formati personalizzati per il web sia pertinente per i loro utenti. Negli appunti del sistema operativo, i vari formati sono disponibili in più formati pronti per l'uso, come si può vedere nello screenshot per macOS riportato di seguito.

Aspettativa di appunti su macOS che mostra una mappa in formato personalizzato che elenca due formati personalizzati per il web.

Demo

Puoi provare la demo di seguito e visualizzare il codice sorgente per vedere come funziona.

Ringraziamenti

Questo articolo è stato recensito da Joe Medley e François Beaufort. Immagine hero di Neon Tommy, utilizzata con licenza CC BY-SA 2.0.