博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的firefox插件开发历程
阅读量:6577 次
发布时间:2019-06-24

本文共 5854 字,大约阅读时间需要 19 分钟。

首先给出firefox插件开发的官方文档列表,如果没有列表,那么开发firefox插件几乎不可能,光看中文资料也是会死的说,从老大给了任务,到基本完成任务,中间花了一周时间,这一周是痛苦而又极有成就感的一周,我的插件其实功能还算简单,就是在界面上添加一个按钮,点击按钮打开我们的主页,右键菜单上在加上一个菜单项,点击可以把当前页面存到我们的server上(HTTP接口)

开发环境:ubuntu10.10 firefox 7.0


基础知识:

firefox插件是一个xpi文件,例如firefox-thinkernote.xpi,安装方式有两种,前者直接拖拽到地址栏,就会提示你安装,再者选择菜单:工具/附件管理 打开附加组件管理窗口,窗口右上侧的搜索栏前有一个扳手的图标,点击选择从文件安装附加组件,就会打开一个选择窗口,找到咱的xpi所在目录,点击即可,也会提示咱们安装

xpi文件其实就是一个zip文件,把我们的开发目录压缩成一个zip压缩包,再重命名就是我们的安装插件了,而我们的插件开发目录其实是有要求的:

firefox-thinkernote/  chrome/    overlay.xul    overlay.js  locale/   en-US/    overlay.dtd   zh-CN/    overlay.dtd  skin/    classic/    icons/      overlay.css  install.rdf  chrome.manifest

顶层目录没有要求,叫什么都成,我叫这个名字是表示这个插件是我们项目的firefox插件,不过底下的结构就有要求了,install.rdf是一个XML文件,描述的插件的开发者信息,谁开发的插件,插件版本,不过需要注意的是:targetAppliction/Description/em:id必须是{ec8030f7-c20a-464f-9b0e-13a3a9e97384}这个表示,该插件是为firefox浏览器开发。另一个em:id 则用于描述插件ID,所以该ID也不能重复,你想很多插件装在一个浏览器上,浏览器怎么区分,必须有一个不重复的ID,因此这个ID可以取邮件地址,因为邮件是全世界唯一的,或者取GUID,这个我不懂,所以我取邮件地址作为插件ID

shujun.li@thinkernote.com
1.0
2
{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
1.5
10.0
ThinkerNote
thinkernote 行客记事
thinkernote.com
http://www.thinkernote.com/

chrome.manifest 定义开发包名称和资源位置的,其语法是

directoryName  packageName  positionInDirectoryOfPackage

content        thinkernote                chrome/content/locale         thinkernote     en-US         chrome/locale/en-US/skin        thinkernote        classic/1.0    chrome/skin/classic/overlay        chrome://browser/content/browser.xul            chrome://thinkernote/content/overlay.xulstyle        chrome://global/content/customizeToolbar.xul    chrome://thinkernote/skin/overlay.css

overlay        chrome://browser/content/browser.xul            chrome://thinkernote/content/overlay.xul

这一行是说把我们的xul文件追加到系统的xul里去,浏览器在启动的时候会启动browser.xul也会顺道启动我们的overlay.xul,这样我们的插件就和浏览器一起启动,并能做一些事情了,注意我们定义了content目录以后,就可以通过chrome://packageName/directoryName/fileName来引用文件了,例如overlay.xul其实是在 firefox-thinkernote/chrome/content/下面

xul文件也是一个XML文件,它描述的是我们的插件启动以后,界面是什么样的,不过大多数的插件没有界面只是在工具栏增加了按钮,右键菜单增加了菜单项

我们这个XUL文件是在chrome.manifest文件里指定的,让系统启动时加载的XUL文件,这里定义了菜单项,按钮,和右键菜单,他们的oncommnd事件和HTML里的onclick没有区别,意思就是说当它们被点击时取执行指定的函数。这些函数被定义在JS文件里,所以XUL文件的开头部分就定义了script引用(注意他们的src)OK,能引用JS就能引用CSS,CSS进来是干嘛的呢,他们来描述我们定义的按钮,例如按钮需要一张图片,他们就来告诉浏览器图片在哪里,那么怎么告诉呢?用按钮的ID,在CSS文件里定义一个和按钮ID名相同的CSS样式定义,系统会自己查找匹配

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");#thinkernote-toolbarbutton {
list-style-image: url("chrome://thinkernote/skin/icons/24x24.png");}toolbar[iconsize="small"] #thinkernote-toolbarbutton {
list-style-image: url("chrome://thinkernote/skin/icons/19x19.png");}#saveFormWindow{
background-color:white;}

