在自定义的xul:浏览器中加载页面的观察者 [英] An observer for page loads in a custom xul:browser
问题描述
我创建了一个观察者,但我还不知道如何将这个观察者只应用于xul:browser元素。
function myFunction(){
var container = jQuery(#container)[0];
var new_browser_element = document.createElement('browser');
container.appendChild(new_browser_element);
var observerService = Components.classes [@ mozilla.org/observer-service;1\"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(myObserver,http-on-modify-request,false);
$ b var myObserver = {
观察:函数(aSubject,aTopic,aData){
if(aTopic!='http-on-修改请求'){
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
// alert(aSubject.URI.spec);
//现在在新选项卡中打开url
$ b $ QueryInterface函数(iid){
if(!iid.equals(Components .interfaces.nsISupports)&&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
返回这个;
}
};
您可以尝试: b
var myObserver = {
观察:函数(aSubject,aTopic,aData){
if(aTopic =='http-on-修改请求')
{
Subject.QueryInterface(Components.interfaces.nsIHttpChannel);
var url = aSubject.URI.spec;
var postData;
if(aSubject.requestMethod.toLowerCase()==post)
{
var postText = this.readPostTextFromRequest(request);
if(postText)
{
var dataString = parseQuery(postText);
postData = postDataFromString(dataString);
}
}
var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow);
//检查它是否是您的迷你浏览器窗口之一
if(jQuery(DOMWindow).hasClass('mini_browser'))
{
openInTab(url,postData);
var request = aSubject.QueryInterface(Components.interfaces.nsIRequest);
request.cancel(Components.results.NS_BINDING_ABORTED);
QueryInterface函数(iid){
if(!iid.equals( Components.interfaces.nsISupports)&&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
返回这个;
},
readPostTextFromRequest:function(request){
var is = request.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
if(is)
{
var ss = is.QueryInterface(Components.interfaces.nsISeekableStream);
var prevOffset;
if(ss)
{
prevOffset = ss.tell();
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET,0);
//从流中读取数据
var charset =UTF-8;
var text = this.readFromStream(is,charset,true);
//寻找锁定文件,只有在necko还没有读取的时候才寻找开头,
//因为在阅读之前necko不会找零(最好不要直到459384被修复)。
if(ss&& prevOffset == 0)
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET,0);
返回文本;
else {
dump(无法查询上传流的接口。);
}
}
返回null;
$ b readFromStream:function(stream,charset,noClose)
{
var sis = Components.classes [@ mozilla.org/binaryinputstream;1 ]
.getService(Components.interfaces.nsIBinaryInputStream);
sis.setInputStream(stream);
var segments = []; (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if(!noClose)
sis.close();
var text = segments.join();
返回文本;
}
};
函数openInTab(url,postData)
{
var wm = Components.classes [@ mozilla.org/appshell/window-mediator;1]
.getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow(navigator:browser);
if(recentWindow)
{
//使用现有的浏览器窗口,打开tab并选择它
recentWindow.gBrowser.selectedTab = recentWindow.gBrowser.addTab(url, null,null,postData);
函数parseQuery(){
var qry = this;
var rex = / [?&]?([^ =] +)(?:=([^&#] *))?/ g;
var qmatch,key;
var paramValues = {};
// parse查询字符串存储键/值在ParamValues关联数组
while(qmatch = rex.exec(qry)){
key = decodeURIComponent(qmatch [1]); // get解码密钥
val = decodeURIComponent(qmatch [2]); //获得解码值
paramValues [key] = val;
}
返回paramValues;
$ b $函数postDataFromString(dataString)
{
// POST方法请求必须将编码文本包装在MIME
//流
var stringStream = Components.classes [@ mozilla.org/io/string-input-stream; 1]
.createInstance(Components.interfaces.nsIStringInputStream);
if(stringStream中的data)// Gecko 1.9或更新
stringStream.data = dataString;
else // 1.8或者更老
stringStream.setData(dataString,dataString.length);
var postData = Components.classes [@ mozilla.org/network/mime-input-stream; 1]。
createInstance(Components.interfaces.nsIMIMEInputStream);
postData.addHeader(Content-Type,application / x-www-form-urlencoded);
postData.addContentLength = true;
postData.setData(stringStream);
返回postData;
}
我会更新这个以填补空白。 p>
编辑:参见 http: //forums.mozillazine.org/viewtopic.php?p=2772951#p2772951 ,了解如何获取请求的源窗口。
要求取消代码 http://zenit.senecac.on.ca/wiki/index.php/Support_For_OpenID 。
请参阅 http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl 了解有关nsIRequest的详细信息。
请参阅 http://forums.mozillazine.org/viewtopic.php? p = 2404533#p2404533 和 https://developer.mozilla.org/ en / XUL / Method / addTab 来定义addTab。
parseQuery来自 http://blog.strictly-software.com/2008/10/using-javascript-to-parse-querystring.html 。
请参阅 https://developer.mozilla.org/zh/Code_snippets/ Post_data_to_window#Preprocessing_POST_data ,以便如何处理适合addTab的表单数据。
$ b ReadPostFromText和ReadTextFromStream都来自于萤火虫(虽然稍作修改)
In my firefox extension I'm creating a xul:browser element. I want to have an observer that intercepts any url changes within the embedded browser and opens the url in a new browser tab (in the main browser). I'd also like new windows spawned by the xul:browser window to open in a tab instead of a new browser window.
I've created an observer which works, but I don't yet know how to apply that observer only to the xul:browser element.
function myFunction(){
var container = jQuery("#container")[0];
var new_browser_element = document.createElement('browser');
container.appendChild(new_browser_element);
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(myObserver, "http-on-modify-request", false);
}
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic != 'http-on-modify-request'){
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
// alert(aSubject.URI.spec);
// Now open url in new tab
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
You could try:
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic == 'http-on-modify-request')
{
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var url = aSubject.URI.spec;
var postData ;
if (aSubject.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request);
if (postText)
{
var dataString = parseQuery(postText);
postData = postDataFromString(dataString);
}
}
var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow);
//check if it is one of your mini browser windows
if (jQuery(DOMWindow).hasClass('mini_browser'))
{
openInTab(url, postData);
var request = aSubject.QueryInterface(Components.interfaces.nsIRequest);
request.cancel(Components.results.NS_BINDING_ABORTED);
}
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
readPostTextFromRequest : function(request) {
var is = request.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Components.interfaces.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
dump("Failed to Query Interface for upload stream.\n");
}
}
return null;
},
readFromStream : function(stream, charset, noClose)
{
var sis = Components.classes["@mozilla.org/binaryinputstream;1"]
.getService(Components.interfaces.nsIBinaryInputStream);
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
};
function openInTab(url, postData)
{
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");
if (recentWindow)
{
// Use an existing browser window, open tab and "select" it
recentWindow.gBrowser.selectedTab = recentWindow.gBrowser.addTab(url, null, null, postData);
}
}
function parseQuery() {
var qry = this;
var rex = /[?&]?([^=]+)(?:=([^&#]*))?/g;
var qmatch, key;
var paramValues = {};
// parse querystring storing key/values in the ParamValues associative array
while (qmatch = rex.exec(qry)) {
key = decodeURIComponent(qmatch[1]);// get decoded key
val = decodeURIComponent(qmatch[2]);// get decoded value
paramValues[key] = val;
}
return paramValues;
}
function postDataFromString(dataString)
{
// POST method requests must wrap the encoded text in a MIME
// stream
var stringStream = Components.classes["@mozilla.org/io/string-input-stream;1"]
.createInstance(Components.interfaces.nsIStringInputStream);
if ("data" in stringStream) // Gecko 1.9 or newer
stringStream.data = dataString;
else // 1.8 or older
stringStream.setData(dataString, dataString.length);
var postData = Components.classes["@mozilla.org/network/mime-input-stream;1"].
createInstance(Components.interfaces.nsIMIMEInputStream);
postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
postData.addContentLength = true;
postData.setData(stringStream);
return postData;
}
I'll update this to fill in the blanks in a bit.
edit: see http://forums.mozillazine.org/viewtopic.php?p=2772951#p2772951 for how to get the source window of a request.
Request cancellation code from http://zenit.senecac.on.ca/wiki/index.php/Support_For_OpenID.
see http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl for details on nsIRequest.
See http://forums.mozillazine.org/viewtopic.php?p=2404533#p2404533 and https://developer.mozilla.org/en/XUL/Method/addTab for the definition of addTab.
parseQuery comes from http://blog.strictly-software.com/2008/10/using-javascript-to-parse-querystring.html.
See https://developer.mozilla.org/en/Code_snippets/Post_data_to_window#Preprocessing_POST_data for how to process post data in a form suitable for addTab.
ReadPostFromText and ReadTextFromStream both come from firebug (though slightly modified)
这篇关于在自定义的xul:浏览器中加载页面的观察者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!