Deskripsi
Gunakan chrome.scripting API untuk menjalankan skrip dalam berbagai konteks.
Izin
scriptingKetersediaan
Manifes
Untuk menggunakan browser.scripting API, deklarasikan izin "scripting" di manifes serta izin host untuk halaman yang akan diinjeksikan skrip. Gunakan kunci "host_permissions" atau izin "activeTab", yang memberikan izin host sementara. Contoh berikut menggunakan izin activeTab.
{
"name": "Scripting Extension",
"manifest_version": 3,
"permissions": ["scripting", "activeTab"],
...
}
Konsep dan penggunaan
Anda dapat menggunakan browser.scripting API untuk memasukkan JavaScript dan CSS ke
situs. Hal ini mirip dengan yang dapat Anda lakukan dengan skrip
konten. Namun, dengan menggunakan namespace browser.scripting, ekstensi
dapat membuat keputusan saat runtime.
Target injeksi
Anda dapat menggunakan parameter target untuk menentukan target yang akan diinjeksikan JavaScript atau CSS.
Satu-satunya kolom yang wajib diisi adalah tabId. Secara default, injeksi akan berjalan di
frame utama tab yang ditentukan.
function getTabId() { ... }
browser.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("script injected"));
Untuk menjalankan di semua frame tab yang ditentukan, Anda dapat menetapkan boolean allFrames
ke true.
function getTabId() { ... }
browser.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
files : [ "script.js" ],
})
.then(() => console.log("script injected in all frames"));
Anda juga dapat memasukkan ke dalam frame tertentu dari tab dengan menentukan ID frame
individual. Untuk mengetahui informasi selengkapnya tentang ID frame, lihat browser.webNavigation
API.
function getTabId() { ... }
browser.scripting
.executeScript({
target : {tabId : getTabId(), frameIds : [ frameId1, frameId2 ]},
files : [ "script.js" ],
})
.then(() => console.log("script injected on target frames"));
Kode yang dimasukkan
Ekstensi dapat menentukan kode yang akan dimasukkan melalui file eksternal atau variabel runtime.
File
File ditentukan sebagai string yang merupakan jalur yang terkait dengan direktori root ekstensi. Kode berikut akan memasukkan file script.js ke dalam frame utama tab.
function getTabId() { ... }
browser.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("injected script file"));
Fungsi runtime
Saat memasukkan JavaScript dengan scripting.executeScript(), Anda dapat menentukan
fungsi yang akan dieksekusi, bukan file. Fungsi ini harus berupa variabel fungsi yang tersedia untuk konteks ekstensi saat ini.
function getTabId() { ... }
function getTitle() { return document.title; }
browser.scripting
.executeScript({
target : {tabId : getTabId()},
func : getTitle,
})
.then(() => console.log("injected a function"));
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor() {
document.body.style.backgroundColor = getUserColor();
}
browser.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
})
.then(() => console.log("injected a function"));
Anda dapat mengatasi masalah ini dengan menggunakan properti args:
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor(backgroundColor) {
document.body.style.backgroundColor = backgroundColor;
}
browser.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
args : [ getUserColor() ],
})
.then(() => console.log("injected a function"));
String runtime
Jika memasukkan CSS dalam halaman, Anda juga dapat menentukan string yang akan digunakan di properti css. Opsi ini hanya tersedia untuk scripting.insertCSS(); Anda tidak dapat mengeksekusi string menggunakan scripting.executeScript().
function getTabId() { ... }
const css = "body { background-color: red; }";
browser.scripting
.insertCSS({
target : {tabId : getTabId()},
css : css,
})
.then(() => console.log("CSS injected"));
Menangani hasil
Hasil eksekusi JavaScript diteruskan ke ekstensi. Satu hasil disertakan per frame. Frame utama dijamin menjadi indeks pertama dalam array yang dihasilkan; semua frame lainnya berada dalam urutan non-deterministik.
function getTabId() { ... }
function getTitle() { return document.title; }
browser.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : getTitle,
})
.then(injectionResults => {
for (const {frameId, result} of injectionResults) {
console.log(`Frame ${frameId} result:`, result);
}
});
scripting.insertCSS() tidak menampilkan hasil apa pun.
Promise
Jika nilai yang dihasilkan dari eksekusi skrip adalah promise, Chrome akan menunggu promise diselesaikan dan menampilkan nilai yang dihasilkan.
function getTabId() { ... }
async function addIframe() {
const iframe = document.createElement("iframe");
const loadComplete =
new Promise(resolve => iframe.addEventListener("load", resolve));
iframe.src = "https://example.com";
document.body.appendChild(iframe);
await loadComplete;
return iframe.contentWindow.document.title;
}
browser.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : addIframe,
})
.then(injectionResults => {
for (const frameResult of injectionResults) {
const {frameId, result} = frameResult;
console.log(`Frame ${frameId} result:`, result);
}
});
Contoh
Membatalkan pendaftaran semua skrip konten dinamis
Cuplikan berikut berisi fungsi yang membatalkan pendaftaran semua skrip konten dinamis yang telah didaftarkan ekstensi sebelumnya.
async function unregisterAllDynamicContentScripts() {
try {
const scripts = await browser.scripting.getRegisteredContentScripts();
const scriptIds = scripts.map(script => script.id);
return browser.scripting.unregisterContentScripts({ ids: scriptIds });
} catch (error) {
const message = [
"An unexpected error occurred while",
"unregistering dynamic content scripts.",
].join(" ");
throw new Error(message, {cause : error});
}
}
Untuk mencoba browser.scripting API,
instal contoh pembuatan skrip dari repositori contoh ekstensi Chrome.
Jenis
ContentScriptFilter
Properti
-
ids
string[] opsional
Jika ditentukan,
getRegisteredContentScriptshanya akan menampilkan skrip dengan ID yang ditentukan dalam daftar ini.
CSSInjection
Properti
-
css
string opsional
String yang berisi CSS yang akan dimasukkan. Hanya salah satu dari
filesdancssyang harus ditentukan. -
file
string[] opsional
Jalur file CSS yang akan dimasukkan, relatif terhadap direktori root ekstensi. Hanya salah satu dari
filesdancssyang harus ditentukan. -
asal
StyleOrigin opsional
Asal gaya untuk injeksi. Default-nya adalah
'AUTHOR'. -
target
Detail yang menentukan target untuk menyisipkan CSS.
ExecutionWorld
Lingkungan JavaScript tempat skrip akan dieksekusi.
Enum
"ISOLATED"
Menentukan dunia terisolasi, yang merupakan lingkungan eksekusi unik untuk ekstensi ini.
"MAIN"
Menentukan dunia utama DOM, yang merupakan lingkungan eksekusi yang digunakan bersama dengan JavaScript halaman host.
InjectionResult
Properti
-
documentId
string
Chrome 106+ browser.* sejak Chrome 148Dokumen yang terkait dengan injeksi.
-
frameId
angka
Chrome 90+ browser.* sejak Chrome 148Frame yang terkait dengan injeksi.
-
hasil
opsional apa pun
Hasil eksekusi skrip.
InjectionTarget
Properti
-
allFrames
boolean opsional
Apakah skrip harus dimasukkan ke dalam semua frame dalam tab. Nilai defaultnya adalah false (salah). Nilai ini tidak boleh benar jika
frameIdsditentukan. -
documentIds
string[] opsional
Chrome 106+ browser.* sejak Chrome 148ID documentId tertentu yang akan diinjeksikan. Ini tidak boleh ditetapkan jika
frameIdsditetapkan. -
frameIds
number[] opsional
ID frame tertentu yang akan diinjeksikan.
-
tabId
angka
ID tab tempat injeksi akan dilakukan.
RegisteredContentScript
Properti
-
allFrames
boolean opsional
Jika ditentukan true, skrip akan dimasukkan ke semua frame, meskipun frame tersebut bukan frame paling atas di tab. Setiap frame diperiksa secara independen untuk persyaratan URL; skrip konten tidak akan dimasukkan ke dalam frame turunan jika persyaratan URL tidak terpenuhi. Defaultnya adalah false, yang berarti hanya frame teratas yang dicocokkan.
-
css
string[] opsional
Daftar file CSS yang akan dimasukkan ke halaman yang cocok. Skrip ini dimasukkan sesuai urutan kemunculannya dalam array ini, sebelum DOM dibuat atau ditampilkan untuk halaman.
-
excludeMatches
string[] opsional
Mengecualikan halaman yang seharusnya disisipi skrip konten ini. Lihat Pola Pencocokan untuk mengetahui detail selengkapnya tentang sintaksis string ini.
-
id
string
ID skrip konten, yang ditentukan dalam panggilan API. Tidak boleh diawali dengan '_' karena dicadangkan sebagai awalan untuk ID skrip yang dihasilkan.
-
js
string[] opsional
Daftar file JavaScript yang akan dimasukkan ke halaman yang cocok. Elemen ini dimasukkan sesuai urutan kemunculannya dalam array ini.
-
matchOriginAsFallback
boolean opsional
Chrome 119+ browser.* sejak Chrome 148Menunjukkan apakah skrip dapat dimasukkan ke dalam frame yang URL-nya berisi skema yang tidak didukung; khususnya: about:, data:, blob:, atau filesystem:. Dalam kasus ini, origin URL akan diperiksa untuk menentukan apakah skrip harus dimasukkan. Jika origin adalah
null(seperti halnya untuk URL data:), origin yang digunakan adalah frame yang membuat frame saat ini atau frame yang memulai navigasi ke frame ini. Perhatikan bahwa ini mungkin bukan frame induk. -
cocok
string[] opsional
Menentukan halaman tempat skrip konten ini akan dimasukkan. Lihat Pola Pencocokan untuk mengetahui detail selengkapnya tentang sintaksis string ini. Harus ditentukan untuk
registerContentScripts. -
persistAcrossSessions
boolean opsional
Menentukan apakah skrip konten ini akan dipertahankan ke sesi mendatang. Nilai defaultnya adalah benar (true).
-
runAt
RunAt opsional
Menentukan kapan file JavaScript dimasukkan ke halaman web. Nilai yang direkomendasikan dan default adalah
document_idle. -
dunia
ExecutionWorld opsional
Chrome 102+ browser.* sejak Chrome 148"World" JavaScript untuk menjalankan skrip. Default-nya adalah
ISOLATED.
ScriptInjection
Properti
-
args
any[] opsional
Chrome 92+ browser.* sejak Chrome 148Argumen yang akan diteruskan ke fungsi yang disediakan. Hal ini hanya valid jika parameter
funcditentukan. Argumen ini harus dapat diserialisasi JSON. -
file
string[] opsional
Jalur file JS atau CSS yang akan diinjeksikan, relatif terhadap direktori root ekstensi. Hanya salah satu dari
filesataufuncyang harus ditentukan. -
injectImmediately
boolean opsional
Chrome 102+ browser.* sejak Chrome 148Apakah injeksi harus dipicu di target sesegera mungkin. Perhatikan bahwa hal ini tidak menjamin injeksi akan terjadi sebelum pemuatan halaman, karena halaman mungkin sudah dimuat saat skrip mencapai target.
-
target
Detail yang menentukan target tempat skrip akan dimasukkan.
-
dunia
ExecutionWorld opsional
Chrome 95+ browser.* sejak Chrome 148"World" JavaScript untuk menjalankan skrip. Default-nya adalah
ISOLATED. -
func
void optional
Chrome 92+ browser.* sejak Chrome 148Fungsi JavaScript yang akan dimasukkan. Fungsi ini akan diserialisasi, lalu dideserialisasi untuk injeksi. Artinya, parameter terikat dan konteks eksekusi apa pun akan hilang. Hanya salah satu dari
filesataufuncyang harus ditentukan.Fungsi
functerlihat seperti:() => {...}
StyleOrigin
Asal perubahan gaya. Lihat asal gaya untuk mengetahui info selengkapnya.
Enum
"AUTHOR"
"USER"
Metode
executeScript()
browser.scripting.executeScript(
injection: ScriptInjection,
): Promise<InjectionResult[]>
Memasukkan skrip ke dalam konteks target. Secara default, skrip akan dijalankan di document_idle, atau segera jika halaman sudah dimuat. Jika properti injectImmediately ditetapkan, skrip akan dimasukkan tanpa menunggu, meskipun halaman belum selesai dimuat. Jika skrip dievaluasi ke promise, browser akan menunggu promise diselesaikan dan menampilkan nilai yang dihasilkan.
Parameter
-
injeksi
Detail skrip yang akan dimasukkan.
Hasil
-
Promise<InjectionResult[]>
Chrome 90+ browser.* sejak Chrome 148Menampilkan Promise yang di-resolve setelah penyisipan selesai. Array yang dihasilkan berisi hasil eksekusi untuk setiap frame tempat injeksi berhasil.
getRegisteredContentScripts()
browser.scripting.getRegisteredContentScripts(
filter?: ContentScriptFilter,
): Promise<RegisteredContentScript[]>
Menampilkan semua skrip konten yang terdaftar secara dinamis untuk ekstensi ini yang cocok dengan filter yang diberikan.
Parameter
-
filter
ContentScriptFilter opsional
Objek untuk memfilter skrip ekstensi yang terdaftar secara dinamis.
Hasil
-
Promise<RegisteredContentScript[]>
insertCSS()
browser.scripting.insertCSS(
injection: CSSInjection,
): Promise<void>
Menyisipkan stylesheet CSS ke dalam konteks target. Jika beberapa frame ditentukan, injeksi yang tidak berhasil akan diabaikan.
Parameter
-
injeksi
Detail gaya yang akan disisipkan.
Hasil
-
Promise<void>
Chrome 90+ browser.* sejak Chrome 148Menampilkan Promise yang di-resolve setelah penyisipan selesai.
registerContentScripts()
browser.scripting.registerContentScripts(
scripts: RegisteredContentScript[],
): Promise<void>
Mendaftarkan satu atau beberapa skrip konten untuk ekstensi ini.
Parameter
-
skrip
Berisi daftar skrip yang akan didaftarkan. Jika terjadi error selama penguraian skrip/validasi file, atau jika ID yang ditentukan sudah ada, tidak ada skrip yang akan didaftarkan.
Hasil
-
Promise<void>
Menampilkan Promise yang di-resolve setelah skrip didaftarkan sepenuhnya atau ditolak jika terjadi error.
removeCSS()
browser.scripting.removeCSS(
injection: CSSInjection,
): Promise<void>
Menghapus stylesheet CSS yang sebelumnya disisipkan oleh ekstensi ini dari konteks target.
Parameter
-
injeksi
Detail gaya yang akan dihapus. Perhatikan bahwa properti
css,files, danoriginharus sama persis dengan stylesheet yang disisipkan melaluiinsertCSS. Mencoba menghapus stylesheet yang tidak ada tidak akan berpengaruh.
Hasil
-
Promise<void>
Menampilkan Promise yang di-resolve setelah penghapusan selesai.
unregisterContentScripts()
browser.scripting.unregisterContentScripts(
filter?: ContentScriptFilter,
): Promise<void>
Membatalkan pendaftaran skrip konten untuk ekstensi ini.
Parameter
-
filter
ContentScriptFilter opsional
Jika ditentukan, hanya membatalkan pendaftaran skrip konten dinamis yang cocok dengan filter. Jika tidak, semua skrip konten dinamis ekstensi tidak akan terdaftar.
Hasil
-
Promise<void>
Menampilkan Promise yang di-resolve setelah skrip dibatalkan pendaftarannya atau ditolak jika terjadi error.
updateContentScripts()
browser.scripting.updateContentScripts(
scripts: RegisteredContentScript[],
): Promise<void>
Mengupdate satu atau beberapa skrip konten untuk ekstensi ini.
Parameter
-
skrip
Berisi daftar skrip yang akan diperbarui. Properti hanya diperbarui untuk skrip yang ada jika ditentukan dalam objek ini. Jika terjadi error selama penguraian skrip/validasi file, atau jika ID yang ditentukan tidak sesuai dengan skrip yang terdaftar sepenuhnya, tidak ada skrip yang akan diperbarui.
Hasil
-
Promise<void>
Menampilkan Promise yang akan diselesaikan setelah skrip diperbarui atau ditolak jika terjadi error.