อัปเดตรหัส

การอัปเดตที่ไม่เกี่ยวข้องกับปัญหาอื่นๆ

นี่เป็นส่วนแรกจาก 3 ส่วนที่อธิบายการเปลี่ยนแปลงที่จำเป็นสำหรับโค้ดที่ไม่ได้เป็นส่วนหนึ่งของ Service Worker ของส่วนขยาย ส่วนนี้มีไว้สำหรับการเปลี่ยนแปลงโค้ดที่จำเป็นซึ่งไม่เกี่ยวข้องกับปัญหาอื่นๆ 2 ส่วนถัดไปจะครอบคลุมการแทนที่คำขอเว็บที่ถูกบล็อกและการปรับปรุงความปลอดภัย

แทนที่ tabs.executeScript() ด้วย scripting.executeScript()

ในไฟล์ Manifest V3 executeScript() จะย้ายจาก tabs API ไปยัง scripting API ซึ่งต้องมีการเปลี่ยนแปลงสิทธิ์ในไฟล์ Manifest นอกเหนือจากการเปลี่ยนแปลงโค้ดจริง

สำหรับวิธี executeScript() คุณต้องมีสิ่งต่อไปนี้

  • สิทธิ์ "scripting"
  • สิทธิ์ของโฮสต์หรือสิทธิ์ "activeTab"

วิธีการ scripting.executeScript() คล้ายกับวิธีการทำงานของ tabs.executeScript() โดยมีความแตกต่างบางประการดังนี้

  • แม้ว่าเมธอดเก่าจะรับได้เพียงไฟล์เดียว แต่เมธอดใหม่จะรับอาร์เรย์ของไฟล์ได้
  • นอกจากนี้ คุณยังส่งออบเจ็กต์ ScriptInjection แทน InjectDetails ด้วย ทั้ง 2 อย่างนี้มีความแตกต่างกันหลายประการ เช่น ตอนนี้ระบบจะส่ง tabId เป็นสมาชิกของ ScriptInjection.target แทนที่จะเป็นอาร์กิวเมนต์เมธอด

ตัวอย่างแสดงวิธีดำเนินการ

Manifest V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

browser.tabs.executeScript(
  tab.id,
  {
    file: 'content-script.js'
  }
);

ในไฟล์สคริปต์เบื้องหลัง

Manifest V3
async function getCurrentTab()
let tab = await getCurrentTab();

browser.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['content-script.js']
});

ใน Service Worker ของส่วนขยาย

แทนที่ tabs.insertCSS() และ tabs.removeCSS() ด้วย scripting.insertCSS() และ scripting.removeCSS()

ใน Manifest V3, insertCSS() และ removeCSS() จะย้ายจาก tabs API ไปยัง scripting API ซึ่งต้องมีการเปลี่ยนแปลงสิทธิ์ในไฟล์ Manifest นอกเหนือจากการเปลี่ยนแปลงโค้ด ดังนี้

  • สิทธิ์ "scripting"
  • สิทธิ์ของโฮสต์หรือสิทธิ์ "activeTab"

ฟังก์ชันใน scripting API คล้ายกับฟังก์ชันใน tabs โดยมีความแตกต่างบางประการดังนี้

  • เมื่อเรียกใช้เมธอดเหล่านี้ คุณจะส่งออบเจ็กต์ CSSInjection แทน InjectDetails
  • ตอนนี้ระบบจะส่ง tabId เป็นสมาชิกของ CSSInjection.target แทนที่จะเป็นอาร์กิวเมนต์เมธอด

ตัวอย่างแสดงวิธีดำเนินการนี้สำหรับ insertCSS() ขั้นตอนสำหรับ removeCSS() จะเหมือนกัน

Manifest V2
browser.tabs.insertCSS(tabId, injectDetails, () => {
  // callback code
});

ในไฟล์สคริปต์เบื้องหลัง

Manifest V3
const insertPromise = await browser.scripting.insertCSS({
  files: ["style.css"],
  target: { tabId: tab.id }
});
// Remaining code. 

ใน Service Worker ของส่วนขยาย

แทนที่การดำเนินการในเบราว์เซอร์และการดำเนินการในหน้าเว็บด้วยการดำเนินการ

การดำเนินการของเบราว์เซอร์และการดำเนินการของหน้าเว็บเป็นแนวคิดที่แยกกันในไฟล์ Manifest V2 แม้ว่าทั้ง 2 จะเริ่มต้นด้วยบทบาทที่แตกต่างกัน แต่ความแตกต่างระหว่างทั้ง 2 ก็ลดลงเมื่อเวลาผ่านไป ใน Manifest V3 แนวคิดเหล่านี้จะรวมอยู่ใน Action API ซึ่งจะต้องทำการเปลี่ยนแปลงใน manifest.json และโค้ดส่วนขยายที่แตกต่างจากที่คุณใส่ไว้ในสคริปต์เบื้องหลังของไฟล์ Manifest V2

การดำเนินการใน Manifest V3 คล้ายกับการดำเนินการของเบราว์เซอร์มากที่สุด แต่ action API ไม่มี hide() และ show() เหมือนกับ pageAction หากยังต้องการการทำงานของหน้าเว็บ คุณสามารถจำลองการทำงานโดยใช้เนื้อหาที่ประกาศหรือเรียกใช้ enable() หรือ disable() ด้วยรหัสแท็บ

แทนที่ "browser_action" และ "page_action" ด้วย "action"

ใน manifest.json ให้แทนที่ช่อง "browser_action" และ "page_action" ด้วยช่อง "action" ดูข้อมูลอ้างอิงสำหรับข้อมูลเกี่ยวกับช่อง "action"

