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
);