FeHelper-JSON

一、序言

鉴于Google Chrome官方强制要求的插件单一用原则,老版本(V2019.12)被官方从商店下架;为保证用户能继续正常使用FeHelper,启动了FeHelper的一次大升级。 先了解一下啥是Google的单一用途原则,直接看Google官方的说明吧:https://developer.chrome.com/extensions/single_purpose

二、新版思路

三、新版界面

程序化交易与云端服务器 开放平台模式下的FeHelper(1)

四、开放平台

4.1 如何将插件配置页打造成工具市场,满足工具的上架、更新、卸载等操作?

4.2 通过市场安装的工具,如何解决资源存储的问题,并确保存储空间足够大?

4.3 如何突破插件对包外资源加载并执行的限制,以实现动态安装的工具可在Chrome插件中正常运行?

4.4 市场内工具包含不同形式:有独立界面形式、纯content-script形式、混合模式,平台如何支持?

4.5 市场内工具与插件background之间的消息通信种类多样,如何提供统一接口进行支持?

4.6 工具的使用方式分两种:Toolbar-Popup-Page模式、Page-Context-Menu模式,如何统一管理?

// test case 1: popup-page中唤起image-base64工具,并传递一个需要进行base64的图片地址 chrome.DynamicToolRunner({ query : 'tool=image-base64', withContent : 'https://www.baidu.com/img/bd_logo1.png' }); // test case 2: popup-page中唤起color-picker工具,此工具无独立页面 chrome.DynamicToolRunner({ query : 'tool=color-picker', noPage : true }); // test case 3: context-menu中唤起qr-code工具,并将需要生成二维码的内容传递到页面 chrome.contextMenus.create({ title: '二维码生成器', contexts: ['all'], parentId: FeJson.contextMenuId, onclick: function (info, tab) { chrome.tabs.executeScript(tab.id, { code: '(' (function (pInfo) { let linkUrl = pInfo.linkUrl; let pageUrl = pInfo.pageUrl; let imgUrl = pInfo.srcUrl; let selection = pInfo.selectionText; return linkUrl || imgUrl || selection || pageUrl; }).toString() ')(' JSON.stringify(info) ')', allFrames: false }, function (contents) { chrome.DynamicToolRunner({ withContent: contents[0], query: `tool=qr-code` }); }); } });

4.7 除作者外,第三方开发者如何发布自己的应用到FeHelper工具市场?

- ${tool}文件夹 `必选` - fh-config.js `必选,具体配置项参考下文` - index.html `必选,要去双击可独立运行` - index.js `必选` - index.css `可选` - content-script.js `可选,除非config中配置了true` - content-script.css `可选,除非config中配置了true` - other js/css files `可选,需在index.html中显式引用` - images `禁止,如果需要可用base64替代` - font `禁止,如果需要可用base64替代`

五、FH开发者工具

5.1 无图无真相

5.2 工具介绍

六、Open API

建议安装FH开发者工具以后,直接拿hello-world示例来学习!

6.1 chrome.* API

  • 官方提供的Api基本都可以用,可以直接去官网看: https://developer.chrome.com/extensions/devguide
  • 如果访问不了chrome.com,你可以用360的插件开发者Api来学习使用,也基本够用: http://open.chrome.360.cn/extension_dev/overview.html
  • 如果也不行看360的Api,你还可以看baidu浏览器插件的开发者Api,也差不多够用: https://chajian.baidu.com/developer/extensions/api_index.html

6.2 在工具独立页面使用chrome.* API

  • 如果你的工具没有配置noPage: true,那么你可以在index.html引用的js文件中直接使用chrome.*API

