[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'],
});
});