diff --git a/common/content/browser.js b/common/content/browser.js index 292c0c53..09a194c2 100644 --- a/common/content/browser.js +++ b/common/content/browser.js @@ -188,6 +188,7 @@ const Browser = Module("browser", { function () { window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils).redraw(); + statusline.updateUrl(); commandline.clear(); }, { argCount: "0" }); diff --git a/common/content/buffer.js b/common/content/buffer.js index f8a30123..c90aa6e3 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -932,11 +932,12 @@ const Buffer = Module("buffer", { * @param {boolean} useExternalEditor View the source in the external editor. */ viewSource: function (url, useExternalEditor) { - url = url || buffer.URI; + let doc = tabs.localStore.focusedFrame.document; if (useExternalEditor) - editor.editFileExternally(url); + this.viewSourceExternally(url || doc); else { + url = url || doc.location.href; const PREFIX = "view-source:"; if (url.indexOf(PREFIX) == 0) url = url.substr(PREFIX.length); @@ -951,6 +952,92 @@ const Buffer = Module("buffer", { } }, + /** + * Launches an editor to view the source of the given document. The + * contents of the document are saved to a temporary local file and + * removed when the editor returns. This function returns + * immediately. + * + * @param {Document} doc The document to view. + */ + /* + * Derived from code in Mozilla, ©2005 Jason Barnabe, + * Tri-licensed under MPL 1.1/GPL 2.0/LGPL 2.1 + * Portions copyright Kris Maglione licensable under the + * MIT license. + */ + viewSourceExternally: Class("viewSourceExternally", + XPCOM([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]), { + init: function (doc) { + let url = isString(doc) ? doc : doc.location.href; + let charset = isString(doc) ? null : doc.characterSet; + + let webNav = window.getWebNavigation(); + try { + webNav = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(nsIWebNavigation); + } + catch (e) {} + let descriptor = null; + try { + descriptor = webNav.QueryInterface(Ci.nsIWebPageDescriptor).currentDescriptor; + } + catch (e) {} + + let uri = util.newURI(url, charset); + if (uri.scheme == "file") + editor.editFileExternally(uri.QueryInterface(Ci.nsIFileURL).file.path); + 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 = Cc["@mozilla.org/docshell;1"].createInstance(Ci.nsIBaseWindow) + .QueryInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIWebPageDescriptor) + .QueryInterface(Ci.nsIWebProgress); + this.docShell.create(); + this.docShell.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); + this.docShell.loadPage(descriptor, Ci.nsIWebPageDescriptor.DISPLAY_AS_SOURCE); + } + else { + this.file = io.createTempFile(); + var webBrowserPersist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] + .createInstance(Ci.nsIWebBrowserPersist); + webBrowserPersist.persistFlags = Ci.nsIWebBrowserPersist.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); + } + editor.editFileExternally(this.file.path); + this.file.remove(false); + } + finally { + this.destroy(); + } + } + return 0; + } + }), + /** * Increases the zoom level of the current buffer. * diff --git a/common/content/io.js b/common/content/io.js index e95c2547..0402c395 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -11,12 +11,13 @@ plugins.contexts = {}; function Script(file) { - let self = plugins.contexts[file.path]; + let self = plugins[file.path]; if (self) { if (self.onUnload) self.onUnload(); return self; - } + } + else self = { __proto__: plugins }; plugins.contexts[file.path] = self; plugins[file.path] = self; @@ -203,6 +204,8 @@ const IO = Module("io", { file.append(config.tempFile); file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt('0600', 8)); + Cc["@mozilla.org/uriloader/external-helper-app-service;1"] + .getService(Ci.nsPIExternalAppLauncher).deleteTemporaryFileOnExit(file); return io.File(file); }, @@ -657,12 +660,11 @@ lookup: completion: function () { completion.charset = function (context) { context.anchored = false; - let service = services.get("charset"); context.keys = { text: util.identity, - description: function (charset) service.getCharsetTitle(charset) + description: services.get("charset").getCharsetTitle }; - context.generate = function () iter(service.getDecoderList()); + context.generate = function () iter(services.get("charset").getDecoderList()); }; completion.directory = function directory(context, full) { diff --git a/common/locale/en-US/buffer.xml b/common/locale/en-US/buffer.xml index 155438c0..03c25467 100644 --- a/common/locale/en-US/buffer.xml +++ b/common/locale/en-US/buffer.xml @@ -73,9 +73,7 @@
View source with an external editor. Opens the source
code of the current web site with the external editor
- specified by the