--- /dev/null
+// Constructs an application object
+function WebDeveloperApplication(applicationPath)
+{
+ this.applicationPath = applicationPath;
+ this.executable = this.getExecutable();
+ this.file = null;
+}
+
+// Creates a source file
+WebDeveloperApplication.prototype.createSourceFile = function(temporaryDirectory, uri)
+{
+ var sourceFile = null;
+
+ // If the URI has a file scheme
+ if(uri.scheme == "file")
+ {
+ var fileProtocolHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].createInstance(Components.interfaces.nsIFileProtocolHandler);
+
+ sourceFile = fileProtocolHandler.getFileFromURLSpec(uri.spec);
+ }
+
+ // If the source file is not set
+ if(!sourceFile)
+ {
+ var fileExtension = "html";
+ var fileName = uri.host;
+ var url = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURL);
+
+ sourceFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ url.spec = uri.spec;
+
+ // If the URL has a file extension
+ if(url.fileExtension)
+ {
+ fileExtension = url.fileExtension;
+ }
+
+ temporaryDirectory.append("webdeveloper_" + fileName + "_" + new Date().getTime() + "." + fileExtension);
+ sourceFile.initWithPath(temporaryDirectory.path);
+ }
+
+ return sourceFile;
+}
+
+// Returns an executable for the application
+WebDeveloperApplication.prototype.getExecutable = function()
+{
+ var executable = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+
+ executable.initWithPath(this.applicationPath);
+
+ return executable;
+}
+
+// Returns the post data
+WebDeveloperApplication.prototype.getPostData = function()
+{
+ // Try to get the post data
+ try
+ {
+ var sessionHistory = getWebNavigation().sessionHistory;
+ var entry = sessionHistory.getEntryAtIndex(sessionHistory.index, false).QueryInterface(Components.interfaces.nsISHEntry);
+
+ return entry.postData;
+ }
+ catch(exception)
+ {
+ return null;
+ }
+}
+
+// Launch the application with the given file
+WebDeveloperApplication.prototype.launchWithFile = function()
+{
+ var mimeService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Components.interfaces.nsIMIMEService);
+ var mimeInfo = mimeService.getFromTypeAndExtension(this.file.path, null);
+
+ mimeInfo.alwaysAskBeforeHandling = false;
+ mimeInfo.preferredAction = Components.interfaces.nsIMIMEInfo.useHelperApp;
+ mimeInfo.preferredApplicationHandler = this.executable;
+
+ mimeInfo.launchWithFile(this.file);
+}
+
+// Launch the application with the source from the given URI
+WebDeveloperApplication.prototype.launchWithSource = function(uri)
+{
+ var stringBundle = document.getElementById("webdeveloper-string-bundle");
+ var temporaryDirectory = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
+
+ // If the temporary directory exists, is a directory and is writable
+ if(temporaryDirectory.exists() && temporaryDirectory.isDirectory() && temporaryDirectory.isWritable())
+ {
+ // If the executable exists
+ if(this.executable.exists())
+ {
+ this.file = this.createSourceFile(temporaryDirectory, uri);
+
+ if(uri.scheme == "file")
+ {
+ this.launchWithFile();
+ }
+ else
+ {
+ var webBrowserPersistInterface = Components.interfaces.nsIWebBrowserPersist;
+ var webBrowserPersist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(webBrowserPersistInterface);
+
+ webBrowserPersist.persistFlags = webBrowserPersistInterface.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION | webBrowserPersistInterface.PERSIST_FLAGS_FROM_CACHE | webBrowserPersistInterface.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ webBrowserPersist.progressListener = this;
+
+ webBrowserPersist.saveURI(uri, null, uri, this.getPostData(), null, this.file);
+ }
+ }
+ else
+ {
+ webdeveloper_error(stringBundle.getFormattedString("webdeveloper_launchApplicationFailed", [this.applicationPath]));
+ }
+ }
+ else
+ {
+ webdeveloper_error(stringBundle.getFormattedString("webdeveloper_tempDirectoryFailed", [temporaryDirectory.path]));
+ }
+}
+
+// Launch the application with the given URL
+WebDeveloperApplication.prototype.launchWithURL = function(url)
+{
+ // If the executable exists, is a file and is executable
+ if(this.executable.exists() && this.executable.isFile() && this.executable.isExecutable())
+ {
+ var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
+ var processArguments = new Array(url);
+
+ process.init(this.executable);
+ process.run(false, processArguments, processArguments.length);
+ }
+ else
+ {
+ webdeveloper_error(document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_launchApplicationFailed", [this.applicationPath]));
+ }
+}
+
+// Called when the progress state changes
+WebDeveloperApplication.prototype.onStateChange = function(webProgress, request, stateFlags, status)
+{
+ // If the progress has stopped
+ if(stateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
+ {
+ this.launchWithFile();
+ }
+}
+
+// Indicates the interfaces this object supports
+WebDeveloperApplication.prototype.QueryInterface = function(id)
+{
+ // If the query is for a supported interface
+ if(id.equals(Components.interfaces.nsISupports) || id.equals(Components.interfaces.nsIWebProgressListener))
+ {
+ return this;
+ }
+
+ throw Components.results.NS_NOINTERFACE;
+}
+
+// Dummy methods requiring implementations
+WebDeveloperApplication.prototype.onLocationChange = function(webProgress, request, location) {}
+WebDeveloperApplication.prototype.onProgressChange = function(webProgress, request, currentSelfProgress, maximumSelfProgress, currentTotalProgress, maximumTotalProgress) {}
+WebDeveloperApplication.prototype.onSecurityChange = function(webProgress, request, state) {}
+WebDeveloperApplication.prototype.onStatusChange = function(webProgress, request, status, message) {}