2 * (C) Copyright 2004-2007 Shawn Betts
3 * (C) Copyright 2007 John J. Foerch
4 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
6 * Use, modification, and distribution are subject to the terms specified in the
10 require("content-buffer.js");
11 require("load-spec.js");
12 require("suggest-file-name.js");
14 /* buffer is used only to associate with the download */
15 define_keywords("$use_cache", "$buffer", "$prepare_download");
16 function save_uri(lspec, output_file) {
17 keywords(arguments, $use_cache = false);
19 var use_cache = arguments.$use_cache;
21 var buffer = arguments.$buffer;
23 var prepare_download = arguments.$prepare_download;
26 var uri = load_spec_uri(lspec);
27 var referrer_uri = load_spec_referrer(lspec);
28 var post_data = load_spec_post_data(lspec);
30 cache_key = load_spec_cache_key(lspec);
32 var file_uri = makeFileURL(output_file);
34 var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
36 persist.persistFlags =
37 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
38 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION |
39 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_CLEANUP_ON_FAILURE;
42 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE;
44 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE;
46 var info = register_download(buffer, uri);
48 prepare_download(info);
50 var tr = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer);
51 tr.init(uri, file_uri, output_file.leafName,
52 load_spec_mime_info(lspec),
53 null /* start time */,
56 persist.progressListener = tr;
57 persist.saveURI(uri, cache_key, referrer_uri, post_data, null /* no extra headers */, file_uri);
63 // We have no DOM, and can only save the URL as is.
64 const SAVEMODE_FILEONLY = 0x00;
65 // We have a DOM and can save as complete.
66 const SAVEMODE_COMPLETE_DOM = 0x01;
67 // We have a DOM which we can serialize as text.
68 const SAVEMODE_COMPLETE_TEXT = 0x02;
70 function get_save_mode_from_content_type(content_type) {
71 var mode = SAVEMODE_FILEONLY;
72 switch (content_type) {
74 case "application/xhtml+xml":
75 mode |= SAVEMODE_COMPLETE_TEXT;
78 case "application/xml":
79 mode |= SAVEMODE_COMPLETE_DOM;
85 define_keywords("$use_cache", "$buffer", "$wrap_column", "$prepare_download");
86 function save_document_as_text(document, output_file)
88 keywords(arguments, $use_cache = true, $wrap_column = 80);
90 var mode = get_save_mode_from_content_type(document.contentType);
91 if (!(mode & SAVEMODE_COMPLETE_TEXT))
92 throw interactive_error("Document cannot be saved as text.");
94 var use_cache = arguments.$use_cache;
96 var prepare_download = arguments.$prepare_download;
98 var buffer = arguments.$buffer;
100 var uri = document.documentURIObject;
102 var file_uri = makeFileURL(output_file);
104 var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
106 persist.persistFlags =
107 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
108 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION |
109 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_CLEANUP_ON_FAILURE;
112 Ci.nsIWebBrowserPersist.ENCODE_FLAGS_FORMATTED |
113 Ci.nsIWebBrowserPersist.ENCODE_FLAGS_ABSOLUTE_LINKS |
114 Ci.nsIWebBrowserPersist.ENCODE_FLAGS_NOFRAMES_CONTENT;
118 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE;
120 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE;
124 var info = register_download(buffer, uri);
125 if (prepare_download)
126 prepare_download(info);
128 var tr = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer);
129 tr.init(uri, file_uri, output_file.leafName,
130 mime_info_from_mime_type("text/plain"),
131 null /* start time */,
132 null /* temp file */,
134 persist.progressListener = tr;
135 persist.saveDocument(document, file_uri, null /* data path */,
136 "text/plain", encoding_flags,
137 arguments.$wrap_column);
141 define_keywords("$use_cache", "$buffer", "$prepare_download");
142 function save_document_complete(document, output_file, output_dir) {
144 var mime_type = document.contentType;
146 var mode = get_save_mode_from_content_type(mime_type);
147 if (!(mode & SAVEMODE_COMPLETE_DOM))
148 throw interactive_error("Complete document cannot be saved.");
150 var use_cache = arguments.$use_cache;
152 var buffer = arguments.$buffer;
154 var prepare_download = arguments.$prepare_download;
156 var uri = document.documentURIObject;
158 var file_uri = makeFileURL(output_file);
160 var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
162 persist.persistFlags =
163 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
164 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION |
165 Ci.nsIWebBrowserPersist.PERSIST_FLAGS_CLEANUP_ON_FAILURE;
168 Ci.nsIWebBrowserPersist.ENCODE_FLAGS_BASIC_ENTITIES;
171 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE;
173 persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE;
176 var info = register_download(buffer, uri);
177 if (prepare_download)
178 prepare_download(info);
180 var tr = Cc["@mozilla.org/transfer;1"].createInstance(Ci.nsITransfer);
181 tr.init(uri, file_uri, output_file.leafName,
182 mime_info_from_mime_type(mime_type),
183 null /* start time */,
184 null /* temp file */,
186 persist.progressListener = tr;
187 persist.saveDocument(document, file_uri, output_dir /* data path */,
188 mime_type, encoding_flags,
193 function download_failed_error() {
194 var e = new Error("Download failed");
195 e.__proto__ = download_failed_error.prototype;
198 download_failed_error.prototype.__proto__ = Error.prototype;
200 /* Returns an array of two elements: the first element is the
201 * nsILocalFile object, the second element is a boolean indicating
202 * whether the file is temporary and should be deleted when the caller is
205 define_keywords("$action", "$shell_command", "$shell_command_cwd", "$buffer", "$use_cache");
206 function download_as_temporary(lspec) {
207 keywords(arguments, $use_cache = true);
209 var action_description = arguments.$action;
210 var shell_command = arguments.$shell_command;
211 var shell_command_cwd = arguments.$shell_command_cwd;
213 var uri = load_spec_uri(lspec);
214 // If it is local file, there is no need to download it
215 if (uri.scheme == "file")
217 let file = uri.QueryInterface(Ci.nsIFileURL).file;
219 yield co_return([file, false /* not temporary */]);
223 var file = get_temporary_file(suggest_file_name(lspec));
225 var cc = yield CONTINUATION;
227 function handle_state_change(info) {
228 var state = info.state;
230 case DOWNLOAD_CANCELED:
231 case DOWNLOAD_FAILED:
232 info.remove(); // ensure that the download cannot be retried later
234 // Delete the temporary file
235 file.remove(false /*non-recursive*/);
237 cc.throw(download_failed_error());
239 case DOWNLOAD_FINISHED:
240 cc([file, true /* temporary */]);
245 save_uri(lspec, file,
246 $use_cache = arguments.$use_cache,
247 $buffer = arguments.$buffer,
248 $prepare_download = function (info) {
249 if (action_description != null) {
250 info.action_description = action_description;
251 info.temporary_status = DOWNLOAD_TEMPORARY_FOR_ACTION;
252 } else if (shell_command != null) {
253 info.set_shell_command(shell_command, shell_command_cwd);
254 info.temporary_status = DOWNLOAD_TEMPORARY_FOR_COMMAND;
256 add_hook.call(info, "download_state_change_hook", handle_state_change);
259 var result = yield SUSPEND;
260 yield co_return(result);