Obsługa SVG dla interfejsu Async Clipboard API

Interfejs Clipboard interfejsu Async Clipboard API zapewnia dostęp do odczytu i zapisu do schowka systemowego. Dzięki temu aplikacja internetowa może implementować funkcje wycinania, kopiowania i wklejania. Dane ze schowka możesz wkleić do aplikacji, wywołując metodę read(), a dane ze schowka możesz skopiować, wywołując metodę write(). Oprócz tekstu, obrazów w formacie Portable Network Graphics (PNG), wyczyszczonego i nieoczyszczonego kodu HTML oraz niestandardowych formatów internetowych interfejs Async Clipboard API obsługuje teraz też kopiowanie i wklejanie obrazów SVG, co oznacza, że możesz w końcu łatwiej współpracować z oprogramowaniem do edycji obrazów, które obsługuje format SVG, kopiując i wklejając obrazy SVG jako obrazy zamiast tekstu lub używając niestandardowych rozwiązań.

Obsługa wykrywania funkcji w pliku SVG

Wykrywanie obsługi obrazów SVG (i dowolnego innego typu MIME) przez wywołanie metody static ClipboardItem.supports() z przekazanym żądanym typem 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 pole ClipboardItem obiektem. Blob z danymi obrazu SVG jest wartością, a jego typ (w tym przypadku 'image/svg+xml') jest kluczem.

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 bufora i uzyskaj żądany typ (w tym przypadku 'image/svg+xml') za pomocą metody getType(). Zwraca on bloba, który po przekonwertowaniu na adres URL bloba może zostać przypisany do atrybutu src obiektu <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;
});

Sanitization

SVG to zaawansowany format, który umożliwia na przykład umieszczanie skryptów. Może to być niebezpieczne, gdy użytkownik wklei treści z nieznanych źródeł, dlatego przeglądarka wykonuje proces sterylizacji. Gdy dane zostaną skopiowane, interfejs Async Clipboard API wygeneruje poprawnie sformatowany dokument SVG, a następnie zapisze go na schowek. Gdy wklejasz dane, parsujący fragmenty parsuje fragment SVG. Dlatego przed operacją wklejania atrybuty onclick nadal są obecne, ale po wklejeniu zostają usunięte.

Aplikacja Clipboard Viewer w systemie macOS wyświetlająca zawartość schowka. Widać, że atrybuty onclick listener w pliku SVG są nadal obecne.
Aplikacja Clipboard Viewer w systemie macOS wyświetlająca zawartość schowka. Pokazuje, że atrybuty detektora zdarzenia onclick w pliku SVG są nadal obecne.

Prezentacja

Dowiedz się więcej o kopiowaniu i wklejaniu plików SVG z prezentacji na Glitch. Aby zobaczyć, jak to działa, wyświetl kod źródłowy. Przed i po skopiowaniu i wklejeniu danych kliknij dowolne kółko. Po wklejeniu potencjalnie niebezpieczne atrybuty onclick eventhandler zostaną usunięte.

Podziękowania

Obsługa SVG dla interfejsu Async Clipboard API w Chromium została zaimplementowana przez zespół Microsoft Edge. Ten post został sprawdzony przez Rachel Andrew i Anupama Snigdha.