OK,说了JS,CSS是干嘛的,那么DTD又是干嘛的呢,DTD其实是为国际化开发做准备,我们把各种语言的字符串放到不同的DTD文件里,定义如下,中间的部分是ENTITY-NAME,名字的thinkernote没有特殊的意思,就已名字的一部分而已,使用的时候就可以用"& ENTITY-NAME" 来引用

特别要说明一点的是,即便是在CSS样式里定义了按钮图片,DTD文件里定义了按钮文字,按钮还是不会出来,orz 因为我们还少了一步,用代码把按钮设置到工具栏上去

function installButton(toolbarId, id, afterId){    if (!document.getElementById(id)) {        var toolbar = document.getElementById(toolbarId);        var before = toolbar.firstChild;        if (afterId) {            let elem = before = document.getElementById(afterId);            if (elem && elem.parentNode == toolbar)                before = elem.nextElementSibling;        }        toolbar.insertItem(id, before);        toolbar.setAttribute("currentset", toolbar.currentSet);        document.persist(toolbar.id, "currentset");    }}    function firstRun(extensions){    let extension = extensions.get("shujun.li@thinkernote.com");    var first = extension.firstRun;    if(first){       installButton("nav-bar", "thinkernote-toolbarbutton", "urlbar-container");    }//第一次安装运行时first才等于true}var Application = Components.classes["@mozilla.org/fuel/application;1"].getService(Components.interfaces.fuelIApplication);if (Application.extensions)    firstRun(extensions);else    Application.getExtensions(firstRun);

JS的代码编写 


在编写页面的时候,我们会使用DOM对象来访问页面上的元素,例如document,window对象,因此如果要没这些可以直接拿来用的顶层全局对象整个就没法玩,因此我们要找在这个控件里可以直接拿来用的对象,我发现有两个对象gBrowser对象和document对象,gBrowser表示浏览器,document表示装载的页面,不过假设用户通过地址栏打开了baidu.com我们想访问这个页面还不能直接使用document对象,而是要这么获得

function getDocument(){    return document.getElementById('content').selectedBrowser.contentDocument;}function gotoHomePage(){    pageDocument = getDocument();    pageDocument.location = serverUri;}function gotoLogin(){    gBrowser.selectedTab = gBrowser.addTab(serverUri + "/login"); }

 firefox插件资料比较少,baidu文档里有一些,如果您在看本文可以去看看,最重要的还是在于看官方的文档!

 

附免打包的开发环境配置

 


邮件地址作为ID: 在firefox的插件目录下建立一个和邮件名同名的文件

$ cd .mozilla/firefox/g911mow7.dev/extensions

$ touch shujun.li@thinkernote.com

$ vi shujun.li@thinkernote.com

写入代码所在目录:/home/shujunli/firefox-thinkernote/

 

补充信息:

上次配置开发环境时查看的资料说需要建立一个dev的环境,然后找dev的extensions目录,其实这不是必需的的,实际上firefox在主目录生成了一个隐藏文件夹.mozilla 并且这个隐藏文件夹下有一个目录是用来放置安装插件的,在我的系统里这个目录是 ~/.mozilla/firefox/i7lsshse.default/extensions 在这个目录里能看见浏览器已经安装了的插件源码(每个源码是一个文件夹或者是email或者是uuid)按照上面描述的免打包开发环境的配置,在这个目录下放一个文本文件

 

 

转载于:https://www.cnblogs.com/code-style/archive/2012/04/21/2462428.html

你可能感兴趣的文章
C Primer Plus 第5章 运算符、表达式和语句 5.2基本运算符
查看>>
蓝牙手柄按键码
查看>>
java并发库之Executors常用的创建ExecutorService的几个方法说明
查看>>
Spring框架错误之org.springframework.beans.factory.BeanCreationException
查看>>
23种设计模式(1):单例模式
查看>>
socket 编程入门教程(五)UDP原理:4、“有连接”的UDP
查看>>
Jquery获取iframe中的元素
查看>>
Laravel 学习笔记5.3之 Query Builder 源码解析(下)
查看>>
Struts2简单入门实例
查看>>
2012CSDN年度博客之星评选http://vote.blog.csdn.net/item/blogstar/xyz_lmn
查看>>
BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划
查看>>
Craking the Interview-1
查看>>
POJ 3468 A Simple Problem with Integers(线段树,区间更新,区间求和)
查看>>
CCF NOI1150 确定进制
查看>>
SpringBoot实战总汇--详解
查看>>
2018年7月1日笔记
查看>>
尝试使用iReport4.7(基于Ubuntu Desktop 12.04 LTS)
查看>>
安装GIT(基于Ubuntu Desktop 12.04 LTS)
查看>>
动态规划:金矿模型
查看>>
子元素应该margin-top为何会影响父元素【转】
查看>>