linux firefox 插件开发教程,Firefox插件(plugins)开发实用指南

了解Firefox插件的开发知识的时候,找到了这篇文章。的确让我少走了弯路,比如,我的NP插件的DLL,之前不是NP开头的,在此非常感谢原作者,您文章让我节约了不少时间。转载传播此文章,希望对准备研究和学习Firefox插件开发的朋友有所帮助。

Firefox插件可实现强大功能,但其中麻烦事情不少。写这个实用指南首先是为了方便自己记忆,免得以后再次栽倒一些坑里面,如果能帮助其他人,则是更好。这个指南不是为了手把手教读者开发插件,而是作为一个FAQ,解决各种诡异问题。

Firefox拥有众多的扩展(Extension),开发扩展也非常容易,不过有一些事情还是无法用扩展解决,需要访问操作系统的底层功能,这就需要写插件(plugins)。例如flash就是一个插件而不是扩展。

Mozilla提供了一系列的教程和文档,虽然很不详尽,众多重要的API语焉不详,但至少是一个好的开始。

最需要阅读的是plugins API和使用入门。这是一个相当长的文档,如果看完所有的内容会花费大量的时间而且还会很晕,这里列一些重点供参考。

写第一个插件(只需要关注Writing Plug-ins这一节所谈到的内容)

获得一份firefox的源码,比如firefox 3.6。plugins的例子可以在源码里找到(modules/plugin/sdk/samples),如果出了问题还可以自己编译一个debug版的firefox来调试。

制作插件的安装程序,推荐用扩展的方式安装插件,有无数的好处

完成以上这些内容以后差不多就已经可以实现自己的插件了,一般而言,参照着例子来做开发不会有什么问题,只是有不少细节需要留意。

Firefox plugins开发的众多奇怪的约定(假设plugins已经被正确安装)

有些约定非常奇怪,不要问我为什么,天晓得开发firefox的牛人们怎么想的。

在Windows下,plugins必须满足以下条件才能被firefox检测到:

插件的名字必须是np*.dll,也就是必须以np开头,.dll结尾

插件dll资源的语言必须为LANG_ENGLISH,code page必须为1252。在rc文件里是这么写的:LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252)

插件dll的VERSION_INFO里面必须包含以下值:VALUE "MIMEType", "application/x-your-mimetype"这个MIME就是标签引用插件的唯一凭证。

在Linux下,plugins必须满足以下条件才能被检测到:

插件的名字必须是lib*plugin.so,即以lib开头,plugin.so结尾

插件必须实现NP_GetMIMEDescription和NP_GetPluginVersion,并返回合适MIME字符串。注意,这个字符串并不是普通的MIME,是有特殊规则的,详见前面这个链接的内容。

插件so不要静态链接gtk、opensll、pthread、z等系统库,这会在不同linux平台上因为符号表的问题遇到各种运行时错误

特别需要说明的是,NP_GetPluginVersion、NP_GetEntryPoints等关键函数没有任何官方文档介绍它们,只能根据例子来猜,反正没事就别改它们的实现,copy例子中的代码就好。

firefox插件开发注意事项

写firefox插件的一个基本习惯是,经常编译代码并运行它,保证你的插件还能工作。只要firefox无法加载dll/so,或者加载出现任何错误,都会悄无声息的忽略这个插件。时常关注一下about:plugins,看看插件是不是还在这个列表里。

firefox插件从窗口模式上可分为windowless和windowed两种。其中,windowless模式的文档较多较全,是firefox比较推荐的模式,坑比较少,这里就不多说了。windowed模式则相反,需要好好说说。

无论在Windows还是Linux上,windowed的插件都拥有独立于浏览器页面的窗口。firefox会通过插件的NPP_SetWindow来告诉插件当前窗口的情况。

关于windowed插件有两个诡异问题需要注意:

