diff options
-rw-r--r-- | common/content/buffer.js | 82 | ||||
-rw-r--r-- | common/modules/base.jsm | 25 | ||||
-rw-r--r-- | common/modules/services.jsm | 2 | ||||
-rw-r--r-- | common/modules/storage.jsm | 58 |
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 { |