[Chrome Extension] API 筆記
keywords: Chrome Extension
- 🔖 Develop Extensions:列出許多開發 Extension 時會用到的 API。
- 🔖 Manifest file format:列出所有 manifest 中可用的 API。
Manifest
Manifest file format @ Chrome Extension
// manifest.json
{
"name": "PJCHENder Extension",
"version": "1.0",
"description": "PJCHENder tester client tool for recording.",
// Extension 要正常運作一定需要的權限
"permissions": [
"storage",
"declarativeContent",
"alarms",
"notifications",
"activeTab", // 取得當前 active tab 的存取權限
"tabs", // 新增、修改還重新排序頁籤
"http://localhost:3000/*" // 具有符合該網址 tab 的存取權限(可以對它使用 executeScript)
],
// 使用 host permission 除了可以 read 和 query tab 中的資料外,還可 inject scripts
"host_permissions": ["https://developer.chrome.com/*"],
// 使用者可以自己選擇要不要提供
"optional_permissions": ["topSites", "http://www.developer.chrome.com/*"],
"background": {
"scripts": ["background.js"],
"persistent": false
},
// 如果要從 webpack 傳送 message 到 extension 內
"externally_connectable": {
"matches": ["http://localhost:3000/*"]
},
// 如果要讓 webpage 可以存取 extension 內的資源
"web_accessible_resources": ["images/*"],
// extension 在 toolbar 上的 icon
"browser_action": {
"default_icon": {
"16": "images/logo@16.png",
"32": "images/logo@32.png",
"48": "images/logo@48.png",
"128": "images/logo@128.png"
},
"default_title": "__MSG_tooltip__", // 搭配 i18n 使用 __MSG_foobar__
"default_popup": "popup.html"
},
// extension 的選項頁
"options_page": "options.html",
"icons": {
"16": "images/logo@16.png",
"32": "images/logo@32.png",
"48": "images/logo@48.png",
"128": "images/logo@128.png"
},
// 搭配 i18n
"default_locale": "en",
// 如果有要使用 declarative content script(到特定頁面自動載入 contentScript)
"content_scripts": [
{
"matches": ["http://*.nytimes.com/*"],
"exclude_matches": ["*://*/*business*"],
"include_globs": ["*nytimes.com/???s/*"],
"exclude_globs": ["*science*"],
"run_at": "document_idle", // 決定 JavaScript 注入的時間,預設是 document_idle
"css": ["myStyles.css"],
"js": ["contentScript.js"]
}
],
"content_security_policy": "default-src 'none'; style-src 'self'; script-src 'self'; connect-src https://maps.googleapis.com; img-src https://maps.googleapis.com",
"manifest_version": 2
}
Manifest File Format @ Chrome Developer
Permission
- 常用的權限項目 Permissions @ Chrome Developer
- Declare Permissions and Warn Users @ Chrome Developer
使用下述功能前,需要先在 manifest.json
中開啟權限:
// manifest.json
{
...
"permissions": [
"https://*/*",
"http://*/*",
"activeTab",
"declarativeContent",
"storage",
"notifications",
"alarms",
],
...
}
notifications
keywords: notifications.create()
, notifications.onButtonClicked.addListener()
// background.js
// 推播 notification
chrome.notifications.create({
type: 'basic',
iconUrl: stayHydratedPNG,
title: 'Time to Hydrate',
message: "Everyday I'm Guru'!",
// notification 上的按鈕
buttons: [{ title: 'Keep it Flowing.' }],
priority: 0,
});
// 監聽 notification 上的 button 如果被點擊
chrome.notifications.onButtonClicked.addListener(function () {
// ...
});
alarms:鬧鐘與計時器
keywords: alarms.create()
, alarms.clearAll()
, alarms.onAlarm.addListener()
// popup.js
chrome.alarms.create({ delayInMinutes: minutes }); // 設定鬧鐘時間
chrome.alarms.clearAll(); // 取消所有計時器
// background.js
// 計時器時間到時發送推播
chrome.alarms.onAlarm.addListener(function() {
chrome.notifications.create(...);
});
storage
keywords: storage.sync.get()
, storage.sync.set()
// 把特定的 key-value 存在 chrome storage 中
chrome.storage.sync.set({ color: '#3aa757' }, function () {
console.log('The color is green.');
});
// 把特定的 key-value 從 chrome storage 中取出
// get 的內容可以是字串或陣列
chrome.storage.sync.get(['color', 'name'], function (data) {
console.log('data.color', data.color);
});
// 列出所有儲存在 chrome.storage 的內容
chrome.storage.sync.get(null, function (data) {
console.info(data);
});
// 移除 chrome.storage 的內 容
// remove 的內容可以是字串或陣列
chrome.storage.sync.remove('color', function (data) {
console.info(data);
});
// 清除 chrome.storage 的所有內容
chrome.storage.local.set({ variable: variableInformation });
declarativeContents
keywords: declarativeContents, declarativeContent.onPageChanged
, declarativeContent.PageStateMatcher()
- declarativeContent @ Chrome Extension
- chrome.events @ Chrome Extension
透過 Declarative Content API 可以在不需要 host permission 或注入 content script 的情況下,根據頁面的 URL 或 CSS 來決定要不要顯示擴充套件的 page action。如果要讓使用者在點擊 page action 能夠和頁面進行互動的話,需要允許 activeTab 的權限。
如果你需要其他更精確的控制或需要在特定頁籤改變其外觀的話,則需要繼續使用 pageAction API。
chrome.declarativeContent.onPageChanged.addRules()
作為一個 declarative API,它讓你可以在 onPageChanged
事件註冊一些規則,當這些規則符合時就執行特定的動作(例如 ShowPageAction
和 SetIcon
)。
用來添加規則:
// background.js
chrome.declarativeContent.onPageChanged.addRules([
{
// 用來設定哪些條件下要做哪些事
// 當使用者頁面的 URL 匹配到下面的項目時...
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: {
schemes: ['https', 'http'],
},
}),
],
// 條件符合時要做的行為
actions: [new chrome.declarativeContent.ShowPageAction()],
},
]);
匹配使用者當前瀏覽頁面的 URL - PageStateMatcher
用 chrome.declarativeContent.PageStateMatcher
來匹配使用者當前瀏覽頁面的 URL:
// background.js
new chrome.declarativeContent.PageStateMatcher({
pageUrl: {
schemes: ['https', 'http'], // http 或 https 開頭的 URL 即可
hostEquals: 'developer.chrome.com', // 選定 host
},
});
tab / activeTab
chrome.tabs @ Chrome Developer
keywords: activeTab
, tabs.query
, tabs.executeScript
當允許 activeTab 後將可以
- 使用
tabs.executeScript
或tabs.insertCSS
- 透過
tabs.Tab
物件取得該 tab 的 URL, title, favicon - 透過 webRequest API 干涉該 tab 的網絡請求,可以讓擴充套件暫時取的該 tab 的 host 權限
使用
activeTab
的意思是有存取當前 active 頁籤(網頁)的權限,但若要executeScript
的網頁不是當前「active tab」,仍需要在 permission 中定義欲存取網頁的網址。
tabs.query
有 activeTab 的權限後可以在特定的頁籤(tab)上執行 JavaScript:
// popup.html
// 找出所有符合條件的 chrome 頁籤
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
// 在該頁籤上執行特定程式
chrome.tabs.executeScript(tabs[0].id, {
code: `document.body.style.backgroundColor='${color}';`,
});
});
tabs.executeScript
tabs.executeScript
的第一個參數是 tabId,不填寫時預設是 active tab:
// 在 active tab 上執行 JavaScript 檔案
chrome.tabs.executeScript({ file: 'logic.js' });
// 在 active tab 上執行 JavaScript 語法
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="orange"',
});
contextMenus
keywords: chrome.contextMenus
chrome.runtime.onInstalled.addListener(function () {
chrome.contextMenus.create({
id: 'sampleContextMenu',
title: 'Sample Context Menu',
contexts: ['selection'],
});
});
bookmarks
keywords: chrome.bookmarks
desktopCapture
keywords: chrome.desktopCapture.chooseDesktopMedia
chrome.desktopCapture @ Chrome Developer
可以使用的 desktop capture source type 為:
const desktopCaptureSourceType = ['screen', 'window', 'tab', 'audio'];
chrome.desktopCapture.chooseDesktopMedia
// 可以使用的 desktop capture source type
const desktopCaptureSourceType = ['screen', 'window', 'tab', 'audio'];
chrome.desktopCapture.chooseDesktopMedia(
desktopCaptureSourceType,
tabs.Tab, // target tab (optional)
callback <string streamId, object options>
)
- 在
callback
中取得的streamId
可以用在getUserMedia()
API,用來產生使用者所選 的 media source 對應的 media stream。 - 若使用者拒絕授權,則
streamId
將為空值。 - 如果使用者沒有選擇任何 source(或選擇取消),那麼該 callback 的 streamId 會是空值。這個 streamId 只能使用一次,且一段時間未使用的話將會過期。
Background Script / Background Page
Background Scripts @ Chrome Extension Manage Events with Background Scripts
Manage Events
擴充套件是以事件為主的程式,可以用來改變或增強 Chrome 瀏覽器的使用體驗。事件是由瀏覽器驅動,例如瀏覽到一個新頁面、移除書籤、關閉頁籤等等,擴充功能可以透過 Background Script 來監控這些事件,並給予相對應的回應。
Background Page 會在需要的時後被載入,並且在閒置時(idle)卸載(unloaded),一些例子如下:
- 擴充套件第一次被安裝或更新版本時
- Background Page 在監聽一個事件,並且事件被觸發(dispatch)時。
- Content Script 或其他的套件傳送訊息時。
- 擴充套件中其他的畫面(例如,popup)呼叫
runtime.getBackgroundPage
時。
Background Scripts 一旦載入後,只要有在 做事(例如,呼叫 Chrome API 或發送網絡請求)Background Page 就會持續運行,此外,除非所有可視頁面(visible views)和所有溝通的連接埠(message ports)都關閉時,Background Page 才會卸載(unload)。要注意的是,開啟頁面並不一定會使得 Event Page 被加載,但可以避免在加載後被關閉。
有效的 Background Scripts 會處於閒置(dormant)的狀態,除非有事件要它們監聽,並作出對應的反應後,再重新進入卸載(unload)。
註冊 Background Scripts
Background Scripts 必須先在 manifest.json
內被註冊:
// manifest.json
{
"name": "Awesome Test Extension",
"background": {
"scripts": [
"backgroundContextMenus.js",
"backgroundOmniBox.js",
"backgroundOauth.js"
],
"persistent": false
}
}
❗ 注意:主要當 Background Script 需要使用到 chrome.webRequest API 時,才需要將
persistent
設為true
。