Formatos web personalizados para la API de Async Clipboard

Hasta ahora, la API de Async Clipboard admitía un conjunto limitado de Tipos de MIME que se deben copiar y pegar desde el portapapeles del sistema, específicamente: text/plain, text/html y image/png. El navegador generalmente depura esto para, por ejemplo, quitar los elementos Elementos script o vínculos javascript: de una cadena HTML, o bien para evitar el formato PNG bombas de descompresión.

Sin embargo, en algunos casos, puede resultar conveniente admitir contenido no depurado en el portapapeles:

  • Situaciones en las que la aplicación se ocupa de la limpieza
  • Situaciones en las que es fundamental que los datos copiados sean idénticos a los datos pegados.

Para tales casos, la API de Async Clipboard ahora admite formatos web personalizados que permiten a los desarrolladores escribir datos arbitrarios al portapapeles.

Navegadores compatibles

La API de Async Clipboard per se con compatibilidad con imágenes es compatible a partir de Chromium 76. Los formatos personalizados web para la API de Async Clipboard son compatibles con Chromium para computadoras y dispositivos móviles a partir de la versión 104.

Escribir formatos personalizados de la Web en el portapapeles

Escribir formatos personalizados web en el portapapeles es casi idéntico a escribir formatos depurados, excepto por el requisito para anteponer la cadena "web " (incluido el espacio final) al tipo de 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);
}

Leer formatos personalizados de la Web desde el portapapeles

Al igual que con la escritura, leer formatos personalizados de la Web desde el portapapeles es casi idéntico a leer formatos depurados. La única diferencia es que La app ahora debe buscar elementos del portapapeles cuyo tipo comience 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);
}

Interoperabilidad con apps específicas de la plataforma

Los formatos personalizados de la Web, como web image/jpeg, no son comunes que las aplicaciones comprendan (ya que esperarían image/jpeg). Con el tiempo, las apps afectadas se espera que se agregue compatibilidad con dichos formatos, como una opción si sus desarrolladores consideran la compatibilidad con personalizados para que sean relevantes para sus usuarios. En el portapapeles del sistema operativo, los diversos están presentes en múltiples formatos listos para el consumo, como se puede ver en el captura de pantalla para macOS.

Expector de portapapeles en macOS que muestra un mapa de formato personalizado en el que se enumeran dos formatos personalizados para la Web.

Demostración

Puedes probar la demostración que aparece a continuación y ver el código fuente para ver cómo funciona.

Agradecimientos

Joe Medley revisó este artículo y François Beaufort. Imagen hero de Neon Tommy, que se usa con una licencia CC BY-SA 2.0.