Windows平台下,插件窗口默认会响应WM_CTLCOLOREDIT、WM_CTLCOLORLISTBOX、WM_CTLCOLORBTN、WM_CTLCOLORSTATIC消息,并设置一个默认的背景色。这本来没问题,但在Windows XP下,这个颜色居然永远是黑色,而不是默认系统背景色(通常是白色)。最好subclass这个窗口并且拦截这些消息,不要让firefox去处理它们。对于插件来说,firefox处理这些消息只是帮倒忙而已。至于firefox还帮了哪些倒忙,可以去源码widget/src/windows/nsWindows.cpp的nsWindow::ProcessMessage()去围观。

Linux平台下,NPP_SetWindow传入的NPWindow指针中虽然有一个ws_info成员,这个成员里面也确实有一个display变量指向X Window的Display结构,但绝对不要真正使用它,否则可能会导致firefox直接退出,据说这可能是firefox的一个bug。

测试firefox插件小技巧,测试方面的高手可以无视

测试插件前建议先在firefox里面创建一个新的profile(帐号)。这样可以创造一个最干净的开发环境,避免被其他扩展/插件干扰。

默认的profile名叫default,在命令行里输入firefox -p default就可以使用这个profile。如果只是输入firefox -p,会弹出一个对话框用于选择profile。这个命令在Windows和Linux下都可使用。

无论是哪个平台,调试插件的方法都很类似。

Windows下可以用VC以调试方式启动firefox,载入插件时调试器会自动载入对应的符号,捕捉发生的异常或者设断点都很方便。

Linux下直接用gdb就好,细节应该不用多说。有一点需要注意,系统默认安装的firefox命令(默认放在/usr/bin/firefox)是一个shell脚本,真正的可执行文件名字需要打开这个脚本自行查找。

实现firefox插件的基本功能

firefox为插件提供的接口十分原始,很多功能默认没有实现,下面提供了一些思路和方法。

让插件接受焦点:默认情况下,标签不能获得焦点,必须指定tabindex。

在插件中使用tab键跳到下一个element:没有好办法,必须自己手动将焦点还给浏览器窗口(Linux下不必如此),然后自己用NPN_*系列函数找到应该获得focus的DOM element,然后调用这个element的focus()方法。

隐藏和显示插件:直接设置标签的style.display = “none”即可,但这里有个严重的副作用,firefox会调用插件的NS_PluginShutdown,销毁这个插件。如果不期望造成这种效果,要么别用这种方式隐藏插件,要么把插件状态保存在js里,再次显示的时候把状态设回去。

触发DOM事件:firefox没有提供任何便利的方法触发DOM事件,要在插件中做到这点,必须自己模拟js触发DOM事件的过程。例如,对于HTML事件,假设self是DOM element,js会这么做。

evt = document.createEvent("KeyboardEvent");

evt.initKeyEvent( "blur", // in DOMString typeArg,

false, // in boolean canBubbleArg,

false); // in boolean cancelableArg, self.dispatchEvent(evt);

对应的C代码就是

void FireHTMLEvent(NPP npp, const string & name)

