开发chrome插件2真正的入门文档
忽然发现插件是绕不过去的, 那么从chrome开始吧. chrome extension
最终还是从stackoverflow入门:
- https://stackoverflow.com/questions/32467151/how-to-disable-javascript-in-chrome-developer-tools-programmatically
- 这其中Joshua Dannemann 的答案:
You can write a simple Chrome extension to do what you want. Chrome provides a JavaScript API were you can allow or block JavaScript using contentSettings and the property you will need to set or unset is JavascriptContentSetting.
https://developer.chrome.com/extensions/contentSettings
https://developer.chrome.com/extensions/contentSettings#type-JavascriptContentSetting
To add the keyboard shortcut, you add it to the manifest as described here:
https://developer.chrome.com/extensions/commands
Just in case you have not built an extension before (don't worry, it is pretty easy), here is a walk-though on putting together your first:
https://developer.chrome.com/extensions/getstarted
Hope this helps.
入门的顺序
- https://developer.chrome.com/extensions/getstarted
- 这个例子是针对tab写的权限, 所以很多时候这个插件并不能够激活, 是灰色的无法应用状态.
- 这个例子最终结果很挫, 要用option改变按钮颜色, 按钮只有一个. 并不是正常的ui思路, 只是为了展示插件的技术.
- https://crxdoc-zh.appspot.com/extensions/getstarted
- 中文的这个入门更搓, 代码和文字明显不匹配了.
- 不过他的改变背景色是有选择的, 可以参考.
- icon是一个19x19的png. 这个貌似也不对, 在英文的例子里面icon有四种16, 32, 48, 128
####关键文档
- https://developer.chrome.com/extensions/overview
- 这个文档很关键, 可以对于chrome插件形成全局观
文件部分:
- 插件的id在开发过程中就是路径, 避免硬编码可以用:
chrome.runtime.getURL()
- manifest.json这个是配置文件, 这个名字是固定的. 插件甚至于只有这个文件
- background脚本, 控制事件的脚本. 这个并不是必须的, 甚至于干正事也不需要他.
- ui组件, 包括html和对应的js, 这个大部分时候是要的, 总是要给用户点反馈.
- aciton有两种
- browser
- page
- context menus
- omnibox 是地址栏快捷键
- keyboard shortcut
- aciton有两种
- popup页面和js 也属于ui组件的一部分, 但是, 这个非常重要
- action设置: 可以popup页面
- 也可以: tabs.create or
window.open()
- 在background脚本里面可以 declarative content 设置popup的显示
- content 脚本 和dom交互的脚本, 也不是必须的. google的项目总喜欢把事情分层复杂化. 用一个复杂的结构解决复杂的问题. 分治的非常勉强.
- options 页面, 插件的设置选项的页面, 其实也没啥用. 一个插件还需要设置.
api部分
所有的api都是chrome.xxxx形式.
同步和异步
//api是异步的
//一般情况, 异步函数是这样调用的, Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)
//实际代码
chrome.tabs.query({'active': true}, function(tabs) {
chrome.tabs.update(tabs[0].id, {url: newUrl}); //这个后执行, 并且它虽然是异步函数, 但是并没有回调函数.
});
someOtherFunction(); //这个先执行
//也有同步代码: // Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()
页面间通讯
-
chrome.extension
-
getViews()
-
getBcakgronundPage()
-
也可以用storage接口的message passing
-
Incognito mode 这个模式的意思是window不可以被tracks, 也就是说插件保留自己的配置是可以的, 但是, 想要保留页面历史, 则必须不包含incognito mode的页面.
-
用tabs.Tab或者windows.Window的incognito属性来测试是否incognito mode.
-
function saveTabData(tab) { if (tab.incognito) { return; } else { chrome.storage.local.set({data: tab.url}); } }
-
看了这个overview之后, 回头再看getstarted, 清晰了很多.
总结:
- browser_action的设计比较简单
- page_action 需要一个chrome.declarativeContent的声明
- 那么问题来了, brower和page的目标是什么呢?
- https://developer.chrome.com/extensions/pageAction
- https://developer.chrome.com/extensions/browserAction
- 官方的说明
- page受限于页面
- browser总是有效
- 那么我的几个需求都是browser比较合理
这个官方文档其实是一个连连看
- overview竟然还有子条目, 这些子条目竟然只存在于左边的目录树.
- 并没有下一步.
- 因此, 需要顺序阅读左边的子条目才可以.
调试
- 调试文档并没有太多有价值内容. 和一般的js调试是基本一致的.
- 特别重要的一点, 用插件的id是可以调试代码的.
- 比如我的popup.html: chrome-extension://plfilniddlhhfmhhcmganobhdjpjcmef/popup.html
- 鼠标右键在弹出窗口上面也可以直接呼出调试界面.
- 参考这个文档的调试部分, 非常有用: https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
生命周期的一个疑问
用popup呼叫background的函数, 这个函数执行的进程生命周期是在background还是popup, 不太好查, 直接测试一下.
// popup.js
var bg = chrome.extension.getBackgroundPage();
bg.test(); // 访问bg的函数
alert(bg.document.body.innerHTML); // 访问bg的DOM
所以说, 要整体学习下chrome extension的生命周期, 这两份文档有用. 官方文档难于检索.
- https://itnext.io/all-youll-ever-need-to-know-about-chrome-extensions-ceede9c28836
- https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
声明周期描述
- popup的周期就是那个弹出的网页, 关闭就木了.
- content注入的是当前的网页, 并不是tab, 也就是说如果tab发生跳转, 那么久木了.
- background运行在浏览器声明周期, 只要插件没有卸载, 浏览器没有关闭, 这个就在.
主要的三个沟通的核心相关api
- Tabs
- Messaging
- Storage
有四种情况background会忙起来:
- The extension is first installed or updated to a new version.
- The background page was listening for an event, and the event is dispatched.
- A content script or other extension sends a message.
- Another view in the extension, such as a popup, calls `runtime.getBackgroundPage’
back的注意:
-
background可以注册多个, 因此可以模块化管理.
-
如果用了chrome.webRequest, 那么就不能用合格eventpage模式了, 应该用background的持久化模式.
-
因为tab不支持event filter, 所以如果要用event filter, 那么用
webNavigation.onCompleted
代替tabs.onUpdated
例如:chrome.webNavigation.onCompleted.addListener(function() { alert("This is my favorite website!"); }, {url: [{urlMatches : 'https://www.google.com/'}]}); //这个意思就是只针对google.com才出上面的alert.
content script
-
注入的match parttern可以写多个, 那是一个数组.
"*://*/*" //这个意思是http或者https的任意链接
-
css也是可以注入的: https://developer.chrome.com/extensions/tabs#method-insertCSS
chrome.tabs.insertCSS(tabs[0].id,{ code: '* {background-color: '+color+';}' });
-
js注入
chrome.tabs.executeScript({ code: 'document.body.style.backgroundColor="orange"' });
-
json配置注入
"content_scripts": [ { "matches": [ "*://*/*" ], "all_frames": true, "js": [ "lib/lib.js", "inject/baser.js", "inject/downbutton.js" ] } ],
特别关注的api
download: 批量没找到, 但是设置地址是可以的.
chrome.downloads.download({url:p,filename:'big/'+name})// 这样就设置到了download的big目录下
有用的附录:
- 入门文档好中文:https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
- 入门文档好英文:https://itnext.io/all-youll-ever-need-to-know-about-chrome-extensions-ceede9c28836
- 官方参考好事件: https://developer.chrome.com/extensions/background_pages
- 官方参考好消息: https://crxdoc-zh.appspot.com/apps/messaging#external-webpage
- 官方overview也是好文档: https://developer.chrome.com/extensions/overview
无用的附录: 曲折的上手弯路, 大家不要这么干了
- 打开extension的开发模式, 在右边三点菜单找到more tools->extensions
- 根目录必须有manifest.json
- 打包之后是crx
- 具体的介绍参考这个: https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
- 从知乎找到根源
- 本来360对于这个部分有翻译.
- 但是google有官方的翻译了, 所以360也就不更新了.
- 入门: https://crxdoc-zh.appspot.com/extensions/getstarted
- 概述: https://crxdoc-zh.appspot.com/extensions/overview
- 开发指南: https://crxdoc-zh.appspot.com/extensions/devguide
- google的官方文档很全面, 并且除了扩展之外, chrome程序的文档也在一起.