标签:plugin

浏览模式: 标准 | 列表 | 图文

乔大妈:【插件】史上最强EditPlus插件OpenCTags使用指南--EditPlus开发者必备

这是乔大妈推荐的插件,在推荐的时候用上了:推荐积德,不推荐积业
好吧,我为了积德推荐一下,当然乔大妈说了,使用的人应该推荐。嗯,我不用Editplus很久了。
原文来自:

首先:
感谢Romeo JunCU的卓绝工作,是他让我们拥有史上最强EditPlus插件OpenCTags,让EditPlus插上了翅膀

demo.png

使用:
1. 将OpenCTags解压后的所有文件,拷贝到EditPlus\User Tools\ctags\下

2. 在EditPlus的用户工具中,进行如下设置:
a.
菜单名称:CTags Build
命令:......\EditPlus\User Tools\ctags\ctags.exe (请根据实际路径设置)
参数:-R *
初始目录:$(FileDir)
动作:捕捉输出
输出模板:默认
保存:无

b.
菜单名称:OpenCTags
命令:......\EditPlus\User Tools\ctags\OpenCTags.exe (请根据实际路径设置)
参数:-word "$(CurWord)" -editor editplus -sel "$(CurSel)" -file $(FilePath) -line $(CurLine) -one
初始目录:$(FileDir)
动作:退出时关闭窗口
输出模板:默认
保存:无

3. 使用方法:
a. 到项目的根目录,打开一个文件,然后执行“CTags Build”,等待建立ctags完成,在根目录会生成tags文件,注意在svn/git/hg/cvs等中设置忽略该文件
b. 打开项目内任意文件,选中需要查看的关键字(类名或者函数方法名或者任意玩意),执行“OpenCTags”,将会打开OpenCTags提示窗口,提示对应的tags信息
c. 提示窗口中,会给出匹配的名称,原型缩写,以及所在的文件相对路径,鼠标移动上去,会显示完整的原型提示,双击,会自动打开对应的文件并定位到对应的位置
d. 提示窗口中,左则的图标代表不同的类型,包括但不限于:类、方法/函数、常量定义、变量等等
icon.png

附加:
0. ctags是个什么东东?格纹滚,自己上网查去,这个不知道,等于没有编过程。
1. 该插件,来自于sf的OpenCTags,我只是经过简单完善和给予中文说明后提供;再次感谢Romeo JunCU的卓绝工作。
2. 如果是editplus2,请使用-editor editplus2
3. 也可参考以上设置,为其他编辑工具配备
4. 欢迎推广,欢迎传播至少一人,一旦使用,将自动接收以下锲约:
传播积德,不传播积业!!!

5. 如有问题和建议,请致信honestqiao@gmail.com,谢谢

6. 欢迎访问史上最强PHP中文手册--PHP手册中文翻译补完计划 --http://code.google.com/p/phpdoc-zh/

问题:

Q. Could not find install dir for editor editplus?
A. 找不到EditPlus的安装路径,绿色版本的一般会出现该问题;
打开“EditPlus安装路径.reg”,将其中的EditPlus路径修改为你自己的,然后导入即可。
或者打开regedit,在HKEY_CURRENT_USER\Software\ES-Computing\EditPlus 3\Install,设置Path字符串属性,值为EditPlus安装路径,不存在的就建立新的
如果是EditPlus2,记得修改为EditPlus 2

Q. 双机无法打开文件?
A. 请打开“Microsoft Visual Studio Spy++.exe”,点搜索菜单,点查找窗口,然后点那个瞄准器,拖到EditPlus的编辑代码的那个位置(需要预先打开一个文件),然后告诉 我,Spy++的“窗口搜索”的类那个地方显示的信息,例如我的是“AfxFrameOrView90su”,你的呢?
Spy++.png

Q. 修改或者增加新的代码后,匹配不到怎么办?
A. 此时,需要及时再来一次:CTags Build

下载:enCTags.tar.gz (1.25 MB)
jQuery SubClass 带来的新的变化

jQuery SubClass 带来的新的变化

jquery在1.5的时候多了一个subclass,代码大约如下:

