การรองรับ SVG สำหรับ Async Clipboard API

Clipboard อินเทอร์เฟซของ Async Clipboard API ให้สิทธิ์การอ่านและเขียนเนื้อหาในคลิปบอร์ดของระบบ ซึ่งช่วยให้เว็บแอปพลิเคชันใช้ฟีเจอร์ตัด คัดลอก และวางได้ คุณสามารถวางข้อมูลจากคลิปบอร์ดลงในแอปพลิเคชันได้โดยเรียกใช้เมธอด read() และคัดลอกข้อมูลลงในคลิปบอร์ดได้โดยเรียกใช้เมธอด write() นอกจากข้อความแล้ว Async Clipboard API ยังรองรับการคัดลอกและวางรูปภาพ SVG ด้วย ซึ่งหมายความว่าตอนนี้คุณสามารถโต้ตอบกับซอฟต์แวร์แก้ไขรูปภาพที่จัดการกับ SVG ได้อย่างเป็นธรรมชาติมากขึ้นด้วยการคัดลอกและวางรูปภาพ SVG เป็นรูปภาพแทนที่จะเป็นข้อความหรือใช้วิธีแก้ปัญหาชั่วคราวที่ยุ่งยาก

การรองรับ SVG ของฟีเจอร์ตรวจจับ

ตรวจหาการรองรับรูปภาพ SVG (และประเภท MIME อื่นๆ) โดยการเรียกใช้เมธอด ClipboardItem.supports() แบบคงที่ โดยส่งประเภท MIME ที่ต้องการ

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

คัดลอกรูปภาพ SVG

คัดลอกรูปภาพ SVG โดยป้อนออบเจ็กต์ใน ClipboardItem Blob ที่มีข้อมูลรูปภาพ SVG เป็นค่า และประเภทของ Blob (ในกรณีนี้คือ '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);
  }
});

วางรูปภาพ SVG

หากต้องการวางรูปภาพ SVG ให้อ่าน ClipboardItem กลับจากคลิปบอร์ด แล้วรับประเภทที่ต้องการ (ในกรณีนี้คือ 'image/svg+xml') ด้วยเมธอด getType() ซึ่งจะแสดงผล Blob เมื่อแปลงเป็น URL ของ Blob แล้ว คุณจะกําหนดให้กับแอตทริบิวต์ src ของ <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;
});

สุขอนามัย

SVG เป็นรูปแบบที่มีประสิทธิภาพซึ่งอนุญาตให้ฝังสคริปต์ได้ เป็นต้น ซึ่งอาจเป็นอันตรายได้เมื่อผู้ใช้วางเนื้อหาจากแหล่งที่มาที่ไม่รู้จัก ดังนั้นเบราว์เซอร์จึงทำขั้นตอนสุขอนามัย เมื่อคัดลอกข้อมูล Async Clipboard API จะสร้างเอกสาร SVG ที่มีรูปแบบถูกต้อง แล้วเขียนลงในคลิปบอร์ด เมื่อวางข้อมูลแล้ว โปรแกรมแยกวิเคราะห์ข้อมูลจะสร้างข้อมูลโค้ด SVG ที่ประมวลผลอย่างเข้มงวด ดังนั้น ก่อนการทําการวาง แอตทริบิวต์ onclick event handler จะยังคงอยู่ แต่จะถูกนําออกเมื่อวาง

แอปเครื่องมือดูคลิปบอร์ดใน macOS กำลังตรวจสอบเนื้อหาในคลิปบอร์ด แสดงให้เห็นว่าแอตทริบิวต์ตัวรับเหตุการณ์ onclick ใน SVG ยังคงอยู่
แอปเครื่องมือดูคลิปบอร์ดใน macOS กำลังตรวจสอบเนื้อหาคลิปบอร์ด แสดงว่ายังคงมีแอตทริบิวต์ Listener เหตุการณ์ onclick ใน SVG

สาธิต

ดูการคัดลอกและวาง SVG ในเดโมบน Glitch ดูวิธีการทำงานของฟีเจอร์นี้ได้จากซอร์สโค้ด อย่าลืมลองคลิกวงกลมใดก็ได้ก่อนและหลังการคัดลอกและวาง หลังจากวางแล้ว ระบบจะนำแอตทริบิวต์ onclick event handler ที่อาจเป็นอันตรายออก

ขอขอบคุณ

ทีม Microsoft Edge เป็นผู้ติดตั้งใช้งานการรองรับ SVG สําหรับ Async Clipboard API ใน Chromium โพสต์นี้ผ่านการตรวจสอบโดย Rachel Andrew และ Anupam Snigdha