2 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
4 * Use, modification, and distribution are subject to the terms specified in the
9 * A load_spec has the following properties:
11 * Name: Required? Type: Description:
12 * ----- --------- ----- ------------
13 * uri required string Specifies the URI of the target.
15 * document optional nsIDOMDocument Specifies a document corresponding to the target.
16 * Can also provide a default value for the mime_type property,
17 * the title property, and the source_frame property.
19 * flags optional number Specifies flags to pass to nsIWebNavigation.loadURI
21 * cache_key optional nsISHEntry Specifies a key for accessing the target from the cache.
23 * referrer optional nsIURI Specifies the referrer URI to use to access the target.
25 * post_data optional nsIInputStream Specifies POST data to use to access the target.
26 * The request headers should be included in this stream.
29 * optional string Specifies the MIME type for the request post data.
32 * optional nsIInputStream Specifies the POST data to use to access the target.
33 * The request_mime_type property must also be set.
34 * This provides a value for post_data.
36 * mime_type optional string Specifies the MIME type of the target.
38 * title optional string Specifies a title/description text associated with the target.
40 * source_frame optional nsIDOMWindow Specifies the frame from which the link to the target was "obtained".
41 * Can provide a default value for referrer if document is not specified.
43 * filename optional string Specifies a default filename to use to save the target.
46 * optional string Specifies a default filename extension to use to save the target.
48 * suggest_filename_from_uri
49 * optional boolean Specifies whether to attempt to generate a filename from the URI.
53 require("webjump.js");
55 function load_spec_from_element (elem) {
57 if (elem instanceof Ci.nsIDOMWindow)
58 spec.document = elem.document;
60 else if (elem instanceof Ci.nsIDOMHTMLFrameElement ||
61 elem instanceof Ci.nsIDOMHTMLIFrameElement)
62 spec.document = elem.contentDocument;
68 if (elem instanceof Ci.nsIDOMHTMLAnchorElement ||
69 elem instanceof Ci.nsIDOMHTMLAreaElement ||
70 elem instanceof Ci.nsIDOMHTMLLinkElement) {
71 if (elem.hasAttribute("href"))
73 title = elem.title || elem.textContent;
75 else if (elem instanceof Ci.nsIDOMHTMLImageElement) {
77 title = elem.title || elem.alt;
81 while (node && !(node instanceof Ci.nsIDOMHTMLAnchorElement))
82 node = node.parentNode;
84 if (node.hasAttribute("href"))
93 if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
94 url = node.getAttributeNS(XLINK_NS, "href");
97 node = node.parentNode;
100 url = makeURLAbsolute(node.baseURI, url);
101 title = node.title || node.textContent;
104 if (url && url.length > 0) {
105 if (title && title.length == 0)
108 spec.source_frame = elem.ownerDocument.defaultView;
115 function load_spec (x) {
117 if (typeof(x) == "string")
118 x = get_url_or_webjump(x);
119 if (typeof(x) == "string")
121 else if ((x instanceof Ci.nsIDOMNode) ||
122 (x instanceof Ci.nsIDOMWindow))
124 spec = load_spec_from_element(x);
125 } else if (typeof(x) == "object") {
128 if (! load_spec_uri_string(spec))
129 throw new Error("Invalid load-spec");
130 spec.__proto__ = load_spec.prototype;
133 load_spec.prototype = {};
135 function load_spec_document(x) {
139 function load_spec_title(x) {
143 return x.document.title;
147 function load_spec_mime_type(x) {
151 return x.document.contentType || "application/octet-stream";
152 return mime_type_from_uri(load_spec_uri(x));
155 function load_spec_filename(x) {
159 function load_spec_filename_extension(x) {
160 return x.filename_extension;
163 function get_web_navigation_for_frame(frame) {
164 var ifr = frame.QueryInterface(Ci.nsIInterfaceRequestor);
165 return ifr.getInterface(Ci.nsIWebNavigation);
168 function get_SHEntry_for_document(doc)
172 var frame = doc.defaultView;
173 var webNav = get_web_navigation_for_frame(frame);
174 var pageLoader = webNav.QueryInterface(Ci.nsIWebPageDescriptor);
175 var desc = pageLoader.currentDescriptor.QueryInterface(Ci.nsISHEntry);
177 } catch (e) { return null; }
180 function load_spec_set_properties_from_sh_entry(x) {
181 var sh_entry = get_SHEntry_for_document(x.document);
182 if (sh_entry != null) {
183 x.cache_key = sh_entry;
184 x.referrer = sh_entry.referrerURI;
185 x.post_data = sh_entry.postData;
189 function load_spec_referrer(x) {
193 load_spec_set_properties_from_sh_entry(x);
196 if (x.source_frame) {
197 x.referrer = x.source_frame.document.documentURIObject;
203 function load_spec_post_data(x) {
206 if (x.raw_post_data) {
207 let y = x.raw_post_data;
208 if (typeof(y) == "string")
209 y = string_input_stream(y);
210 x.post_data = mime_input_stream(y, [["Content-Type", x.request_mime_type]]);
214 load_spec_set_properties_from_sh_entry(x);
220 function load_spec_raw_post_data(x) {
221 return x.raw_post_data;
224 function load_spec_request_mime_type(x) {
225 return x.request_mime_type;
228 function load_spec_cache_key(x) {
232 load_spec_set_properties_from_sh_entry(x);
238 function load_spec_source_frame(x) {
240 return x.source_frame;
242 return x.document.defaultView;
246 function load_spec_uri_string(x) {
249 if (x.document && x.document.defaultView)
250 return x.document.defaultView.location.href;
252 return x.document.documentURI;
256 function load_spec_uri(x) {
257 if (x.document && x.document.defaultView)
258 return make_uri(x.document.defaultView.location.href);
260 return x.document.documentURIObject;
261 return make_uri(load_spec_uri_string(x));
264 function load_spec_flags(x) {
265 return x.load_spec_flags;
268 function load_spec_mime_info(x) {
269 var type = load_spec_mime_type(x);
270 return mime_info_from_mime_type(type);
273 function load_spec_default_shell_command(x) {
274 var mime_type = load_spec_mime_type(x);
275 return get_mime_type_external_handler(mime_type);
278 function load_spec_forced_charset (x) {
279 return x.forced_charset;
282 define_variable('forced_charset_list', null,
283 "Alist mapping url-regexps to forced charsets. The first match "+
286 /* Target can be either a content_buffer or an nsIWebNavigation */
287 function apply_load_spec(target, spec) {
288 if (! (spec instanceof load_spec))
289 spec = load_spec(spec);
290 var uri = load_spec_uri_string(spec);
291 var flags = load_spec_flags(spec);
292 var referrer = load_spec_referrer(spec);
293 var post_data = load_spec_post_data(spec);
294 var forced_charset = load_spec_forced_charset(spec);
296 if (! forced_charset && forced_charset_list)
297 forced_charset = predicate_alist_match(forced_charset_list, uri);
299 if (forced_charset) {
301 var atomservice = Cc['@mozilla.org/atom-service;1']
302 .getService(Ci.nsIAtomService);
303 target.web_navigation.documentCharsetInfo.forcedCharset =
304 atomservice.getAtom(forced_charset);
309 flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
311 if (target instanceof content_buffer) {
313 target.web_navigation.loadURI(uri, flags, referrer, post_data, null /* headers */);
314 target._display_URI = uri;
315 buffer_description_change_hook.run(target);
317 /* Ignore error for now */
321 target.loadURI(uri, flags, referrer, post_data, null /* headers */);
323 /* Ignore error for now */