6.3 content-script.js

  • 只要你配置了contentScript: true,工具就一定需要有content-script.js脚本文件
  • content-script.js文件中,一定要显示的在window上绑定一个方法,以hello-world为例:/** * 注意这里的方法名称,其实是:window[`${toolName.replace(/[-_]/g,'')}ContentScript`]; * @author 阿烈叔 */ window.HelloworldContentScript = function () { console.log('你好,我是来自FeHelper的工具Demo:hello world!'); };
  • 你完全不必要担心window对象被污染,因为content-script是在一个独立的沙箱内运行的,对网页的正常运行毫无影响
  • content-script.js文件中,基本是除了chrome.runtimeAPI,其他的chrome.*是用不了的,如果实在要用,可以参考6.5的消息机制
  • 在content-script.js中,你可以进行任意的DOM操作,就跟你正常的coding一样

6.4 关于noPage配置

  • 如果你配置了noPage: true,那你的工具也一定需要有content-script.js脚本文件
  • content-script.js文件中,一定要显示的在window上绑定一个方法,依然以hello-world为例:/** * 如果在 fh-config.js 中指定了 noPage参数为true,则这里必须定义noPage的接口方法,如: * 注意这里的方法名称,其实是:window[`${toolName.replace(/[-_]/g,'')}NoPage`]; * @author 阿烈叔 */ window.helloworldNoPage = function (tabInfo) { alert('你好,我是来自FeHelper的工具Demo:hello world!你可以打开控制台看Demo的输出!'); console.log('你好,我是来自FeHelper的工具Demo:', tabInfo); };
  • 既然noPage和content-script都一样,那为什么还要有noPage这个东西?noPage指明的是:该工具无独立页面点击下拉列表中的工具入口、或者右键菜单中点击工具入口,会执行window.xxxNoPage中的代码
  • noPage的应用有没有一些实用的例子?比如,FeHelper中提供的网页取色工具,就是一个noPage的应用,点击工具,直接在网页上呼出一个取色器再比如,FeHelper中提供的二维码解码工具,在二维码图片上右击,可以直接对该二维码进行解码

6.5 消息通信

  • 消息机制主要是提供给content-script.js使用的,它提供了一种内容脚本使用chrome.* API的可行性,示例:// background 示例:在content-script.js中获取当前浏览器的所有tab chrome.runtime.sendMessage({ type: 'fh-dynamic-any-thing', params: { tabId: window.__FH_TAB_ID__ // 这是FH的内置变量,表示当前Tab的id }, func: ((params, callback) => { // TODO: 这里可以调用 chrome.* 的API,随便用。。。 // Case1:获取当前窗口的全部tab chrome.tabs.query({currentWindow: true}, tabs => { let jsonInfo = JSON.stringify(tabs); // 注入到页面,注意看这里如何读取外面传进来的参数 chrome.tabs.executeScript(params.tabId, { code: 'console.log(' jsonInfo ');' }); }); callback && callback(); return true; }).toString() });

6.6 content-script.css

  • 如果配置了contentScriptCss: true,那说明你的FH工具还需要向页面注入CSS代码
  • content-script.css的加载机制,是在content-script.js中通过6.5中介绍的消息机制来完成的
  • 依然以hello-world为例,看代码示例:// 注入css and html fragment chrome.runtime.sendMessage({ type: 'fh-dynamic-any-thing', func: ((params, callback) => { // 通过这个内置方法来获取css内容,并直接注入当前网页 Awesome.getContentScript('hello-world', true).then(cssText => { chrome.tabs.insertCSS({ code: cssText, runAt: 'document_end' }); }); callback && callback(); return true; }).toString() });
  • 当然,要想在content-script中使用自定义的css,办法还有很多,可以定义contentScriptCss: false,通过在页面上直接硬编码插入的方式来完成,比如:let cssText = `/* Your CSS Codes Here... */`; let elStyle = document.createElement('style'); elStyle.textContent = cssText; document.head.appendChild(elStyle);

七、意见反馈

  • 大家可在feedback中反馈、也可加群反馈、或者直接Mail给我
  • 最后,欢迎搭建使用 FeHelper ,希望开放平台思路的FeHelper能给大家带来快感!
,