subclass: function(){
function jQuerySubclass( selector, context ) {
return new jQuerySubclass.fn.init( selector, context );
}
jQuerySubclass.superclass = this;
jQuerySubclass.fn = jQuerySubclass.prototype = this();
jQuerySubclass.fn.constructor = jQuerySubclass;
jQuerySubclass.subclass = this.subclass;
jQuerySubclass.fn.init = function init( selector, context ) {
if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
context = jQuerySubclass(context);
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
};
jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
var rootjQuerySubclass = jQuerySubclass(document);
return jQuerySubclass;
},
很多看到这个代码的人都认为这个功能是用来优化插件的,因为现在jQuery的插件越来越多,有类似功能,类似名称的插件也越来越多了,所以,同名插件带来的困扰也就更多了。

未来怎么办,jQuery鼓励用户开发插件,但插件总不能老是给用户带来麻烦吧?所以这个subclass就成了新的插件机制所必备的方法,利用subclass来创建一个新的实例(即所谓的继承,当然也能覆写父类[jQuery]的方法 )。

只是这样的频繁继承,肯定会造成效率降低吧。怎么样既能继承,又不降低效率,这恐怕就是未来jQuery团队要考虑的事情了?但是否靠什么behavior这种行为的方式来加载呢?现在都在讲究这种行为触发性的插件。jQuery是不是未来也会采用这种方式呢。

loadMask

loadMask

loadmask 这个小插件不错,可以让指定的DIV上出现那种类似于extjs的等待框,当内容加载完毕后,可以通过 unmask方法来解除等待框的状态。。。

程序也很小,不到2K。当然不是我写的。。是google上的一个小插件。嗯,其实我也会写,但我真不会CSS。。。

看介绍:

LoadMask jQuery plugin can mask DOM elements while their content is loading or changing to prevent user interactions and inform that some background task is still running. It is very light (~2Kb) and easy to use.

The behavior of this plugin is largely based on handy Element.mask() method from ExtJS Framework.

也有例子:You can try online demo here.

内容在这里:http://code.google.com/p/jquery-loadmask/

cnbeta:2010年最佳jQuery插件

cnbeta:2010年最佳jQuery插件

这个玩意,纯收藏了,象QuickSand这个玩意已经被很多人转过了,每年都能在各个推荐中出现,真没劲。还有colortip,如今其实已经真不算稀奇了吧。不过还是转一下,因为对其中有两个插件非常感兴趣:Lettering.js和Masonry。

好吧,上原文【文字版】:

在前两周国外知名博客WDL先后分享了“2010最佳系列”中的“最佳免费WordPress主题”和“最佳免费字体”, 在这个星期又发布了2010年最佳jQuery插件。在2010年,JavaScript框架继续日渐普及,这使得大量的插件被开发出来。满目琳琅,难以 选择心头之好。WDL的作者从大量的优秀jQuery插件精心筛选出一些对Web Designers有帮助的和具备非常不错的视觉效果的Best of the best。

2010年最佳jQuery插件(排名不分先后):

Nivo Slider

一个加载设置拥有9种过度效果的超级smooth slider,它还支持如链接图像和键盘导航等内容。

Quicksand

通过一个非常不错的洗牌动画实现选项内容重新排序,只需要指定源容器和替换源的目标collection 。新元素将会以奇特缩放+阿尔法效果出现,消失的元素(non-existant in destination collection)平滑地消失或重新排位,移动到它们的目标位置。

Spritely

Spritely 是一个由Artlogic开发的 jQuery插件,用于使用纯HTML和JavaScript创建动态物体和背景动画。

Lettering.js

Lettering.js是一个轻量经的、易于使用的 jQuery插件,可创造出极具个性的网页排版。

Colortip

Colortip可转换你的页面元素的标题属性为一系列色彩丰富的提示(当你的鼠标移动到不同的标题上会出现不同颜色的字体文本提示)。支持六种色彩主题,这样你可更加容易融合到你的个人网页中去。

Masonry

Masonry是一个 jQuery布局插件. 你可以将它看作CSS floats的另一面。浮动元素的排列是先水平后垂直,Masonry排列内容是根据一个网格先垂直后水平的。

gvChart

gvChart是一个使用Google Charts了的jQuery插件,可通过HTML table tag的数据实现交互可视化。它非常容易上手,此外它支持创建五种风格的图标。

Animated table sort

这是一个用于创建表格的jQuery插件,所创建的表格可以根据不同的列项目进行A-Z,升序排列,切换效果非常不错。

jQuery Image Scale Carousel

网站图片保持完整的纵横比比什么都重要。这个jQuery插件可以完美地在slider展示你所有的图片,而不需担心产生变形。 jQuery Image Scale Carousel插件自动改变你所有图片到适合大小,一切都是那么的简单。

