summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/content/buffer.js82
-rw-r--r--common/modules/base.jsm25
-rw-r--r--common/modules/services.jsm2
-rw-r--r--common/modules/storage.jsm58
4 files changed, 71 insertions, 96 deletions
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 8c450fce..0913c4e9 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -982,73 +982,41 @@ const Buffer = Module("buffer", {
viewSourceExternally: Class("viewSourceExternally",
XPCOM([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]), {
init: function (doc, callback) {
- let url = isString(doc) ? doc : doc.location.href;
- let charset = isString(doc) ? null : doc.characterSet;
this.callback = callback ||
function (file) editor.editFileExternally(file.path);
- let webNav = window.getWebNavigation();
- try {
- webNav = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation);
- }
- catch (e) {}
- let descriptor = null;
- try {
- descriptor = webNav.QueryInterface(Ci.nsIWebPageDescriptor).currentDescriptor;
- }
- catch (e) {}
-
+ let url = isString(doc) ? doc : doc.location.href;
let uri = util.newURI(url, charset);
+ let charset = isString(doc) ? null : doc.characterSet;
+
+ if (!isString(doc))
+ return io.withTempFiles(function (temp) {
+ let encoder = services.create("htmlEncoder");
+ encoder.init(doc, "text/unicode", encoder.OutputRaw|encoder.OutputPreformatted);
+ temp.write(encoder.encodeToString(), ">");
+ this.callback(temp);
+ }, this);
+
if (uri.scheme == "file")
this.callback(File(uri.QueryInterface(Ci.nsIFileURL).file));
else {
- if (descriptor) {
- // we'll use nsIWebPageDescriptor to get the source because it may
- // not have to refetch the file from the server
- // XXXbz this is so broken... This code doesn't set up this docshell
- // at all correctly; if somehow the view-source stuff managed to
- // execute script we'd be in big trouble here, I suspect.
-
- this.docShell = services.create("docshell");
- this.docShell.create();
- this.docShell.addProgressListener(this, this.docShell.NOTIFY_STATE_DOCUMENT);
- this.docShell.loadPage(descriptor, this.docShell.DISPLAY_AS_SOURCE);
- }
- else {
- this.file = io.createTempFile();
- var webBrowserPersist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
- .createInstance(Ci.nsIWebBrowserPersist);
- webBrowserPersist.persistFlags = webBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
- webBrowserPersist.progressListener = this;
- webBrowserPersist.saveURI(uri, null, null, null, null, this.file);
- }
+ this.file = io.createTempFile();
+ var webBrowserPersist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+ .createInstance(Ci.nsIWebBrowserPersist);
+ webBrowserPersist.persistFlags = webBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ webBrowserPersist.progressListener = this;
+ webBrowserPersist.saveURI(uri, null, null, null, null, this.file);
}
return null;
},
- destroy: function () {
- if (this.docShell)
- this.docShell.destroy();
- },
-
onStateChange: function (progress, request, flag, status) {
- // once it's done loading...
if ((flag & Ci.nsIWebProgressListener.STATE_STOP) && status == 0) {
try {
- if (this.docShell) {
- this.file = io.createTempFile();
- this.file.write(this.docShell.document.body.textContent);
- }
- try {
- this.callback(this.file);
- }
- finally {
- this.file.remove(false);
- }
+ this.callback(this.file);
}
finally {
- this.destroy();
+ this.file.remove(false);
}
}
return 0;
@@ -1344,7 +1312,7 @@ const Buffer = Module("buffer", {
return buffer.viewSourceExternally(buffer.focusedFrame.document,
function (tmpFile) {
try {
- file.write(tmpFile.read(), ">>");
+ file.write(tmpFile, ">>");
}
catch (e) {
dactyl.echoerr(file.path.quote() + ": E212: Can't open file for writing");
@@ -1355,7 +1323,7 @@ const Buffer = Module("buffer", {
let file = io.File(filename);
dactyl.assert(!file.exists() || args.bang,
- "E13: File exists (add ! to override)");
+ "E13: File exists (add ! to override)");
chosenData = { file: file, uri: window.makeURI(doc.location.href, doc.characterSet) };
}
@@ -1366,16 +1334,16 @@ const Buffer = Module("buffer", {
prefs.set("browser.download.lastDir", io.cwd);
try {
- var contentDisposition = window.content
- .QueryInterface(Ci.nsIInterfaceRequestor)
+ var contentDisposition = window.content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.getDocumentMetadata("content-disposition");
}
catch (e) {}
window.internalSave(doc.location.href, doc, null, contentDisposition,
- doc.contentType, false, null, chosenData, doc.referrer ?
- window.makeURI(doc.referrer) : null, true);
+ doc.contentType, false, null, chosenData,
+ doc.referrer ? window.makeURI(doc.referrer) : null,
+ true);
},
{
argCount: "?",
diff --git a/common/modules/base.jsm b/common/modules/base.jsm
index 9495f089..404872cf 100644
--- a/common/modules/base.jsm
+++ b/common/modules/base.jsm
@@ -526,8 +526,8 @@ function call(fn) {
*/
function memoize(obj, key, getter) {
obj.__defineGetter__(key, function replace() (
- Class.replaceProperty(this, key, null),
- Class.replaceProperty(this, key, getter.call(this, key))));
+ Class.replaceProperty(this.instance || this, key, null),
+ Class.replaceProperty(this.instance || this, key, getter.call(this, key))));
}
/**
@@ -684,19 +684,8 @@ function Class() {
(function constructor() {
let self = Object.create(Constructor.prototype, {
constructor: { value: Constructor },
- closure: {
- configurable: true,
- get: function () {
- function closure(fn) function () fn.apply(self, arguments);
- for (let k in iterAll(properties(this),
- properties(this, true)))
- if (!this.__lookupGetter__(k) && callable(this[k]))
- closure[k] = closure(self[k]);
- Object.defineProperty(this, "closure", { value: closure });
- return closure;
- }
- }
});
+ self.instance = self;
var res = self.init.apply(self, arguments);
return res !== undefined ? res : self;
})]]>,
@@ -820,6 +809,14 @@ Class.prototype = {
return timer;
}
};
+memoize(Class.prototype, "closure", function () {
+ const self = this;
+ function closure(fn) function () fn.apply(self, arguments);
+ for (let k in iterAll(properties(this), properties(this, true)))
+ if (!this.__lookupGetter__(k) && callable(this[k]))
+ closure[k] = closure(this[k]);
+ return closure;
+});
/**
* A base class generator for classes which impliment XPCOM interfaces.
diff --git a/common/modules/services.jsm b/common/modules/services.jsm
index f7000727..7452d405 100644
--- a/common/modules/services.jsm
+++ b/common/modules/services.jsm
@@ -56,8 +56,6 @@ const Services = Module("Services", {
this.add("windowWatcher", "@mozilla.org/embedcomp/window-watcher;1", Ci.nsIWindowWatcher);
- this.addClass("docshell", "@mozilla.org/docshell;1", [Ci.nsIBaseWindow, Ci.nsIWebNavigation,
- Ci.nsIWebPageDescriptor, Ci.nsIWebProgress]);
this.addClass("file", "@mozilla.org/file/local;1", Ci.nsILocalFile);
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm
index 0e5a0b15..266336e9 100644
--- a/common/modules/storage.jsm
+++ b/common/modules/storage.jsm
@@ -286,7 +286,7 @@ const File = Class("File", {
}
}
let self = XPCSafeJSObjectWrapper(file);
- self.__proto__ = File.prototype;
+ self.__proto__ = this;
return self;
},
@@ -310,22 +310,32 @@ const File = Class("File", {
*/
read: function (encoding) {
let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- let icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
-
- if (!encoding)
- encoding = File.defaultEncoding;
ifstream.init(this, -1, 0, 0);
- icstream.init(ifstream, encoding, 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering
-
- let buffer = [];
- let str = {};
- while (icstream.readString(4096, str) != 0)
- buffer.push(str.value);
- icstream.close();
- ifstream.close();
- return buffer.join("");
+ try {
+ if (encoding instanceof Ci.nsIOutputStream) {
+ let l, len = 0;
+ while ((l = encoding.writeFrom(ifstream, 4096)) != 0)
+ len += l;
+ return len;
+ }
+ else {
+ var icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
+ icstream.init(ifstream, encoding || File.defaultEncoding, 4096, // 4096 bytes buffering
+ Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ let buffer = [];
+ let str = {};
+ while (icstream.readString(4096, str) != 0)
+ buffer.push(str.value);
+ return buffer.join("");
+ }
+ }
+ finally {
+ if (icstream)
+ icstream.close();
+ ifstream.close();
+ }
},
/**
@@ -376,6 +386,8 @@ const File = Class("File", {
stream.init(ofstream, encoding, 0, defaultChar);
return stream;
}
+ if (buf instanceof File)
+ buf = buf.read();
if (!encoding)
encoding = File.defaultEncoding;
@@ -391,18 +403,18 @@ const File = Class("File", {
this.create(this.NORMAL_FILE_TYPE, perms);
ofstream.init(this, mode, perms, 0);
- let ocstream = getStream(0);
try {
- ocstream.writeString(buf);
- }
- catch (e) {
- if (e.result == Cr.NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
- ocstream = getStream("?".charCodeAt(0));
+ if (callable(buf))
+ buf(ofstream.QueryInterface(Ci.nsIOutputStream));
+ else {
+ var ocstream = getStream(0);
ocstream.writeString(buf);
- return false;
}
- else
- throw e;
+ }
+ catch (e if callable(buf) && e.result == Cr.NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
+ ocstream = getStream("?".charCodeAt(0));
+ ocstream.writeString(buf);
+ return false;
}
finally {
try {