饮水思源 - GNULinux精华区文章阅读
发信人: sudo (火星领航员), 信区: GNULinux
标  题: Firefox扩展开发实例入门之comic扩展
发信站: 饮水思源 (2009年02月14日23:44:23 星期六)

     情人节不能就这么闲着过去了,打了一个下午的dota,总觉得该做点什么了。于是
就写了个简单的实例入门,教教大家如何写firefox的扩展(注意,这里是extension,
和plugin还是有一定区别的)。这次的实例选的是看comic的插件。虽然若干年前的前辈
门为了让在linux下也能享受到comic已经写好了相当不错的extension,大家可以直接拿
来用。不过因为暂时没想到有什么比较简单的插件(HelloWorld除外)可以作为入门教
程,并同时让大家练练手的,就只有拿这个开刀了~还是希望能有人对这个有兴趣,有朝
一日弄出个我们SJTUer自己的Firefox版本来~废话到此为止,下面进入正题!

一.    基础知识

    最直接了当的入门请猛击这里:https://developer.mozilla.org/en/Extensions

    当然,如果这篇文章我什么也不介绍,肯定会被人诅咒的。于是,我就稍微说几句
来实现脱盲。

    首先,我们要知道,extension,扩展,顾名思义就是给firefox添加新功能的。比
如对于我们亲爱的comic.sjtu.edu.cn,“裸体”状态下的firefox中浏览点击播放图标
,我们的小萌狐狸是不会理你的,这时候,就需要给她弄点extension来调教调教,教教
她如何service。调教步骤如下:
    1.从网上找一个扩展,或者自己写一个;
    2.给小萌狐穿上这个扩展;
    3.“X掉,再打开”。这时候就已经调教完毕可以正常服务了。

    本文是教你如何写扩展,我们就要了解一下firefox扩展的文件格式。从网上下载下
来的都是个xpi后缀名的包,其实也就是个zip格式的包改了个名字而已。把这个包拖到f
irefox上就能进行安装。具体这个压缩包有些什么,我将在下一节和实例一起介绍~

    最后,说说想在小狐狸身上打主意都需要些什么要求:
    1.一定要是怪叔叔,例如sudo;
    2.会用电脑,要装有firefox(连情人都没有,怎么能过情人节~);
    3.懂英语,很可惜,这是只洋loli;
    4.(最好)看的懂HTML,JAVASCRIPT,XML。以上。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

二.    开发一个comic扩展

    这里,不会系统的教你如何去开发一个firefox的扩展,我没那本事。我只能以一个
看comic的小扩展作为例子,让你理解下firefox的扩展。至于能理解到什么程度,看你
造化了~~~这个扩展有别于现在大家用的那个comicview,以为是我自己写的,用于教学
的所以简化了很多内容,比如字符集处理等。

    整个开发的文件目录结构如下:

Comic:                  ------总目录
-----install.rdf            ------扩展安装信息文件
-----chrome.manifest            ------chrome目录描述文件
-----chrome:                ------chrome目录下是用户界面元素
----------content:          ------content目录下是扩展的源代码
---------------overlay.js       ------处理脚本
---------------overlay.xul      ------用户界面配置
---------------options.xul      ------扩展选项配置

    你看,其实整个下来也就5个文件,代码也很少,都很容易理解。下面我们就开始逐
个的看看这些文件的代码,和作用。

首先是install.rdf文件:

<?xml version="1.0"?>
<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#
    xmlns:NC="http://home.netscape.com/NC-rdf#
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    <RDF:Description RDF:about="urn:mozilla:install-manifest"
        em:id="comic@sudo"
        em:name="Comic Extension"
        em:version="0.1"
        em:creator="sudo"
        em:description="A simple extension to view movies on 
comic.sjtu.edu.cn"
        em:optionsURL="chrome://comic/content/options.xul">
        <em:targetApplication RDF:resource="rdf:#$Jw9Pt1"/>
    </RDF:Description>
    <RDF:Description RDF:about="rdf:#$Jw9Pt1"
        em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
        em:minVersion="1.5"
        em:maxVersion="3.*" />
</RDF:RDF>

    这个文件只是用来描述你开发的扩展的,比如说,em:id元素是你扩展的id,应该取
一个唯一的名字,比如可以用你的邮件之类的来命名。em:targetApplication中表示这
个扩展运用的mozilla应用是什么,以为mozilla除了firefox,还有thunderbird等一大
堆东西。
    这里em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"是firefox,下面的是版本
号。有些同学的firefox升级后部分插件扩展不能使用了,就是从这里检查出来的。多数
情况下只要修改一下最高版本号,死了的插件和扩展就又能原地复活了。再下面是插件
的描述,是安装后最终显示在附加组件中的信息。这个太简单了,我就不废话了:)


    然后是chrome.manifest文件:

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

    就两行,不用解释也看的出是干啥的~定义用户界面的内容的位置



    再看overlay.xul:

<?xml version="1.0" encoding="UTF-8"?>
<overlay id="comic-overlay"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul>
    <script src="chrome://comic/content/overlay.js"/>
    <popup id="contentAreaContextMenu">
        <menuitem id="play-comic" label="Play Online"
            oncommand="comic.play()"
            insertbefore="context-openlink"/>
    </popup>
</overlay>

    这里定义的是在浏览器中的显示方式,
     <script src="chrome://comic/content/overlay.js"/>指出我们要用到这个脚本