{

NPVariant result;

NPObject *window;

NPVariant vDoc;NPN_GetValue(npp, NPNVWindowNPObject, &window);

// 也许页面已经跳转了……

if (!window) {

return;

}

NPIdentifier sDocument = NPN_GetStringIdentifier(“document”);

NPN_GetProperty(npp, window, sDocument, &vDoc);

NPN_ReleaseObject(window);

// evt = document.createEvent(“KeyboardEvent”);

NPVariant evt;

NPObject* npDoc = NPVARIANT_TO_OBJECT(vDoc);

NPIdentifier createEvent = NPN_GetStringIdentifier(“createEvent”);

NPVariant eventArgs[1];

STRINGZ_TO_NPVARIANT(“HTMLEvents”, eventArgs[0]);

NPN_Invoke(npp, npDoc, createEvent, eventArgs, 1, &evt);

NPN_ReleaseObject(npDoc);

// evt.initKeyEvent(

//    “blur”,      //  in DOMString typeArg,

//    false,            //  in boolean canBubbleArg,

//    false);            //  in boolean cancelableArg,

NPObject * npEvt = NPVARIANT_TO_OBJECT(evt);

NPIdentifier initKeyEvent = NPN_GetStringIdentifier(“initEvent”);

NPVariant initArgs[3];

STRINGZ_TO_NPVARIANT(name.c_str(), initArgs[0]);

BOOLEAN_TO_NPVARIANT(false, initArgs[1]);

BOOLEAN_TO_NPVARIANT(false, initArgs[2]);

NPN_Invoke(npp, npEvt, initKeyEvent, initArgs, 3, &result);

NPN_ReleaseVariantValue(&result);

// this.dispatchEvent(evt);

NPObject * self;

NPN_GetValue(npp, NPNVPluginElementNPObject, &self);

NPIdentifier dispatchEvent = NPN_GetStringIdentifier(“dispatchEvent”);

NPVariant dispatchArgs[1];

dispatchArgs[0] = evt;

NPN_Invoke(npp, self, dispatchEvent, dispatchArgs, 1, &result);

NPN_ReleaseVariantValue(&result);

NPN_ReleaseObject(npEvt);

NPN_ReleaseObject(self);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马程序员--IO【1】

------------------- android培训、java培训、期待与您交流!------------------ /*System:类中的方法和属性都是静态的。out:标准输出,默认是控制台。in:标准输入,默认是键盘。描述系统一些信息。获取系统属性信息:Pro…

C# 爬虫:疫情实时信息图

运行结果:using System; using System.Drawing; using System.Text; using NSoup; using NSoup.Nodes; using System.IO; using System.Net; using System.Text.RegularExpressions; using System.Windows.Forms;namespace Pneumonia {public partial class MainFor…

史上最黑科技 | 人造肌肉、DNA折叠、柔性外骨骼…

全世界只有3.14 % 的人关注了数据与算法之美说起被机器人支配,一部分人恐惧得不行,另一部人只当个笑话,但无论哪一边,都忍不住想看看这个神秘的领域正在发生什么,这是本能:“我得盯着你,如果哪天…

linux l显示详细信息,fdisk -l显示信息详解

fdisk -l显示信息详解[rootwww.linuxidc.com ~]# fdisk -lDisk /dev/sda: 10.7 GB, 10737418240 bytes255 heads, 63 sectors/track, 1305 cylindersUnits cylinders of 16065 * 512 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/o…

今天正式开通51CTO技术博客

今天正式开通51CTO技术博客,今后会把自己工作和学习过程中的点点滴滴记录在此博客中!转载于:https://blog.51cto.com/dashuai/1160235

ML.NET Cookbook:(17)如何在分类数据上训练模型?

一般来说,所有的ML.NET学习器都希望这些特征是一个浮点向量。因此,如果您的一些数据不是一个float,您需要将其转换为float。如果我们的数据包含“分类”特征(比如“enum”),我们需要以某种方式对它们进行“…

有钱真的能为所欲为,微软用75亿美元解决了比尔盖茨的“心头大患”

全世界只有3.14 % 的人关注了数据与算法之美2018年6月4日,微软在官方博客上宣布:以75 亿美元的价格收购了全球最大的开源代码托管平台GitHub。谁也没想到,微软和开源这场长达几十年的战争,到最后双方竟然喜结连理了。不过&#xf…

linux 逻辑卷 pe size 4.00 mib大小怎么改,linux逻辑卷的建立

开始的时候系统各目录的挂载情况如下:增加了一个8G大小的scsi磁盘启动系统之后。[rootpoint1 ~]#fdisk �Cl增加了一个sdb设别。一、分区并格式化磁盘[rootpoint1 ~]#fdisk /dev/sdb输入m是显示帮助菜单输入n创建一个分区,选择p创建主分区&…

svn 自动同步到web站点目录post-commit.bat

为什么80%的码农都做不了架构师?>>> 需求分析: 在服务器上搭建了visualSVN server ,然后为了统一测试环境,又在服务器上搭建了web server。现在的需求是,当开发人员通过svn提交更新的时候,让svn自动将文件…

.NET之模型绑定和验证

介绍模型绑定就是接收将来自HTTP请求的数据映射到模型的过程。如果找不到模型属性的值&#xff0c;并不会报错&#xff0c;而是给该属性设置默认值。示例&#xff1a;比如我们有一个接口为[HttpGet("{id}")] public ActionResult<Pet> GetById(int id, bool do…

每日一笑 | 大学教室的真实写照...

全世界只有3.14 % 的人关注了数据与算法之美&#xff08;图片来源于网络&#xff0c;侵权删&#xff09;

linux调用v4l2获取视频,嵌入式Linux:V4L2视频采集操作流程和接口说明

一般操作流程(视频设备)&#xff1a;1. 打开设备文件。 int fdopen("/dev/video0",O_RDWR);2. 取得设备的capability&#xff0c;看看设备具有什么功能&#xff0c;比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability3. 选择视频输入…

面向对象技术——UML

UML&#xff0c;统一建模语言是一种可视化建模语言。 UML包括九种类型的图&#xff1a;用例图&#xff0c;类图&#xff0c;对象图&#xff0c;顺序图&#xff0c;协作图&#xff0c;状态图&#xff0c;活动图&#xff0c;构件图&#xff0c;及部署图&#xff0c;各种图示系统在…

面向.NET开发人员的Dapr——前言

Foreword前言With the wave of cloud adoption well underway, there is a major shift happening towards “cloud native” development, often built with microservice-architectures. These microservices are both stateless and stateful, and run on the cloud and…

美国返还中国文物,阿里谣言粉碎机获奖,教育部规范研究生培养,腾讯严打微信跑分活动,推动降低港澳漫游费,这就是今天的大新闻。...

今天是3月1日农历正月廿五今天星期五相信大家都很舍不得放下工作下面是今天的大新闻美国返还361件中国文物&#xff08;中国日报&#xff09;当地时间2月28日&#xff0c;美国政府向中国返还361件&#xff08;套&#xff09;流失文物。这些中国流失文物&#xff0c;由美国联邦调…

Linux怎么更新镜像,利用 Zsync 更新已有的 Ubuntu ISO 镜像

对! 是升级iso镜像, 不是升级系统. 从旧的镜像升级到新的镜像.可能有点迟了~大家都down好了镜像~ 我现在才有心情和时间写blog哦~由alpha的iso升到正式版都可以. 呃~ 当然,估计由alpha开始的话,下载量也与直接下载正式版区别不大~这么多人下载, 速度当然会慢喇~ 用zsync来升级镜…

你有做 Code Review 吗?

在代码的编写中有一个很重要的环节&#xff0c;经常会被忽视&#xff0c;那就是 Code Review ,据说在 Facebook、Google 这种互联网大公司&#xff0c;要求每一个提交都必须通过审查&#xff0c;对于每个工程师来说 Code Review 是一项十分重要的工作&#xff0c;甚至比写代码本…

PhotoShop CS5制作残旧的印章效果

编者按&#xff1a;不少网友喜欢个性印章效果&#xff0c;因此常常搜索个性印章在线制作。其实&#xff0c;Photoshop就可以完成个性印章制作。事实上&#xff0c;使用 Photoshop制作残旧的印章效果文字有多种方法&#xff0c;例如可以使用云彩滤镜。本文作者介绍了另一种实现方…

限时秒杀┃秒杀90%的玩具,让孩子爱上科学的彩虹实验2来了!

▲数据汪特别推荐点击上图进入玩酷屋之前小木有推荐过“彩虹实验”&#xff0c;这款是可以让孩子在探索中能够独立思考&#xff0c;主动地构建知识库&#xff0c;培养创造力。&#xff08;传送门&#xff09;让孩子们在家开展科学游戏&#xff0c;既能提升动手能力&#xff0c;…

linux accept过程,Linux协议栈accept和syn队列问题

161310 cient端收到synack后&#xff0c;根据ack值&#xff0c;使用SACK算法&#xff0c;只重传最后一个ack内容。Server端收到数据包&#xff0c;由于accept队列仍然是满的&#xff0c;所以server端处理也只是标记acked&#xff0c;然后返回。162884 client端等待几秒后&#…