1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-03-01 13:35:47 +01:00

Use rendered HTML for gF/:w !foo/:w >>foo until someone inevitably complains. Closes issue #44.

This commit is contained in:
Kris Maglione
2010-10-15 17:52:28 -04:00
parent 4bbfa212bc
commit b940a9db96
4 changed files with 71 additions and 96 deletions

View File

@@ -982,73 +982,41 @@ const Buffer = Module("buffer", {
viewSourceExternally: Class("viewSourceExternally", viewSourceExternally: Class("viewSourceExternally",
XPCOM([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]), { XPCOM([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]), {
init: function (doc, callback) { init: function (doc, callback) {
let url = isString(doc) ? doc : doc.location.href;
let charset = isString(doc) ? null : doc.characterSet;
this.callback = callback || this.callback = callback ||
function (file) editor.editFileExternally(file.path); function (file) editor.editFileExternally(file.path);
let webNav = window.getWebNavigation(); let url = isString(doc) ? doc : doc.location.href;
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 uri = util.newURI(url, charset); 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") if (uri.scheme == "file")
this.callback(File(uri.QueryInterface(Ci.nsIFileURL).file)); this.callback(File(uri.QueryInterface(Ci.nsIFileURL).file));
else { else {
if (descriptor) { this.file = io.createTempFile();
// we'll use nsIWebPageDescriptor to get the source because it may var webBrowserPersist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
// not have to refetch the file from the server .createInstance(Ci.nsIWebBrowserPersist);
// XXXbz this is so broken... This code doesn't set up this docshell webBrowserPersist.persistFlags = webBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
// at all correctly; if somehow the view-source stuff managed to webBrowserPersist.progressListener = this;
// execute script we'd be in big trouble here, I suspect. webBrowserPersist.saveURI(uri, null, null, null, null, this.file);
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);
}
} }
return null; return null;
}, },
destroy: function () {
if (this.docShell)
this.docShell.destroy();
},
onStateChange: function (progress, request, flag, status) { onStateChange: function (progress, request, flag, status) {
// once it's done loading...
if ((flag & Ci.nsIWebProgressListener.STATE_STOP) && status == 0) { if ((flag & Ci.nsIWebProgressListener.STATE_STOP) && status == 0) {
try { try {
if (this.docShell) { this.callback(this.file);
this.file = io.createTempFile();
this.file.write(this.docShell.document.body.textContent);
}
try {
this.callback(this.file);
}
finally {
this.file.remove(false);
}
} }
finally { finally {
this.destroy(); this.file.remove(false);
} }
} }
return 0; return 0;
@@ -1344,7 +1312,7 @@ const Buffer = Module("buffer", {
return buffer.viewSourceExternally(buffer.focusedFrame.document, return buffer.viewSourceExternally(buffer.focusedFrame.document,
function (tmpFile) { function (tmpFile) {
try { try {
file.write(tmpFile.read(), ">>"); file.write(tmpFile, ">>");
} }
catch (e) { catch (e) {
dactyl.echoerr(file.path.quote() + ": E212: Can't open file for writing"); 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); let file = io.File(filename);
dactyl.assert(!file.exists() || args.bang, 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) }; 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); prefs.set("browser.download.lastDir", io.cwd);
try { try {
var contentDisposition = window.content var contentDisposition = window.content.QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils) .getInterface(Ci.nsIDOMWindowUtils)
.getDocumentMetadata("content-disposition"); .getDocumentMetadata("content-disposition");
} }
catch (e) {} catch (e) {}
window.internalSave(doc.location.href, doc, null, contentDisposition, window.internalSave(doc.location.href, doc, null, contentDisposition,
doc.contentType, false, null, chosenData, doc.referrer ? doc.contentType, false, null, chosenData,
window.makeURI(doc.referrer) : null, true); doc.referrer ? window.makeURI(doc.referrer) : null,
true);
}, },
{ {
argCount: "?", argCount: "?",

View File

@@ -526,8 +526,8 @@ function call(fn) {
*/ */
function memoize(obj, key, getter) { function memoize(obj, key, getter) {
obj.__defineGetter__(key, function replace() ( obj.__defineGetter__(key, function replace() (
Class.replaceProperty(this, key, null), Class.replaceProperty(this.instance || this, key, null),
Class.replaceProperty(this, key, getter.call(this, key)))); Class.replaceProperty(this.instance || this, key, getter.call(this, key))));
} }
/** /**
@@ -684,19 +684,8 @@ function Class() {
(function constructor() { (function constructor() {
let self = Object.create(Constructor.prototype, { let self = Object.create(Constructor.prototype, {
constructor: { value: Constructor }, 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); var res = self.init.apply(self, arguments);
return res !== undefined ? res : self; return res !== undefined ? res : self;
})]]>, })]]>,
@@ -820,6 +809,14 @@ Class.prototype = {
return timer; 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. * A base class generator for classes which impliment XPCOM interfaces.

View File

@@ -56,8 +56,6 @@ const Services = Module("Services", {
this.add("windowWatcher", "@mozilla.org/embedcomp/window-watcher;1", Ci.nsIWindowWatcher); 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/file/local;1", Ci.nsILocalFile);
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler); this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind); this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);

View File

@@ -286,7 +286,7 @@ const File = Class("File", {
} }
} }
let self = XPCSafeJSObjectWrapper(file); let self = XPCSafeJSObjectWrapper(file);
self.__proto__ = File.prototype; self.__proto__ = this;
return self; return self;
}, },
@@ -310,22 +310,32 @@ const File = Class("File", {
*/ */
read: function (encoding) { read: function (encoding) {
let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 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); ifstream.init(this, -1, 0, 0);
icstream.init(ifstream, encoding, 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering
let buffer = []; try {
let str = {}; if (encoding instanceof Ci.nsIOutputStream) {
while (icstream.readString(4096, str) != 0) let l, len = 0;
buffer.push(str.value); while ((l = encoding.writeFrom(ifstream, 4096)) != 0)
len += l;
icstream.close(); return len;
ifstream.close(); }
return buffer.join(""); 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); stream.init(ofstream, encoding, 0, defaultChar);
return stream; return stream;
} }
if (buf instanceof File)
buf = buf.read();
if (!encoding) if (!encoding)
encoding = File.defaultEncoding; encoding = File.defaultEncoding;
@@ -391,18 +403,18 @@ const File = Class("File", {
this.create(this.NORMAL_FILE_TYPE, perms); this.create(this.NORMAL_FILE_TYPE, perms);
ofstream.init(this, mode, perms, 0); ofstream.init(this, mode, perms, 0);
let ocstream = getStream(0);
try { try {
ocstream.writeString(buf); if (callable(buf))
} buf(ofstream.QueryInterface(Ci.nsIOutputStream));
catch (e) { else {
if (e.result == Cr.NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) { var ocstream = getStream(0);
ocstream = getStream("?".charCodeAt(0));
ocstream.writeString(buf); 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 { finally {
try { try {