New man-page location: mentioned in debian/changelog, adapted debian/rules
[conkeror.git] / modules / load-spec.js
blobdc45b8890b8a6143e0a29dd83635aecac0b68733
1 /**
2  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
3  *
4  * Use, modification, and distribution are subject to the terms specified in the
5  * COPYING file.
6 **/
8 /**
9  * A load_spec has the following properties:
10  *
11  * Name:        Required?   Type:           Description:
12  * -----        ---------   -----           ------------
13  * uri          required    string          Specifies the URI of the target.
14  *
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.
18  *
19  * flags        optional    number          Specifies flags to pass to nsIWebNavigation.loadURI
20  *
21  * cache_key    optional    nsISHEntry      Specifies a key for accessing the target from the cache.
22  *
23  * referrer     optional    nsIURI          Specifies the referrer URI to use to access the target.
24  *
25  * post_data    optional    nsIInputStream  Specifies POST data to use to access the target.
26  *                                          The request headers should be included in this stream.
27  *
28  * request_mime_type
29  *              optional    string          Specifies the MIME type for the request post data.
30  *
31  * raw_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.
35  *
36  * mime_type    optional    string          Specifies the MIME type of the target.
37  *
38  * title        optional    string          Specifies a title/description text associated with the target.
39  *
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.
42  *
43  * filename     optional    string          Specifies a default filename to use to save the target.
44  *
45  * filename_extension
46  *              optional    string          Specifies a default filename extension to use to save the target.
47  *
48  * suggest_filename_from_uri
49  *              optional    boolean         Specifies whether to attempt to generate a filename from the URI.
50  *                                          Defaults to true.
51  */
53 require("webjump.js");
55 function load_spec_from_element (elem) {
56     var spec = {};
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;
64     else {
65         var url = null;
66         var title = null;
68         if (elem instanceof Ci.nsIDOMHTMLAnchorElement ||
69             elem instanceof Ci.nsIDOMHTMLAreaElement ||
70             elem instanceof Ci.nsIDOMHTMLLinkElement) {
71             if (elem.hasAttribute("href"))
72                 url = elem.href;
73             title = elem.title || elem.textContent;
74         }
75         else if (elem instanceof Ci.nsIDOMHTMLImageElement) {
76             url = elem.src;
77             title = elem.title || elem.alt;
78         }
79         else {
80             var node = elem;
81             while (node && !(node instanceof Ci.nsIDOMHTMLAnchorElement))
82                 node = node.parentNode;
83             if (node) {
84                 if (node.hasAttribute("href"))
85                     url = node.href;
86                 else
87                     node = null;
88             }
89             if (!node) {
90                 // Try simple XLink
91                 node = elem;
92                 while (node) {
93                     if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
94                         url = node.getAttributeNS(XLINK_NS, "href");
95                         break;
96                     }
97                     node = node.parentNode;
98                 }
99                 if (url)
100                     url = makeURLAbsolute(node.baseURI, url);
101                 title = node.title || node.textContent;
102             }
103         }
104         if (url && url.length > 0) {
105             if (title && title.length == 0)
106                 title = null;
107             spec.uri = url;
108             spec.source_frame = elem.ownerDocument.defaultView;
109             spec.title = title;
110         }
111     }
112     return spec;
115 function load_spec (x) {
116     var spec;
117     if (typeof(x) == "string")
118         x = get_url_or_webjump(x);
119     if (typeof(x) == "string")
120         spec = { uri: x };
121     else if ((x instanceof Ci.nsIDOMNode) ||
122              (x instanceof Ci.nsIDOMWindow))
123     {
124         spec = load_spec_from_element(x);
125     } else if (typeof(x) == "object") {
126         spec = x;
127     }
128     if (! load_spec_uri_string(spec))
129         throw new Error("Invalid load-spec");
130     spec.__proto__ = load_spec.prototype;
131     return spec;
133 load_spec.prototype = {};
135 function load_spec_document(x) {
136     return x.document;
139 function load_spec_title(x) {
140     if (x.title)
141         return x.title;
142     if (x.document)
143         return x.document.title;
144     return null;
147 function load_spec_mime_type(x) {
148     if (x.mime_type)
149         return x.mime_type;
150     if (x.document)
151         return x.document.contentType || "application/octet-stream";
152     return mime_type_from_uri(load_spec_uri(x));
155 function load_spec_filename(x) {
156     return x.filename;
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)
170     try
171     {
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);
176         return desc;
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;
186     }
189 function load_spec_referrer(x) {
190     if (x.referrer)
191         return x.referrer;
192     if (x.document) {
193         load_spec_set_properties_from_sh_entry(x);
194         return x.referrer;
195     }
196     if (x.source_frame) {
197         x.referrer = x.source_frame.document.documentURIObject;
198         return x.referrer;
199     }
200     return null;
203 function load_spec_post_data(x) {
204     if (x.post_data)
205         return x.post_data;
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]]);
211         return x.post_data;
212     }
213     if (x.document) {
214         load_spec_set_properties_from_sh_entry(x);
215         return x.post_data;
216     }
217     return null;
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) {
229     if (x.cache_key)
230         return x.cache_key;
231     if (x.document) {
232         load_spec_set_properties_from_sh_entry(x);
233         return x.cache_key;
234     }
235     return null;
238 function load_spec_source_frame(x) {
239     if (x.source_frame)
240         return x.source_frame;
241     if (x.document)
242         return x.document.defaultView;
243     return null;
246 function load_spec_uri_string(x) {
247     if (x.uri)
248         return x.uri;
249     if (x.document && x.document.defaultView)
250         return x.document.defaultView.location.href;
251     if (x.document)
252         return x.document.documentURI;
253     return null;
256 function load_spec_uri(x) {
257     if (x.document && x.document.defaultView)
258         return make_uri(x.document.defaultView.location.href);
259     if (x.document)
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 "+
284     "will be used.");
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) {
300         try {
301             var atomservice = Cc['@mozilla.org/atom-service;1']
302                 .getService(Ci.nsIAtomService);
303             target.web_navigation.documentCharsetInfo.forcedCharset =
304                 atomservice.getAtom(forced_charset);
305         } catch (e) {}
306     }
308     if (flags == null)
309         flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
311     if (target instanceof content_buffer) {
312         try {
313             target.web_navigation.loadURI(uri, flags, referrer, post_data, null /* headers */);
314             target._display_URI = uri;
315             buffer_description_change_hook.run(target);
316         } catch (e) {
317             /* Ignore error for now */
318         }
319     } else {
320         try {
321             target.loadURI(uri, flags, referrer, post_data, null /* headers */);
322         } catch (e) {
323             /* Ignore error for now */
324         }
325     }