手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:mozilla

[转]为什么所有浏览器的userAgent都带Mozilla

为什么浏览器的userAgent第一个都是mozilla呢?看了这个博客后才发现,原来,历史上发生了N多事情,在浏览器大战里,NetScape才是最后的赢家,虽然它已经消失在茫茫人海.
转自[作者:Eamonn 发布时间:2012-01-06 20:04]
时间离现在都有1年过去了,虽然在这一年里发生了很多变化,比如...opera居然也投奔了webkit,看来下一个就是webkit一统江湖了.不知道IE是否能够抗住,firefox呢???

好了不多说了,直接上原文吧.

http://www.eamonning.com/blog.php?id=289
  1. 最早的时候有一个浏览器叫NCSA Mosaic,把自己标称为NCSA_Mosaic/2.0 (Windows 3.1),它支持文字显示的同时还支持图片,于是Web开始好玩起来。  
  2.   
  3.   
  4. 然后出现了一个新的网页浏览器,“Mozilla”,其实就是“Mosaic终结者”的意思,这搞的Mosaic很不爽,(毕竟Mosaic出道早,江湖老),新浏览器最后正式公布的名称是Netscape,它把自己标称为Mozilla/1.0 (Win3.1),更好玩了。Netscape支持框架显示,后来框架在大家中间流行起来了,但Mosaic不支持框架啊,于是伟大的“用户代-理人探测”技术出现了,如果是“Mozilla”,那就发给支持框架的页面,至于其他的浏览器,则发给不含框架的页面。  
  5.   
  6.   
  7. Netscape想逗Microsoft玩儿,把Windows叫做“几乎不曾做过调试的设备驱动器”,后者很恼火。Microsoft于是推出了自己的 网页浏览器,叫做Internet Explorer,希望它能成为“Netscape终结者”。Internet Explorer也支持框架,但它不是Mozilla啊,所以没人给它发送带有框架的页面。Microsoft慢慢烦躁起来,不再寄希望于网站管理员逐渐 认识IE并给它发框架,而是宣称自己是“兼容Mozilla”的,开始模仿Netscape,把自己标称为Mozilla/1.22 (compatible; MSIE 2.0; Windows 95),这样Internet Explorer也能收到框架了,整个Microsoft狂喜,但网站管理员开始有点被搞糊涂了。  
  8.   
  9. Microsoft把IE和Windows一起卖,并且把产品也弄得比Netscape更好了,拉开了第一场浏览器之战。结果和大家知道的一样,Netscape被干掉了,Microsoft大胜、大喜。但是后来Netscape以Mozilla的新名称重生了,构造了Gecko,标称其为Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826,Gecko属于渲染引擎,表现优异。Mozilla开发了Firefox,标称为Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0,并且Firefox表现也非常优秀。Gecko扩张迅速,一些浏览器使用了它的代码并标称为Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1 ,这是一个,还有Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0,另一个,它们都伪装成Mozilla,同时也都是基于Gecko支持的。  
  10.   
  11.   
  12. Gecko表现优秀,IE则很差劲,于是身份甄别再次发生,输送给Gecko的是设计良好的网页代码,其他浏览器就没有这个待遇了。Linux的跟随者很伤心,因为他们创建了基于KHTML引擎支持的Konqueror,但却不会被输送好代码,虽然他们自己认为KHTML和Gecko一样优秀,于是Konquerer开始伪装自己“像Gecko”那样以得到好的网页,并标称自己为Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko),这个世界更让人困惑了。  
  13.   
  14.   
  15. 后来出现了Opera这样的主儿,宣称“允许用户自己决定让浏览器装成谁”,它的菜单中提供了Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51, Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51,Opera/9.51 (Windows NT 5.1; U; en) 供大家来选择,选谁是谁。  
  16.   
  17.   
  18.   
  19. Apple开发了Safari,使用了KHTML,同时也增加了很多新特性,后来干脆一锅煮,另起炉灶叫了WebKit,但是它有希望能够得到那些为KHTML编写的网页,于是Safari标称自己为Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5,这个世界更混乱了。  
  20.   
  21.   
  22.   
  23. Microsoft越来越担心Firefox的发展,重新启动了Internet Explorer的开发,标称自己为Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ,可以很好的渲染代码,但那要看网站管理员是否指示它这么做。  
  24.   
  25.   
  26.   
  27. Google也开发了自己的浏览器Chrome, 使用了Webkit,有点像Safari,希望能得到为Safari编写的网页,于是决定装成Safari。这样啊,Chrome使用了WebKit渲染 引擎,想装成Safari,而WebKit呢又伪装自己是KHTML,KHTML呢又是伪装成Gecko的,同时所有的浏览器又都宣称自己是 Mozilla,于是,Chrome宣称自己是Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13,,UserAgent字符串彻底混乱了,也几乎不再发挥任何作用,每个人都宣称自己是别人,混乱充斥人间啊。  
  28.   
  29.   
  30. 有点调侃的味道,可以总结为一句话:Mozilla是Netscape的吉祥物,也是Netscape Navigator浏览器使用的内部开发代号。由于Netscape早期的影响力,直到今天,所有浏览器包括IE,向Web服务器报告自己的浏览器标识的 时候,都以 “Mozilla”开头,表明自己是Mozilla兼容的。这,就是原因啦。  
  31.   
  32.   
  33. 查看浏览器标记的方法也很容易,通过JavaScript语句:  
  34. javascript:alert(navigator.userAgent)  
  35. 在地址栏输入以上代码,然后回车。 