Manifest V2
{
  ...
  "page_action": { ... },
  "browser_action": {
    "default_popup": "popup.html"
   }
  ...
}
Manifest V3
{
  ...
  "action": {
    "default_popup": "popup.html"
  }

  ...
}

แทนที่ browserAction API และ pageAction API ด้วย action API

หาก Manifest V2 ใช้ browserAction และ pageAction API คุณควรใช้ action API แทน

Manifest V2
browser.browserAction.onClicked.addListener(tab => { ... });
browser.pageAction.onClicked.addListener(tab => { ... });
Manifest V3
browser.action.onClicked.addListener(tab => { ... });

แทนที่ Callback ด้วย Promise

ในไฟล์ Manifest V3 เมธอด API ของส่วนขยายจำนวนมากจะแสดงผลเป็น Promise Promise คือพร็อกซีหรือตัวยึดตำแหน่งสำหรับค่าที่แสดงผลโดยเมธอดแบบอะซิงโครนัส หากไม่เคยใช้ Promise คุณสามารถอ่านข้อมูลเกี่ยวกับ Promise ได้ใน MDN หน้านี้จะอธิบายสิ่งที่คุณจำเป็นต้องทราบเพื่อใช้ API เหล่านี้ในส่วนขยาย Chrome

หลายๆ เมธอดจะยังคงรองรับ Callback หลังจากเพิ่มการรองรับ Promise เพื่อให้เข้ากันได้แบบย้อนหลัง โปรดทราบว่าคุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ หากคุณส่ง Callback ฟังก์ชันจะไม่แสดงผล Promise และหากต้องการให้แสดงผล Promise ก็ไม่ต้องส่ง Callback ฟีเจอร์ API บางอย่าง เช่น Listener เหตุการณ์ จะยังคงต้องใช้ Callback หากต้องการตรวจสอบว่าเมธอดรองรับ Promise หรือไม่ ให้มองหาป้ายกำกับ "Promise" ในเอกสารอ้างอิง API

หากต้องการแปลงจาก Callback เป็น Promise ให้นำ Callback ออกและจัดการ Promise ที่แสดงผล ตัวอย่างด้านล่างนำมาจากตัวอย่างสิทธิ์ที่ไม่บังคับ โดยเฉพาะ newtab.js เวอร์ชัน Callback แสดงลักษณะการเรียกใช้ request() ของตัวอย่างด้วย Callback โปรดทราบว่าเวอร์ชัน Promise สามารถเขียนใหม่ได้ด้วย async และ await

การติดต่อกลับ
browser.permissions.request(newPerms, (granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});
Promise
const newPerms = { permissions: ['topSites'] };
browser.permissions.request(newPerms)
.then((granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});

แทนที่ฟังก์ชันที่คาดหวังบริบทพื้นหลังของไฟล์ Manifest V2

บริบทอื่นๆ ของส่วนขยายจะโต้ตอบกับ Service Worker ของส่วนขยายได้โดยใช้การส่งข้อความเท่านั้น ดังนั้น คุณจะต้องแทนที่การเรียกที่คาดหวังบริบทเบื้องหลัง โดยเฉพาะอย่างยิ่ง

  • browser.runtime.getBackgroundPage()
  • browser.extension.getBackgroundPage()
  • browser.extension.getExtensionTabs()

สคริปต์ส่วนขยายควรใช้การส่งข้อความเพื่อสื่อสารระหว่าง Service Worker กับส่วนอื่นๆ ของส่วนขยาย ปัจจุบันสามารถทำได้โดยใช้ sendMessage() และใช้ browser.runtime.onMessage ใน Service Worker ของส่วนขยาย ในระยะยาว คุณควรวางแผนที่จะแทนที่การเรียกเหล่านี้ด้วย postMessage() และเครื่องจัดการเหตุการณ์ข้อความของ Service Worker

แทนที่ API ที่ไม่รองรับ

เมธอดและพร็อพเพอร์ตี้ที่แสดงด้านล่างต้องมีการเปลี่ยนแปลงในไฟล์ Manifest V3

เมธอดหรือพร็อพเพอร์ตี้ของไฟล์ Manifest V2 แทนที่ด้วย
browser.extension.connect() browser.runtime.connect()
browser.extension.connectNative() browser.runtime.connectNative()
browser.extension.getExtensionTabs() browser.extension.getViews()
browser.extension.getURL() browser.runtime.getURL()
browser.extension.lastError ในกรณีที่เมธอดแสดงผลเป็น Promise ให้ใช้ promise.catch()
browser.extension.onConnect browser.runtime.onConnect
browser.extension.onConnectExternal browser.runtime.onConnectExternal
browser.extension.onMessage browser.runtime.onMessage
browser.extension.onRequest browser.runtime.onMessage
browser.extension.onRequestExternal browser.runtime.onMessageExternal
browser.extension.sendMessage() browser.runtime.sendMessage()
browser.extension.sendNativeMessage() browser.runtime.sendNativeMessage()
browser.extension.sendRequest() browser.runtime.sendMessage()
browser.runtime.onSuspend (สคริปต์เบื้องหลัง) ไม่รองรับใน Service Worker ของส่วนขยาย โปรดใช้เหตุการณ์เอกสาร beforeunload แทน
browser.tabs.getAllInWindow() browser.tabs.query()
browser.tabs.getSelected() browser.tabs.query()
browser.tabs.onActiveChanged browser.tabs.onActivated
browser.tabs.onHighlightChanged browser.tabs.onHighlighted
browser.tabs.onSelectionChanged browser.tabs.onActivated
browser.tabs.sendRequest() browser.runtime.sendMessage()
browser.tabs.Tab.selected browser.tabs.Tab.highlighted