var msg_service = messenger.messageServiceFromURI(uri);
var msg_stream = AsyncStream();
try {
msg_service.streamMessage(uri, msg_stream, msgWindow, null,
false, null);
}catch (ex) {
log(ex)
}
/*do something*/
var params = {inn:{msg_stream:msg_stream}, out:null};
window.openDialog("chrome://test/content/dialog.xul","test-
dialog","chrome, dialog, modal",params).focus();
}
function AsyncStream() {
var aListener = {
_first: true,
_data: null,
_finaldata: null,
QueryInterface : function(iid) {
if (iid.equals
(Components.interfaces.nsIStreamListener) ||
iid.equals
(Components.interfaces.nsIMsgHeaderSink) ||
iid.equals(Components.interfaces.nsISupports))
{
return this;
} else {
throw Components.results.NS_NOINTERFACE;
return 0;
}
},
onStartRequest : function (aRequest, aContext) {
},
onStopRequest : function (aRequest, aContext, aStatusCode)
{
this._finaldata = this._data;
},
onDataAvailable : function (aRequest, aContext,
aInputStream, aOffset, aCount) {
var binInputStream = Components.classes["@mozilla.org/
binaryinputstream;1"].createInstance
(Components.interfaces.nsIBinaryInputStream);
binInputStream.setInputStream(aInputStream);
if (this._first) {
this._data = binInputStream.readBytes
(binInputStream.available());
this._first = false;
} else{
this._data += binInputStream.readBytes
(binInputStream.available());
binInputStream.close();
}
},
};
return aListener;
}
The code from the dialog:
custombutton_accept = function(){
msg_stream = window.arguments[0].inn.msg_stream;
var lade = window.setInterval("wait_until_finished(msg_stream)",
500);
function wait_until_finished(stream){
if(stream._finaldata){
log(stream._finaldata);
window.clearInterval(lade);
get_body(stream._finaldata);
}
};
function get_body(body){
alert(body);
return true;
};
return true;
}
Since I want to check every x ms I tried using setInterval, however
the dialog simply gets closed as the code isn't stopped after
setInterval, instead it simply continues and closes the dialog. I
waited a bit to see if afterwards something happened but there never
came anything.
I also tried setTimeout:
custombutton_accept = function(){
msg_stream = window.arguments[0].inn.msg_stream;
wait_until_finished(msg_stream);
}
wait_until_finished = function(stream){
if(stream._finaldata){
log(stream._finaldata);
get_body(stream._finaldata);
}else{
window.setTimeout("wait_until_finished(stream)",500);
}
}
get_body = function(body){
/*do something*/
alert(body);
}
Same problem as with setInterval.
A combination of while and setInterval:
wait_until_finished = function(stream){
while( !stream._finaldata() ){
setTimeout('wait_until_finished(stream)', 100)
}
get_body(stream._finaldata());
}
This froze the ui as if you just used while, since the code doesn't
stop after setInterval.
I don't know what else to try. Any tipps/hints/code examples are
greatly appreciated.
Greetings,
Serratia
I think it's best to use the event queue service object instead of
setting timeouts which pretty much stalls the entire UI thread while
still being mixed in with current browser thread: @mozilla.org/event-
queue-service
----------------------------------8<----------------------------------
Components.classes["@mozilla.org/event-queue-service;1"].getService
(Components.interfaces.nsIEventQueueService)
---------------------------------->8----------------------------------
And use an asynchrounous request to resolve it, but you'll have to
embed the listener in the object while resolving it so that it can
notify the listener when data is available, or stopped. Like:
onDataAvailable.
Please correct me if I'm wrong or don't understand your question
properly.
/rvdh
>custombutton_accept = function(){
> msg_stream = window.arguments[0].inn.msg_stream;
> wait_until_finished(msg_stream);
>}
>
>
A dialog's accept button will close the dialog unless you return false here.
Rather than using a timeout, you might consider adding an extra callback
property to the stream something like this:
onStopRequest : function (aRequest, aContext, aStatusCode) {
this._finalData = this._data;
if (this._callback)
this._callback(this._finalData);
},
custombutton_accept = function() {
function get_body(body) {
alert(body);
window.close();
}
var msg_stream = window.arguments[0].inn.msg_stream;
if (msg_stream._finalData)
get_body(msg_stream._finalData);
else
msg_stream._callback = get_body;
return false;
}
Not shown: code to cancel the callback when the dialog is cancelled;
code to deal with clicking OK twice; etc.
--
Warning: May contain traces of nuts.
nsIEventQueueServide doesn't seem to exist in the current versions.
According to http://markmail.org/message/2p63wgqhzwtpujiy it has been
replaced by nsIThreadManager, which I knew about but in through
http://groups.google.com/group/mozilla.dev.extensions/browse_frm/thread/bd2624ca5169915a/fe79dec301a06d2f?lnk=gst&q=nsIThread#fe79dec301a06d2f
I got discouraged in reading in further.
Greetings,
Serratia
This worked excellent, so thank you very much. =) This is quite a
beautiful solution.
Greetings,
Serratia