最后那三段话,不是在每个浏览器中都支持,比如我的firefox18就不支持,后来在firebug的F12的console里直接alert了一下,看了看效果.....
世界已经变了

Tags: mozilla, useragent

[转载]一步一步学习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/HTML代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"   
  3.  xmlns:em="http://www.mozilla.org/2004/em-rdf#">  
  4.   <Description about="urn:mozilla:install-manifest">  
  5.     <em:id>uusharedemo1@uushare.com</em:id>  
  6.     <em:name>Uushare书签(示例)</em:name>  
  7.     <em:version>1.0</em:version>  
  8.     <em:creator>KwanhongYoung</em:creator>  
  9.     <em:description>这是一个模仿Uushare书签插件的示例</em:description>  
  10.     <em:homepageURL>http://www.uushare.com</em:homepageURL>  
  11.     <em:iconURL>chrome://uusharedemo1/content/uusharedemo1.png</em:iconURL>  
  12.     <em:targetApplication>  
  13.       <Description>  
  14.         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->  
  15.         <em:minVersion>1.5</em:minVersion>  
  16.         <em:maxVersion>3.0.*</em:maxVersion>  
  17.       </Description>  
  18.     </em:targetApplication>  
  19.   </Description>  
  20. </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

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

XML/HTML代码
  1. content    uusharedemo1    chrome/content/  
  2. locale    uusharedemo1    en-US    chrome/locale/en-US/  
  3. skin    uusharedemo1    classic/1.0    chrome/skin/  
  4. overlay    chrome://browser/content/browser.xul    chrome://uusharedemo1/content/firefoxOverlay.xul  
  5. 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/HTML代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- 下面一行指明当前窗口控件所引用的样式表文件 -->  
  3. <?xml-stylesheet href="chrome://uusharedemo1/skin/overlay.css" type="text/css"?>  
  4.   
  5. <!-- 这行指明当前窗口控件所使用的语言文件,注意这里不需指定语言的名称(即zh-CN或en-US等),只需指明文件名即可  
  6. 有了语言文件之后,所有控件的文本(即text/label等属性)都统一写到语言文件里。 -->  
  7. <!DOCTYPE overlay SYSTEM "chrome://uusharedemo1/locale/uusharedemo1.dtd">  
  8.   
  9. <overlay id="uusharedemo1-overlay"  
  10.          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">  
  11.     
  12.   <!-- 这行用于指定当前窗口控件的事件(如单击事件)触发后所执行的代码所在的文件 -->  
  13.   <script src="overlay.js"/>  
  14.   <stringbundleset id="stringbundleset">  
  15.     <stringbundle id="uusharedemo1-strings" src="chrome://uusharedemo1/locale/uusharedemo1.properties"/>  
  16.   </stringbundleset>  
  17.   
  18.   <menupopup id="menu_ToolsPopup">  
  19.     <menuitem id="uusharedemo1-hello" label="&uusharedemo1.label;"   
  20.               oncommand="uusharedemo1.onMenuItemCommand(event);"/>  
  21.   </menupopup>  
  22.     
  23.   <popup id="contentAreaContextMenu">  
  24.     <menuitem id="context-uusharedemo1" label="&uusharedemo1Context.label;"  
  25.               accesskey="&uusharedemo1Context.accesskey;"  
  26.               insertafter="context-stop"  
  27.               oncommand="uusharedemo1.onMenuItemCommand(event)"/>  
  28.   </popup>  
  29.     
  30.   <toolbarpalette id="BrowserToolbarPalette">  
  31.   <toolbarbutton id="uusharedemo1-toolbar-button"  
  32.     label="&uusharedemo1Toolbar.label;"  
  33.     tooltiptext="&uusharedemo1Toolbar.tooltip;"  
  34.     oncommand="uusharedemo1.onToolbarButtonCommand()"  
  35.     class="toolbarbutton-1 chromeclass-toolbar-additional"/>  
  36.   </toolbarpalette>  
  37. </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以及被选中的文本。
下面是例子中的代码:

