Chrome 插件开发示例
前言
我们常称的 Chrome 插件(Chrome Extension)是指 Chrome 扩展程序,它的作用是增强浏览器功能。通常在Chrome商店中下载的扩展是.crx
后缀的压缩包,安装插件可以以压缩包形式安装,当你开启开发者模式的时候,也可以加载已解压的扩展程序,即至少包含一个manifest.json
文件和一个 html 或者 js 文件的的文件夹。
Chrome插件提供了很多实用API供我们使用,包括但不限于:书签控制、下载控制、窗口控制、标签控制、网络请求控制,各类事件监听、自定义原生菜单、完善的通信机制等。
本文多图预警 🙃
Talk is cheap. Show me the code.
一、一个最简单的 Chrome 扩展的组成示例
此示例由一个manifest.json文件和html文件和一个png图片文件组成,是一个git 提交的emoji速查工具,功能非常的简单,就是点击弹出一个html页面(下图),以达到速查的目的,html里可以替换成任何你想要的内容。代码戳这里 下载这份代码,在 Chrome 里的扩展程序里打开开发者模式,加载已解压的扩展程序即可体验
manifest.json 基本配置
{
"manifest_version": 2, // 必填 用整数表示manifest文件自身格式的版本号。从Chrome 18开始,manifest_version就是2了
"name": "git commit emoji速查", // 必填 用来标识扩展的简短纯文本。这个文字将出现在安装对话框,扩展管理界面,和store里面
"description": "git commit emoji对照表", // 描述扩种的一段字符串(不能是html或者其他格式,不能超过132个字符)
"version": "1.0.0", // 必填
"browser_action": { // 一个 browser action 可以拥有一个图标,一个tooltip,一个badge和一个popup。
"default_icon": "icon.png", // 右上角的图标
"default_title": "这是一个 git commit emoji 速查的Chrome插件", // 鼠标hover的文字
"default_popup": "popup.html" // 点击图标展示的html内容
}
}
几个常用配置比较
二、Chrome插件的表现形式
1. 浏览器右上角(最常见)
不管有没有开发过 Chrome 插件,我们最熟悉的 Chrome 插件一定是右上角插件图标
一般功能上有两种,一种是一直开启状态,点击发生交互,展示弹窗之类的,在 manifest.json 配置的是 browser_action;一种是点击开启(例如屏蔽广告等)功能,有些是在特定情况下才展示,比如vue的调试插件是在vue开发模式下才能开启。page_action 则指的是只有当某些特定页面打开才点亮的图标,其他则是置灰。
2. 自定义右键菜单
鼠标右键的菜单
使用 chrome.contextMenus 实现
chrome.contextMenus.create({
id: 'page',
title: '测试右键菜单'
});
如果要在选中状态的时候去监听点击事件,达到这样的效果
注意:使用 chrome.contextMenus API 需要在 manifest.json 里生命权限 permissions 数组里加上 contextMenus
chrome.contextMenus.create({
id: 'baidu-search',
title: '使用百度搜索:%s',
contexts: ['selection']
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
switch(info.menuItemId){
case 'baidu-search':
chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(info.selectionText)});
break;
}
});
3. 覆盖特定页面
在 manifest.json 里添加 chrome_url_overrides,可以被替换的只有新标签页 newtab、历史记录页 history、书签页 bookmarks 这三个选项,但是一个插件只能重写一个默认页
"chrome_url_overrides":
{
"newtab": "newtab.html"
}
4. 开发者工具
自定义开发者工具面板,大家熟悉的 vue 插件就是通过自定义开发者工具面板实现
通过 chrome.devtools API来实现
// 几个参数依次为:panel标题、图标(其实设置了也没地方显示)、要加载的页面、加载成功后的回调
chrome.devtools.panels.create("TestPanel", "", "devtools.html", function(
panel
) {
console.log("自定义面板创建成功!", panel); // 注意这个log一般看不到
});
// 创建自定义侧边栏
chrome.devtools.panels.elements.createSidebarPane("Images", function(sidebar) {
// sidebar.setPage("devtools.html"); // 指定加载某个页面
sidebar.setExpression('document.querySelectorAll("img")', 'All Images'); // 通过表达式来指定
// sidebar.setObject({aaa: 111, bbb: 'Hello World!'}); // 直接设置显示某个对象
});
5. 选项页
选项页实际上是指插件的详细信息介绍,配置在 manifest.json 里的options_ui
"options_ui": {
"page": "options.html",
"browser_style": true
},
6. 搜索建议
manifest.json里配置触发关键词,配置后再地址栏输入关键词后按空格键触发插件搜索建议
"omnibox": { "keyword" : "go" }
background.js 里 使用chrome.omnibox API
chrome.omnibox.onInputChanged.addListener((text, suggest) => {
console.log('inputChanged: ' + text);
if(!text) return;
if(text == 'c') {
suggest([
{content: 'extension' + text, description: 'chrome://extension'},
{content: 'bookmarks' + text, description: 'chrome://bookmarks'},
{content: 'history' + text, description: 'chrome://history'}
]);
}
});
// 当用户接收关键字建议时触发
chrome.omnibox.onInputEntered.addListener((text) => {
console.log('inputEntered: ' + text);
if(!text) return;
var href = '';
if(text.endsWith('extension')) href = 'chrome://extension'
else if(text.endsWith('history')) href = 'chrome://history'
else href = 'chrome://bookmarks'
openUrlCurrentTab(href);
});
// 获取当前选项卡ID
function getCurrentTabId(callback)
{
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
if(callback) callback(tabs.length ? tabs[0].id: null);
});
}
// 当前标签打开某个链接
function openUrlCurrentTab(url)
{
getCurrentTabId(tabId => {
chrome.tabs.update(tabId, {url: url});
})
}
桌面通知
chrome.notifications API ,首先在 permissions 里声明 notifications 权限,再在background里创建通知
chrome.notifications.create('', {
type: 'basic',
iconUrl: 'icons/icon.png',
title: '这是标题',
message: '您刚才点击了自定义右键菜单!'
});
三、消息通信
Chrome插件中有2种通信方式,一个是短连接(chrome.tabs.sendMessage和chrome.runtime.sendMessage),一个是长连接(chrome.tabs.connect和chrome.runtime.connect)
sendMessage 发消息 onMessage 接收监听消息
connect 建立长连接 通过 onConnect 接收监听消息
四、用 vue 开发 Chrome 插件
用 vue 开发 Chrome 插件实际上是页面都通过vue来开发,最后打包之后的文件还是包含 html、js、静态资源文件和 manifest.json 几个 Chrome 必要组成部分,vue是通过模板引擎生成对应的想要的页面。
https://github.com/Kocal/vue-web-extension 是一个通过命令生成的vue开发Chrome插件模板cli
本文代码演示是用的这个模板