Obsługa SVG dla interfejsu Async Clipboard API

ClipboardInterfejs interfejsu Async Clipboard API zapewnia dostęp do odczytu i zapisu zawartości schowka systemowego. Umożliwia to aplikacji internetowej implementowanie funkcji wycinania, kopiowania i wklejania. Dane ze schowka możesz wkleić do aplikacji, wywołując metodę read(), a dane do schowka możesz skopiować, wywołując metodę write(). Oprócz tekstu, obrazów w formacie PNG, oczyszczonego i nieoczyszczonego kodu HTML oraz niestandardowych formatów internetowych interfejs Async Clipboard API obsługuje teraz również kopiowanie i wklejanie obrazów SVG. Oznacza to, że możesz wreszcie w bardziej naturalny sposób korzystać z programów do edycji obrazów, które obsługują SVG, kopiując i wklejając obrazy SVG jako obrazy, a nie jako tekst, lub używając niezgrabnych obejść.

Wykrywanie obsługi SVG

Sprawdź, czy obrazy SVG (i inne typy MIME) są obsługiwane, wywołując statyczną metodę ClipboardItem.supports() i przekazując jej żądany typ MIME.

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

Kopiowanie obrazu SVG

Skopiuj obraz SVG, wypełniając element ClipboardItem obiektem. Wartością jest obiekt blob z danymi obrazu SVG, a kluczem jest typ obiektu blob (w tym przypadku 'image/svg+xml').

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

Wklejanie obrazu SVG

Aby wkleić obraz SVG, odczytaj ClipboardItem z schowka i uzyskaj żądany typ (w tym przypadku 'image/svg+xml') za pomocą metody getType(). Zwraca to obiekt blob, który po przekonwertowaniu na adres URL obiektu blob możesz przypisać do atrybutu src elementu <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;
});

Sanityzacja

SVG to zaawansowany format, który umożliwia na przykład osadzanie skryptów. Może to być niebezpieczne, gdy użytkownik wklei treść z nieznanych źródeł, dlatego przeglądarka przeprowadza proces oczyszczania. Gdy dane są kopiowane, interfejs Async Clipboard API tworzy prawidłowy dokument SVG, a następnie zapisuje go w schowku. Po wklejeniu danych parser fragmentów generuje ściśle przetworzony fragment SVG. Dlatego przed operacją wklejania atrybuty onclick obsługi zdarzeń są nadal obecne, ale po wklejeniu zostają usunięte.

Aplikacja Podgląd schowka w systemie macOS sprawdzająca zawartość schowka. Pokazuje to, że atrybuty odbiornika zdarzeń onclick w SVG nadal istnieją.
Aplikacja Podgląd schowka w systemie macOS sprawdzająca zawartość schowka. Pokazuje to, że atrybuty detektora zdarzeń onclick w SVG nadal istnieją.

Prezentacja

Wypróbuj kopiowanie i wklejanie plików SVG w wersji demonstracyjnej. Wyświetl kod źródłowy, aby zobaczyć, jak to działa. Spróbuj kliknąć dowolne kółko przed skopiowaniem i wklejeniem oraz po tych czynnościach. Po wklejeniu potencjalnie niebezpieczne atrybuty obsługi zdarzeń onclick zostaną usunięte.

Podziękowania

Obsługę SVG w asynchronicznym interfejsie API schowka w Chromium wdrożył zespół Microsoft Edge. Ten post został sprawdzony przez Rachel Andrew i Anupam Snigdha.