JavaScript代码
  1. var uusharedemo1 = {  
  2.   onLoad: function() {  
  3.     // initialization code  
  4.     this.initialized = true;  
  5.     this.strings = document.getElementById("uusharedemo1-strings");  
  6.     document.getElementById("contentAreaContextMenu")  
  7.             .addEventListener("popupshowing"function(e) { this.showContextMenu(e); }, false);  
  8.   },  
  9.   
  10.   showContextMenu: function(event) {  
  11.     // 根据上下文决定显示/隐藏右键菜单项  
  12.     // see http://kb.mozillazine.org/Adding_items_to_menus  
  13.     document.getElementById("context-uusharedemo1").hidden = gContextMenu.onImage;  
  14.   },  
  15.     
  16.   onMenuItemCommand: function(e) {  
  17.     uusharedemo1.addToUushareBookmark();  
  18.   },  
  19.     
  20.   addToUushareBookmark: function() {  
  21.      //这里调用 uushare.com 书签API的接口  
  22.     var location, title, desc;  
  23.     var browser = window.getBrowser();  
  24.     var webNav = browser.webNavigation;  
  25.   
  26.     if (webNav.currentURI)  
  27.         location = webNav.currentURI.spec;  
  28.     else  
  29.         location = gURLBar.value;  
  30.   
  31.     if (webNav.document.title) {  
  32.         title = webNav.document.title;  
  33.     }  
  34.     else {  
  35.         title = location;  
  36.     }  
  37.   
  38.     var focusedWindow = document.commandDispatcher.focusedWindow;  
  39.     var winWrapper = new XPCNativeWrapper(focusedWindow, 'getSelection()');  
  40.     desc = winWrapper.getSelection().toString();  
  41.   
  42.     var serverUrl = "http://www.uushare.com/bookmark/save?v=1&client=ff10";  
  43.     var saveUrl = serverUrl + "&noui=yes&jump=close&url=" + encodeURIComponent(location) + "&title=" + encodeURIComponent(title) + "&content=" + encodeURIComponent(desc);  
  44.     window.open(saveUrl, 'uusharev1''location=yes,links=no,scrollbars=yes,toolbar=no,width=550,height=550');  
  45.   },  
  46.     
  47.   onToolbarButtonCommand: function(e) {  
  48.     uusharedemo1.addToUushareBookmark();  
  49.   }  
  50.   
  51. };  
  52. 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代码:

JavaScript代码
  1. var uusharedemo1 = {  
  2.     strVersion : '1.0',  
  3.   
  4.     getUBKCharPref: function(strPrefName) {  
  5.         this.prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);  
  6.         try {  
  7.             return(this.prefManager.getCharPref("extensions.uusharedemo1." + strPrefName));          
  8.         } catch(e) {  
  9.             return(false);      
  10.         }  
  11.     },  
  12.       
  13.         setUBKCharPref: function(strPrefName, strValue) {  
  14.         this.prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);              
  15.         this.prefManager.setCharPref("extensions.uusharedemo1." + strPrefName, strValue);  
  16.     },  
  17.       
  18.     onLoadEvent: function()  
  19.     {  
  20.         //first load  
  21.         var strPrefVersion = this.getUBKCharPref('version');  
  22.           
  23.         if(strPrefVersion != this.strVersion) {  
  24.               
  25.             var bolWongPostButtonExists = document.getElementById('uusharedemo1-toolbar-button');  
  26.               
  27.             if(!bolWongPostButtonExists) {  
  28.                 var objToolbox = document.getElementById("navigator-toolbox");      
  29.                 var strChild = '';  
  30.                 var strSet = '';  
  31.                 var objNavBar = false;  
  32.               
  33.                 if(objToolbox) {  
  34.                     for (var i = 0; i < objToolbox.childNodes.length; ++i) {  
  35.                         if(objToolbox.childNodes[i].id == "nav-bar" && objToolbox.childNodes[i].getAttribute("customizable") == "true") {  
  36.                             objNavBar = objToolbox.childNodes[i];  
  37.                             break;  
  38.                         }  
  39.                     }  
  40.                 }  
  41.                               
  42.                 if(objNavBar) {  
  43.                     for (var i = 0; i < objNavBar.childNodes.length; i++) {  
  44.                         if(objNavBar.childNodes[i].id == "urlbar-container") {  
  45.                             if(!bolWongPostButtonExists) {  
  46.                                 strSet += "uusharedemo1-toolbar-button,"                                                          
  47.                             }  
  48.                         }  
  49.                         strSet += objNavBar.childNodes[i].id + ",";  
  50.                     }  
  51.                       
  52.                     strSet = strSet.substring(0, strSet.length-1);  
  53.                     objNavBar.currentSet = strSet;  
  54.                     objNavBar.setAttribute("currentset", strSet);  
  55.                     objNavBar.ownerDocument.persist(objNavBar.id, "currentset");  
  56.                     BrowserToolboxCustomizeDone(true);  
  57.                 }   
  58.                   
  59.                 strSet = strSet.substring(0, strSet.length-1);  
  60.                 toolbar.currentSet = strSet;  
  61.                   
  62.                 if(toolbar.setAttribute) {  
  63.                     toolbar.setAttribute("currentset", strSet);  
  64.                 }  
  65.                   
  66.                 toolboxDocument.persist(toolbar.id, "currentset");  
  67.                 BrowserToolboxCustomizeDone(true);          
  68.             }  
  69.               
  70.             this.setUBKCharPref('version'this.strVersion);  
  71.               
  72.         }//end if first load  
  73.     }  
  74. }  
  75.   
  76. window.addEventListener("load"function()                 { uusharedemo1.onLoadEvent(); }, false);  


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

本文完。

Tags: xul, mozilla, plugin, addon