1
/* See license.txt for terms of usage */
3
FBL.ns(function() { with (FBL) {
5
// ************************************************************************************************
8
const nsIIOService = CI("nsIIOService");
9
const nsIRequest = CI("nsIRequest");
10
const nsICachingChannel = CI("nsICachingChannel");
11
const nsIScriptableInputStream = CI("nsIScriptableInputStream");
12
const nsIUploadChannel = CI("nsIUploadChannel");
14
const IOService = CC("@mozilla.org/network/io-service;1");
15
const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1");
17
const LOAD_FROM_CACHE = nsIRequest.LOAD_FROM_CACHE;
18
const LOAD_BYPASS_LOCAL_CACHE_IF_BUSY = nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
20
const NS_BINDING_ABORTED = 0x804b0002;
22
// ************************************************************************************************
24
top.SourceCache = function(context)
26
this.context = context;
30
top.SourceCache.prototype =
32
loadText: function(url)
34
var lines = this.load(url);
35
return lines ? lines.join("\n") : null;
40
if (url in this.cache)
41
return this.cache[url];
43
var d = FBL.reDataURL.exec(url);
46
var src = url.substring(FBL.reDataURL.lastIndex);
47
var data = decodeURIComponent(src);
48
var lines = data.split(/\r\n|\r|\n/);
49
this.cache[url] = lines;
54
var j = FBL.reJavascript.exec(url);
57
var src = url.substring(FBL.reJavascript.lastIndex);
58
var lines = src.split(/\r\n|\r|\n/);
59
this.cache[url] = lines;
64
var charset = this.context.window.document.characterSet;
66
var ioService = IOService.getService(nsIIOService);
71
channel = ioService.newChannel(url, null, null);
72
channel.loadFlags |= LOAD_FROM_CACHE | LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
76
ERROR("sourceCache.load fails newChannel for url="+url+ " cause:"+exc+"\n");
80
if (url == this.context.browser.contentWindow.location.href)
82
if (channel instanceof nsIUploadChannel)
84
var postData = getPostStream(this.context);
87
var uploadChannel = QI(channel, nsIUploadChannel);
88
uploadChannel.setUploadStream(postData, "", -1);
92
if (channel instanceof nsICachingChannel)
94
var cacheChannel = QI(channel, nsICachingChannel);
95
cacheChannel.cacheKey = getCacheKey(this.context);
102
stream = channel.open();
107
if (FBL.reChrome.test(url)) // chrome urls cannot be read with this code.
114
var data = readFromStream(stream, charset);
115
var lines = data.split(/\r\n|\r|\n/);
116
this.cache[url] = lines;
128
loadAsync: function(url, cb)
130
if (url in this.cache)
132
cb(this.cache[url], url);
136
var ioService = IOService.getService(nsIIOService);
138
var channel = ioService.newChannel(url, null, null);
139
channel.loadFlags |= LOAD_FROM_CACHE | LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
141
var listener = new StreamListener(url, this, cb);
142
channel.asyncOpen(listener, null);
145
store: function(url, text)
147
var lines = splitLines(text);
148
return this.cache[url] = lines;
151
invalidate: function(url)
153
delete this.cache[url];
156
getLine: function(url, lineNo)
158
var lines = this.load(url);
159
return lines ? lines[lineNo-1] : null;
162
getLineAsync: function(url, lineNo, cb)
164
if (url in this.cache)
165
cb(this.cache[url][lineNo-1], url, lineNo);
168
function loader(lines, url)
170
cb(lines[lineNo-1], url, lineNo);
173
this.loadAsync(url, loader);
178
// ************************************************************************************************
180
function StreamListener(url, cache, cb)
188
StreamListener.prototype =
190
onStartRequest: function(request, context)
194
onStopRequest: function(request, context, status)
198
if (status != NS_BINDING_ABORTED)
200
var data = this.data.join("");
201
var lines = this.cache.store(this.url, data);
202
this.cb(lines, this.url, status);
206
onDataAvailable: function(request, context, inStr, sourceOffset, count)
208
var sis = ScriptableInputStream.createInstance(nsIScriptableInputStream);
210
this.data.push(sis.read(count));
214
// ************************************************************************************************
216
function getPostStream(context)
220
var webNav = context.browser.webNavigation;
221
var descriptor = QI(webNav, CI("nsIWebPageDescriptor")).currentDescriptor;
222
var entry = QI(descriptor, CI("nsISHEntry"));
226
// Seek to the beginning, or it will probably start reading at the end
227
var postStream = QI(entry.postData, CI("nsISeekableStream"));
228
postStream.seek(0, 0);
239
function getCacheKey(context)
243
var webNav = context.browser.webNavigation;
244
var descriptor = QI(webNav, CI("nsIWebPageDescriptor")).currentDescriptor;
245
var entry = QI(descriptor, CI("nsISHEntry"));
246
return entry.cacheKey;
253
// ************************************************************************************************