淘先锋技术网

首页 1 2 3 4 5 6 7
前面的例子(为firefox添加新的protocol)虽然很详细,但是形式过于古老,无法应用于新的firefox版本中。我对这个进行进一步的研究。有了定制about页面的URL的经验,我打算实现一种新的协议“research”,在地址栏中输入“research:XXX”则显示百度或者谷歌搜索XXX关键词所得到的搜索页面。
第一步,看看百度/谷歌搜索关键词之后的URL有什么特征,打开百度,在搜索框内输入firefox,回车发现地址栏为http://www.baidu.com/s?wd=firefox&rsv_bp=0&rsv_spt=3&inputT=1282。我觉得太长了,将前面部分截断,在地址栏中输入:http://www.baidu.com/s?wd=firefox也得到了上面的搜索后的网页。因此可以初步判断,百度的搜索页面可以按照http://www.baidu.com/s?wd=keyword的方式进行。如果为汉字估计比较复杂,不深究。
对于google搜索研究了一会儿,也试出来了,其搜索页可以使用的URL是http://www.google.com.hk/search?q=firefox
第二步,protocol实现代码之外的其他东西,我利用自己已经实现了的一个hello world扩展,在这个扩展里面新建一个components目录。目录下建立一个js文件。然后在chrome.manifest文件末尾添加如下代码行:
component {09bde46b-739c-4a6d-8ffd-f170972db8c9} components/myProtocol.js
contract @mozilla.org/network/protocol;1?name=research {09bde46b-739c-4a6d-8ffd-f170972db8c9}
第三步,实现protocol,编辑前面建立的myProtocol.js文件,实现一个protocol的模板如下:

const Cc = Components.classes;
const Ci = Components.interfaces;
const mScheme="research";

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function myProtocol() { }
myProtocol.prototype={
	scheme: mScheme,
	classDescription: "mResearch Protocol",
	classID: Components.ID("09bde46b-739c-4a6d-8ffd-f170972db8c9"),
	contractID: "@mozilla.org/network/protocol;1?name=" + mScheme,
	QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler, Ci.nsISupports]),

	defaultPort: -1,
	protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
		Ci.nsIProtocolHandler.URI_NOAUTH,
	
	allowPort:function(port,scheme){
		return false;//该函数可以按需要修改,一般都是这样使用,与前面defaultPort:-1
//是有联系的。
	},
	
	newURI:function(aSpec, aOriginCharset,aBaseURI){
    // newURI的实现代码
	},
	
	newChannel:function(aURI){
    // newChannel的实现代码
	}
};

const NSGetFactory = XPCOMUtils.generateNSGetFactory([myProtocol]);
上面是我使用的代码,加下划线的是可以改和需要改的地方。下面研究两个关键的方法如何实现。
经过研究,暂时没有发现newChannel的实现机制。但是,已经实现了我本次的目标。最终结果是在地址栏输入“research:KEYWORDS”或者“research:KEYWORDS#baidu”则会显示百度搜索页。输入“research:KEYWORDS#otherthing”则会显示google的搜索页。其搜索的关键词都是KEYWORDS。
newURI的实现代码如下:

	newURI:function(aSpec, aOriginCharset,aBaseURI){
		var ioService = Cc["@mozilla.org/network/io-service;1"]  
                  .getService(Ci.nsIIOService); 
		var sPos=aSpec.indexOf("#");
		var keyWord;
		if(sPos>0){
			keyWord=aSpec.substring(aSpec.indexOf(":")+1,sPos);
			if("baidu"==aSpec.substring(sPos+1,aSpec.length))
			    var uri=ioService.newURI("http://www.baidu.com/s?wd=", null, null);
		    else var uri=ioService.newURI("http://www.google.com.hk/search?q=",null,null);
		}
		else {
			keyWord=aSpec.substring(aSpec.indexOf(":")+1,aSpec.length);
			var uri=ioService.newURI("http://www.baidu.com/s?wd=", null, null);
		}
		uri=uri.spec+keyWord;
		return  ioService.newURI(uri, null, null);		
	},
效果如图:
输入research:firefox并回车:


输入research:mozilla#baidu并回车:

输入research:firefox#XXX并回车(XXX代表不是baidu的其他字符串):

接下来需要研究的就是如何编写实现newChannel的代码,完成上述任务竟然不需要对newChannel方法进行操作就可以完成,真是出乎我的意料。
可能是我在newURI中就已经return了一个firefox可以识别的URL了,然后它就给处理了,所以压根儿都没去运行我的newChannel。于是我在newURI中不处理了,直接返回。看看是什么效果。


newChannel的内容,研究得不是很透彻,希望与大家交流,共同进步