Formati web personalizzati per l'API Async Clipboard

Thomas Steiner
Thomas Steiner

Fino a questo momento, l'API Async Clipboard supportava un insieme limitato di tipi MIME da copiare e incollare negli appunti di sistema, in particolare: text/plain,text/html e image/png. In genere il browser sanifica questo comportamento, ad esempio per rimuovere gli elementi script o i link javascript: incorporati da una stringa HTML o per prevenire attacchi bomba di decompressione PNG.

In alcuni casi, però, può essere opportuno supportare i contenuti non sottoposti a sanificazione nella clipboard:

  • Situazioni in cui l'applicazione gestisce la sanificazione stessa.
  • Situazioni in cui è fondamentale che i dati copiati siano identici a quelli incollati.

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

Supporto browser

L'API Async Clipboard per se con il supporto delle immagini è supportata a partire da Chromium 76. I formati personalizzati web per l'API Async Clipboard sono supportati su Chromium per computer e dispositivi mobili a partire dalla versione 104.

Scrittura di formati web personalizzati negli appunti in corso...

La scrittura di formati personalizzati web negli appunti è quasi identica alla scrittura di formati sottoposti a sanificazione, 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 dei formati personalizzati web dagli appunti

Come per la scrittura, la lettura dei formati personalizzati web dagli appunti è quasi identica alla lettura dei formati sottoposti a sanificazione. L'unica differenza è che ora l'app deve cercare gli elementi della clipboard 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 della piattaforma

I formati personalizzati web come web image/jpeg non sono compresi dalle applicazioni specifiche per piattaforma (poiché si aspettano image/jpeg). Nel tempo, le app interessate dovrebbero aggiungere il supporto di questi formati come opzione se i relativi sviluppatori ritengono che il supporto dei formati personalizzati web sia pertinente per i loro utenti. Negli appunti del sistema operativo, i vari formati sono presenti in vari formati pronti per l'utilizzo, come si può vedere nello screenshot di macOS riportato di seguito.

Aspettatore di appunti su macOS che mostra una mappa dei formati personalizzati che elenca due formati personalizzati per il web.

Demo

Puoi provare la demo e visualizzare il codice sorgente per scoprire come funziona.

Ringraziamenti

Questo documento è stato esaminato da Joe Medley e François Beaufort.