来处理。
     <popup id="contentAreaContextMenu">说明这里是一个弹出的菜单,contentArea
ContextMenu是我给这个菜单制定的ID,你想取啥随便你:)

<menuitem id="play-comic" label="Play Online" oncommand="comic.play()"
              insertbefore="context-openlink"
              image="chrome://comic/content/comic.png"/>
    指定了菜单中选项的一些属性,比如标签是Play Online,点击后执行的动作是comi
c.play(),这个是在overlay.js中的,下面会讲到。这里还可以指定位置,insertbefor
e是在哪个item之前插入这个选项。


    然后就是options.xul了,这个是配置扩展的地方,代码如下:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<prefwindow id="comic-prefs" title="Comic Setting"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul>
<prefpane id="perf-setting">
  <preferences>
    <preference id="mplayer" name="sjtu.comic.mplayer" type="string"/>
  </preferences>
  <vbox>
    <label value="mplayer location: "/>
    <textbox preference="mplayer"/>
  </vbox>
</prefpane>
</prefwindow>

    很简单,我们把mplayer播放器的位置保存在firefox的配置之中,配置的位置为sjt
u.comic.mplayer。这个是可以在浏览器中用about:config打开查的到的~然后就是些简
单的配置界面上的东西,我就不啰嗦了:)


    最后,最核心的代码当然要javascript上场了,请看overlay.js:直接在代码上注
释了,大家睁大眼睛了!

var comic = {
onLoad: function() {
      this.initialized = true;
      document.getElementById("contentAreaContextMenu")
        .addEventListener("popupshowing",this.showContextMenu,false);
    },
//这是加载时做的事,第二条是加入处理菜单时候显示的监听器

getURL:function(){
     var URL;
     if (gContextMenu && gContextMenu.link
           &&  gContextMenu.link.getAttribute("onclick")) {
       var result = gContextMenu.link.getAttribute("onclick")
               .match(/TruevodPlayEx\('(.*)','(.*)','(.*)'\);/i);
       if (result && result[1] && result[2]) {
         URL = "vod://"+result[1]+"/"+result[2];
         URL=URL.replace(/\\\\/ig, '/');
         URL=URL.replace(/\\/ig, '');
         URL = encodeURI(URL);
         URL = unescape(URL);
         return URL;
       }
     }
   },
//这个函数是解析页面上的vod的地址,用到正则表达式大家自己去分析分析:)
//这里要注意的是,我把URL转成unicode了,在linux下是能很好的工作的
//但在windows下,由于字符集的问题,碰到非拉丁的玩意就不行了~
//要打补丁的话~有点麻烦,这里就从简了呵呵~~~~

showContextMenu: function() {
           document.getElementById("play-comic").hidden = true;

           if (comic.getURL()) {
             document.getElementById("play-comic").hidden = false;
           }
         },
//这个是是否显示菜单项~当然只有在有vod的URL的情况下才显示,
//否则多出个menuitem多难看~
//这里注意那些id的匹配~

callProcess:function(path,args){
          var file = Components.classes["@mozilla.org/file/local;1"]
        .createInstance(Components.interfaces.nsILocalFile);
          file.initWithPath(path);
          var process = Components.classes["@mozilla.org/process/util;1"]
        .createInstance(Components.interfaces.nsIProcess);
          process.init(file);
          process.run(false, args, args.length);
        },
//firefox调用外部程序,我稍微包装了下,参数为程序路径和穿的参数
//这里参数也就是vod视屏的链接啦

play:function(){
       var path =Components.classes["@mozilla.org/preferences-service;1"]
            .getService(Components.interfaces.nsIPrefBranch)
            .getCharPref("sjtu.comic.mplayer");
       var URL = comic.getURL();
       var args = [];
       args.push(URL);
       comic.callProcess(path,args);
     }
};
//播放函数,当在菜单中点击时就调用这个,其先从配置中读取mplayer的位置

window.addEventListener("load", function(e) { comic.onLoad(e); }, false);
//这个自己理解:)

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


三.    小结

    总觉得在关键的地方写的太少了~算了反正代码也不长,读起来也不算太难大家自己
理解理解吧:)这个版本是被我“和谐”后的~也就是隐藏了#XX#功能后的版本,也做了
很大的简化,在linux下是非常正常的运行的,windows下只能搞搞文件路径中没有中文
的。当然,当做教学使用应该是足够了。有什么问题和建议都欢迎来GNULinux提~也欢迎
更多的人参与到开发中来,体验开发的乐趣:)

    代码:(xpi文件)
    http://bbs.sjtu.edu.cn/file/GNULinux/1234626218274327.xpi

附一:
    对于mplayer:
    linux下推荐使用打过utf的vod补丁的,推荐smplayer前端
    扩展配置中直接输入位置,如/usr/local/bin/mplayer,/usr/local/bin/smplayer

     windows下推荐使用ww编译版(http://mplayer-ww.sourceforge.net/)
    扩展配置重输入位置,斜杆需转义,如C:\\Program Files\\mplayer\mplayer.exe

附二:
    开发出来的扩展的打包:用压缩软件打包成zip格式文件,然后修改后缀为xpi即可

附三:
    非常感谢BanWuPieXun帮我重新排版:)
※ 修改内容:·sudo 于 02月15日11:12:22 修改本文·[FROM: 211.80.59.137]

[返回上一页] [本讨论区]