YoxView

YoxView是一个免费的多媒体播放jQuery插件。它易于使用,功能丰富。你可以用它来展示各种媒体,如图像,视频,内嵌的内容,iframes,Flash等等。

MK编译 via WDL

原文地址:http://www.x-berry.com/best-jquery-plugins-of-2010

--EOF--

然后那个gvchart也可以,方便你调用了google chart的一些参数了

Wordpress自动升级和plugin插件更新的问题

Wordpress自动升级和plugin插件更新的问题

为了文章中所说的问题,我删除了我VPS上的wordpress。如果早知道这个问题,我就不会换了。不过,想想WORDpress在那么小内存的VPS上跑,也会很痛苦吧?所以还是让他跑跑一些简单的内容就完事了。原文在http://www.jefflei.com/post/884.html

--START--

Wordpress2.7的一键自动更新很好用。可是在使用Wordpress插件自动更新和安装时,有时发现需要提示输入ftp信息:
FTP Connection Information
Host:
Username:
Password:

这是Wordpress的一个bug,在某些文件系统上有问题从wordpress2.5到2.7都一直没有更新,在国外网站上查了下修复方法如 下:

1. 编辑wp-admin/includes/file.php找到以下这行
if(getmyuid()==fileowner($tempFile)){
把这句中把getmyuid改成posix_getuid

2. 完成以上修改应该不会再要输入ftp信息了,但是有时候会告知目录不对,在wp-content目录下建立upgrade目录
chown www:www wp-content/upgrade
chmod +w wp-content/upgrade

做完以上设置应该就可以自动更新了。

--EOF--

根据我的估计,有两个人可能会用到这个,虫少侠(http://enjoyphp.com)和拉拉(http://www.ifotos.net)。我想,他们两个看到我这篇博客的时候,估计会感动的帮我点广告的吧?

[转载]一步一步学习Firefox扩展的开发[据说这将是一个系列]

Firefox的插件也曾经研究过,对于XUL感觉也有点痛苦,当初想研究它是为了给自己的博客增加插件,可以方便的让自己在找到好的资料的时候,可以直接通过插件发送到博客上。但最终我还是放弃了。没有什么理由。。。。

看到有人在贴一步一步学习的教程,又有点拾起了回忆,如果有可能,这个系列,我会在这个作者写的同时,也一点点的转载。
希望作者不要见怪,转载完了,我也贴点我在开发的时候遇到的问题之类。当然一切都到元旦后。。。
原文网址:http://www.cnblogs.com/uubox/archive/2008/12/25/1361278.html
作者:DOMS
内容:Firefox提供开放、强大且灵活的扩展机制,因此衍生出了大量功能丰富的扩展组件,这些扩展组件甚至可以说是某些用户爱上firefox的主要因素。
比较可惜的是firefox扩展开发的中文资料相对比较少,因此在这里我会从简单到深入介绍开发firefox扩展的一些技术及常遇到的问题。

本文主要内容:

  • 制作一个包含工具栏按钮及右键菜单的简单组件
  • 解决扩展安装后工具栏按钮却不显示的问题


因为这个组件不需要设计交互窗口,因此开发过程相对简单,下面是这个组件运行的效果图:
firefox_addons_demo1_view.jpg

在开始之前先介绍一下几个网址:

  1. https://developer.mozilla.org/en/Extensions 官方开发网,类似MSDN,是开发时的主要参考资料;
  2. https://developer.mozilla.org/en/Building_an_Extension,官方的一个基础教程,笔者通过此篇文章而入门;
  3. http://ted.mielczarek.org/code/mozilla/extensionwiz/,一个在线的创建扩展的向导,如果你想立即创建一个属于自己的扩展,可以试试用这个向导制作一个雏形,然后再自己慢慢添砖添瓦。本文所讲的例子也是用这个向导制作出来的。

另外还有本文例子的源代码:http://www.uushare.com/user/csprogram/file/1139797。

好了,下面就开始讲解本文的示例组件:uusharedemo1的制作过程。

1、了解扩展组件的构成

Firefox 扩展组件是以一个xpi文件的形式发布的,而xpi文件实际上是zip压缩包文件,我们只要把Firefox扩展组件下载回来(用右键另存为即可下载), 把文件扩展名改为zip即可解压并看到所有的源代码,有时可能还会在压缩包里面看到jar格式文件,这个也是zip压缩包,改名解压即可看到源代码。因此 多下载优秀的扩展回来慢慢研究其源代码也不失为一种快速的学习方法。
一般xpi文件内部有(但不一定都有)如下目录及文件:
xpi_filetree.png
其中 uusharedemo1 为本文示例组件的名称,可以看到压缩包首层有:install.rdf及chrome.manifest两个文件以及一个chrome目录。

  • install.rdf:是该组件的安装信息,例如组件的名称、版本、作者等信息,XML格式;
  • chrome.manifest:是用于描述该组件由哪些文件组成的,即一个资源列表;


在chrome目录里就是该组件的主要内容了,一般有:content、defaults、locale、skin等目录,它们的作用如下:

  • content:这个是最主要的目录,包含组件的界面定义以及程序代码,其中xul文件是界面定义文件,类似SilverLight的XAML文件,同样是XML格式;js文件是组件功能实现的代码,全部用javascript实现的。
  • skin:存放css样式表文件及资源位图,css是用来控制组件界面外观的。
  • locale:如果想让组件能够在不同语言的firefox里显示正确的文本,则将不用的语言列表放到此目录,firefox会自动加载合适的语言文件。这点有些类似Win32PE可执行程序中的资源文件。
  • defaults:存放一些默认值,一般不要此目录也可以;


我 们可以把Firefox程序认为是一个平台,而我们看到firefox浏览器外观本身也是用跟扩展组件类似的结构搭建起来的,感兴趣的朋友可以解压 “C:\Program Files\Mozilla Firefox\chrome”目录下的jar文件观摩一下firefox浏览器外观的源代码,所以我们制作的扩展组件也会成为firefox浏览器自身 的一部分,可以实现非常强大而灵活的功能(例如Firebug这个神奇的组件)。相对来说,开发ie扩展程序显得困难多了,除非只是想做工具栏按钮和右键 菜单(用注册表即搞定),否则需要使用VC,VB,Delphi这些工具开发COM组件才能完成。

如果想了解firefox浏览器本身各个元素的定义,但又不想阅读chrome目录下的脚本代码,可以安装 DOM Inspector 这个组件,这个组件有如开发web时的FireBug,是开发具有界面的扩展组件时的神兵利器!

提醒:自己编写的组件代码文件最好用“UTF-8”格式保存,一般可以减少很多麻烦的问题。

2、认识install.rdf

install.rdf包含组件安装信息,本文例子中它的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>uusharedemo1@uushare.com</em:id>
<em:name>Uushare书签(示例)</em:name>
<em:version>1.0</em:version>
<em:creator>KwanhongYoung</em:creator>
<em:description>这是一个模仿Uushare书签插件的示例</em:description>
<em:homepageURL>http://www.uushare.com</em:homepageURL>
<em:iconURL>chrome://uusharedemo1/content/uusharedemo1.png</em:iconURL>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->
<em:minVersion>1.5</em:minVersion>
<em:maxVersion>3.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>



文件里有很多是固定的写法,这里就不一一讲解了。
第 5行的id是组件的一个标识符号,类似Windows里COM组件的CLSID,用于区别其他组件。可以使用 xxx@yyy.zzz 这样类似email地址的格式组成,而这个“email地址”不要求是真实或有效的。也可以用的GUID来标识,例如“{c45c406e- ab73-11d8-be73-000a95be3b12}”是WebDevelop组件的标识符。

name、version、creator、description、homepageURL分别是组件的名称、版本、创建者的姓名、组件描述、组件官方网站地址。
iconURL用于显示组件的图标,格式一般用32x32pixel的png图片。
这里出现了chrome://这样的地址,跟http://和file://协议类似,chrome://也是用来定位资源的。格式是:
chrome://组件名称/目录路径/文件名
需要注意的是,这里的组件名称可以跟em:name属性中所指定的名称(用于显示的)不一样的,并且这个组件名称需要在chrome.manifest里定义。
这些信息在安装完组件之后能够在firefox的组件管理列表显示,如下图:

firefox_addons_demo1_item.jpg

第14行比较重要,用于标识当前组件是用于哪个平台的(firefox/Thunderbird/SeaMonkey等),如果开发的组件是给firefox用的,则id={ec8030f7-c20a-464f-9b0e-13a3a9e97384}。
第 15、16行用于指定当前组件适用于firefox的哪些版本,因为firefox从1.5到3.0有些地方有所改变,所以如果你不知道自己的组件在哪些 版本下可运行的话,最好先测试一下,然后准确地指定一个范围值,上例的值表示该组件适用于firefox1.5到3.0及3.0所有修订版。版本号码不能 自己随便造,这里有一个完整的列表:
https://addons.mozilla.org/en-US/firefox/pages/appversions

3、认识chrome.manifest

这是资源列表文件,内容如下:

content uusharedemo1 chrome/content/
locale uusharedemo1 en-US chrome/locale/en-US/
skin uusharedemo1 classic/1.0 chrome/skin/
overlay chrome://browser/content/browser.xul chrome://uusharedemo1/content/firefoxOverlay.xul
style chrome://global/content/customizeToolbar.xul chrome://uusharedemo1/skin/overlay.css



前3行每一行表示一种类型的资源的地址,格式是:
资源名称<Tab>组件名称<Tab>参数<Tab>目录路径
其中组件名称是自定义的,只要跟其他组件名不一样并且使用全小写字母即可。定义好之后,就可以使用chrome://地址来定位资源了。例如,假设当前开发文件路径是“c:/dev/uusharedemo1/”,那么:
chrome://uusharedemo1/content/uusharedemo1.png 实际指的是 c:/dev/uusharedemo1/chrome/content/uusharedemo1.png 这个文件。

第4行及第5行表示将当前组件的界面结合到系统本身的界面,因为当前组件会修改firefox本身的工具栏及右键菜单,所以需要加上这两行。

4、default/、skin/、locale/

这几个目录下的文件比较简单,下载本文的源代码查看一般能明白其中的意思,为了节约篇幅这里就不讲解了,等以后我写后续的章节时再详细介绍。

5、认识 content/firefoxOverlay.xul

Firefox的所有窗口都是使用xul文件定义的,例如在地址栏输入:
chrome://browser/content/aboutDialog.xul
(这个地址对应的源文件是:“C:\Program Files\Mozilla Firefox\chrome\browser.jar/content/aboutDialog.xul”
就可以看到firefox的“关于”对话框,在这个例子里我们用firefoxOverlay.xul定义一个工具栏按钮、右键菜单以及一个工具菜单项,源代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 下面一行指明当前窗口控件所引用的样式表文件 -->
<?xml-stylesheet href="chrome://uusharedemo1/skin/overlay.css" type="text/css"?>

<!-- 这行指明当前窗口控件所使用的语言文件,注意这里不需指定语言的名称(即zh-CN或en-US等),只需指明文件名即可
有了语言文件之后,所有控件的文本(即text/label等属性)都统一写到语言文件里。 -->
<!DOCTYPE overlay SYSTEM "chrome://uusharedemo1/locale/uusharedemo1.dtd">

<overlay id="uusharedemo1-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<!-- 这行用于指定当前窗口控件的事件(如单击事件)触发后所执行的代码所在的文件 -->
<script src="overlay.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="uusharedemo1-strings" src="chrome://uusharedemo1/locale/uusharedemo1.properties"/>
</stringbundleset>

<menupopup id="menu_ToolsPopup">
<menuitem id="uusharedemo1-hello" label="&uusharedemo1.label;"
oncommand="uusharedemo1.onMenuItemCommand(event);"/>
</menupopup>

<popup id="contentAreaContextMenu">
<menuitem id="context-uusharedemo1" label="&uusharedemo1Context.label;"
accesskey="&uusharedemo1Context.accesskey;"
insertafter="context-stop"
oncommand="uusharedemo1.onMenuItemCommand(event)"/>
</popup>

<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="uusharedemo1-toolbar-button"
label="&uusharedemo1Toolbar.label;"
tooltiptext="&uusharedemo1Toolbar.tooltip;"
oncommand="uusharedemo1.onToolbarButtonCommand()"
class="toolbarbutton-1 chromeclass-toolbar-additional"/>
</toolbarpalette>
</overlay>

menupopup 段定义了一个位于“工具”菜单栏下的项目,其中id是菜单项的名称,我们自己添加的菜单项、按钮等结合到firefox本身的控件的id必须惟 一;label属性是菜单项显示的文本,这里因为引用了语言文件,所以真正显示的文本内容位于语言文件(uusharedemo1.dtd)里标有 uusharedemo1.label 这行定义的后面;oncommand属性定义菜单被点击后执行 overlay.js 里面的那一个方法过程。

popup 段定义了一个右键菜单项,accesskey为菜单项的快捷键(即带下划线的字母),insertafter为新菜单项所出现的位置位于id为 “context-stop”(即“停止”)这项的后面,如何得知某一项菜单项的id呢?出动Dom Inspector 吧。包括firefox工具栏上面的所有按钮的id,都可以用Dom Inspector查看得知。

toolbarpalette段定义了一个工具栏按钮,其中tooltiptext为鼠标停留在这个新按钮上面时所显示的提示文本。

上面一段代码并没有定义自己的窗口,我会在下一章再讲解。

6、认识content/overlay.js

overlay.js 文件是专门为上面的firefoxOverlay.xul服务的,(怎么知道的呢?在firefoxOverlay.xul文件的第13行有引用啊)。在 xul文件里可以看到菜单被点击之后会调用一个名叫“onMenuItemCommand”的方法过程,而工具栏按钮被点击之后会调用 “onToolbarButtonCommand”方法过程。我们想在他们被点击之后做什么事情呢?为了演示如何在js里编写调用firefox对象的代 码,这里模仿uushare书签的功能,让菜单和按钮点击之后调用Uushare.com网站上的书签服务的添加书签的接口,接口是这样的:

http://www.uushare.com/bookmark/save?v=1&client=ff10&noui=yes&jump=close&url=XXXX&title=YYYY&content=ZZZZ

其中XXXX为待收藏的网页地址,YYYY是网页的标题,ZZZZ是网页中选中的文本。所以我们需要在js里获取当前网页的URL、Title以及被选中的文本。
下面是例子中的代码:

var uusharedemo1 = {
onLoad: function() {
// initialization code
this.initialized = true;
this.strings = document.getElementById("uusharedemo1-strings");
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", function(e) { this.showContextMenu(e); }, false);
},

showContextMenu: function(event) {
// 根据上下文决定显示/隐藏右键菜单项
// see http://kb.mozillazine.org/Adding_items_to_menus
document.getElementById("context-uusharedemo1").hidden = gContextMenu.onImage;
},

onMenuItemCommand: function(e) {
uusharedemo1.addToUushareBookmark();
},

addToUushareBookmark: function() {
//这里调用 uushare.com 书签API的接口
var location, title, desc;
var browser = window.getBrowser();
var webNav = browser.webNavigation;

if (webNav.currentURI)
location = webNav.currentURI.spec;
else
location = gURLBar.value;

if (webNav.document.title) {
title = webNav.document.title;
}
else {
title = location;
}

var focusedWindow = document.commandDispatcher.focusedWindow;
var winWrapper = new XPCNativeWrapper(focusedWindow, 'getSelection()');
desc = winWrapper.getSelection().toString();

var serverUrl = "http://www.uushare.com/bookmark/save?v=1&client=ff10";
var saveUrl = serverUrl + "&noui=yes&jump=close&url=" + encodeURIComponent(location) + "&title=" + encodeURIComponent(title) + "&content=" + encodeURIComponent(desc);
window.open(saveUrl, 'uusharev1', 'location=yes,links=no,scrollbars=yes,toolbar=no,width=550,height=550');
},

onToolbarButtonCommand: function(e) {
uusharedemo1.addToUushareBookmark();
}

};
window.addEventListener("load", function(e) { uusharedemo1.onLoad(e); }, false);



相信对于熟悉js的朋友上面的代码并不难。大部分代码跟在普通html页面里写的差不多,只是firefox提供了内置的一些对象需要翻查官方的文档才能知道它的作用及其成员。

7、打包、测试

至 此我们的扩展组件就编写完毕了,下面开始做安装测试。首先用压缩工具将install.rdf、chrome.manifest以及chrome目录打包 成一个zip格式的压缩包,要注意的是这2个文件及chrome目录必须在压缩包的顶层目录,否则安装会失败。然后将压缩包文件的扩展名更改了 “xpi”,并把这个文件拖到firefox窗口当中,firefox应该会提示安装并要求重启,重启完之后若无问题即可看到我们制作的“工具”栏菜单 项、右键菜单等。如果组件的源代码有错误,例如xul文件或js脚本文件有错误,一般什么预期的效果都看不到,这时需要重复卸载->修复错误代码 ->重新打包->安装这几个步骤。
开发firefox扩展组件最烦人的事情可能就是调试问题了,幸好firefox提供了一些工具,例如 Extension Developer's Extension 等可以减少一些麻烦。

8、工具栏按钮怎么看不到?如何解决

刚 才我们测试的时候会发现虽然右键菜单、“工具”菜单项都显示出来了,不过怎么工具栏上面的按钮没有显示呢?估计这是很多扩展组件开发者都会遇到的共同问 题,原来firefox将非系统默认的按钮都放到按钮箱里,如果想显示这些按钮,需要对着工具栏右键鼠标,选择“定制”,然后将需要的按钮拖出来才行。这 个特性某种程度上可以给用户最大的选择权,不过另一方面这特性给初级的用户带来困惑。所以我们最好能将工具栏按钮自动显示出来。下面是目前“民间”常用的 方法:
大致思路跟我们平时修改windows注册表类似。firefox工具栏上面的按钮布局被储存在firefox设置表中 navigator-toolbox/nav-bar/currentset 键下面,键的值为当前各个工具栏按钮id的以逗号分隔而连在一起的字符串。我们必须读出这个字符串,并把自己的按钮的id(本示例中按钮id为uusharedemo1-toolbar-button,见xul文件)掺和在其中,再写入新的字符串到设置表。
那 么在什么执行此连串操作呢?很明显不能在每次firefox启动时都执行,因为这样会耗时并影响firefox的启动速度,“民间”的方法是先在设置表中 检查某个自定义的键(例如extensions.uusharedemo1)的值,如果这个值为空的或者不等于当前组件的版本,则执行上述的连串操作,并 写入当前组件的版本号。所以完整的过程是:

  1. 读取某个自定义键(extensions.uusharedemo1)的值;
  2. 如果键的值为空或者不等于当前组件版本号,则下一步,否则退出过程;
  3. 读取navigator-toolbox/nav-bar/currentset键的字符串;
  4. 寻找自己按钮的id是否在字符串当中,不存在则将id连接到地址栏id(urlbar-container)的前面;
  5. 将新字符串写入键;
  6. 写当前组件的版本号到自定义键。

下面是上面过程的js代码:

var uusharedemo1 = {
strVersion : '1.0',

getUBKCharPref: function(strPrefName) {
this.prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
try {
return(this.prefManager.getCharPref("extensions.uusharedemo1." + strPrefName));
} catch(e) {
return(false);
}
},

setUBKCharPref: function(strPrefName, strValue) {
this.prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
this.prefManager.setCharPref("extensions.uusharedemo1." + strPrefName, strValue);
},

onLoadEvent: function()
{
//first load
var strPrefVersion = this.getUBKCharPref('version');

if(strPrefVersion != this.strVersion) {

var bolWongPostButtonExists = document.getElementById('uusharedemo1-toolbar-button');

if(!bolWongPostButtonExists) {
var objToolbox = document.getElementById("navigator-toolbox");
var strChild = '';
var strSet = '';
var objNavBar = false;

if(objToolbox) {
for (var i = 0; i < objToolbox.childNodes.length; ++i) {
if(objToolbox.childNodes[i].id == "nav-bar" && objToolbox.childNodes[i].getAttribute("customizable") == "true") {
objNavBar = objToolbox.childNodes[i];
break;
}
}
}

if(objNavBar) {
for (var i = 0; i < objNavBar.childNodes.length; i++) {
if(objNavBar.childNodes[i].id == "urlbar-container") {
if(!bolWongPostButtonExists) {
strSet += "uusharedemo1-toolbar-button,"
}
}
strSet += objNavBar.childNodes[i].id + ",";
}

strSet = strSet.substring(0, strSet.length-1);
objNavBar.currentSet = strSet;
objNavBar.setAttribute("currentset", strSet);
objNavBar.ownerDocument.persist(objNavBar.id, "currentset");
BrowserToolboxCustomizeDone(true);
}

strSet = strSet.substring(0, strSet.length-1);
toolbar.currentSet = strSet;

if(toolbar.setAttribute) {
toolbar.setAttribute("currentset", strSet);
}

toolboxDocument.persist(toolbar.id, "currentset");
BrowserToolboxCustomizeDone(true);
}

this.setUBKCharPref('version', this.strVersion);

}//end if first load
}
}

window.addEventListener("load", function() { uusharedemo1.onLoadEvent(); }, false);


为了简单起见,这段代码并没有整合到示例的压缩包当中,如果想查看整合后的结果,可以参考uushare书签组件的源代码:http://www.uushare.com/help/bookmark/toolbar_firefox。

本文完。