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 * element optional nsIDOMNode The DOM node of a load_spec created by load_spec_from_element.
21 * flags optional number Specifies flags to pass to nsIWebNavigation.loadURI
23 * cache_key optional nsISHEntry Specifies a key for accessing the target from the cache.
25 * referrer optional nsIURI Specifies the referrer URI to use to access the target.
27 * post_data optional nsIInputStream Specifies POST data to use to access the target.
28 * The request headers should be included in this stream.
31 * optional string Specifies the MIME type for the request post data.
34 * optional nsIInputStream Specifies the POST data to use to access the target.
35 * The request_mime_type property must also be set.
36 * This provides a value for post_data.
38 * mime_type optional string Specifies the MIME type of the target.
40 * title optional string Specifies a title/description text associated with the target.
42 * source_frame optional nsIDOMWindow Specifies the frame from which the link to the target was "obtained".
43 * Can provide a default value for referrer if document is not specified.
45 * filename optional string Specifies a default filename to use to save the target.
48 * optional string Specifies a default filename extension to use to save the target.
50 * suggest_filename_from_uri
51 * optional boolean Specifies whether to attempt to generate a filename from the URI.
57 require("webjump.js");
59 function page_fragment_load_spec (elem) {
60 var uri = makeURLAbsolute(elem.ownerDocument.documentURI,
61 "#" + (elem.id || elem.name));
62 var title = elem.ownerDocument.title;
63 if (elem.textContent) {
64 if (title) title += ' - ';
65 title += elem.textContent;
74 function load_spec_from_element (elem) {
76 if (elem instanceof Ci.nsIDOMWindow)
77 spec.document = elem.document;
79 else if (elem instanceof Ci.nsIDOMHTMLFrameElement ||
80 elem instanceof Ci.nsIDOMHTMLIFrameElement)
81 spec.document = elem.contentDocument;
87 if ((elem instanceof Ci.nsIDOMHTMLAnchorElement ||
88 elem instanceof Ci.nsIDOMHTMLAreaElement ||
89 elem instanceof Ci.nsIDOMHTMLLinkElement) &&
90 elem.hasAttribute("href"))
93 title = elem.title || elem.textContent;
95 else if (elem instanceof Ci.nsIDOMHTMLImageElement) {
97 title = elem.title || elem.alt;
99 else if (elem.hasAttribute("id") ||
100 (elem instanceof Ci.nsIDOMHTMLAnchorElement &&
101 elem.hasAttribute("name"))) {
102 return page_fragment_load_spec(elem);
106 while (node && !(node instanceof Ci.nsIDOMHTMLAnchorElement))
107 node = node.parentNode;
109 if (node.hasAttribute("href"))
118 if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
119 url = node.getAttributeNS(XLINK_NS, "href");
122 node = node.parentNode;
125 url = makeURLAbsolute(node.baseURI, url);
126 title = node.title || node.textContent;
129 if (url && url.length > 0) {
130 if (title && title.length == 0)
133 spec.source_frame = elem.ownerDocument.defaultView;
141 function load_spec (x) {
143 if (typeof(x) == "string")
144 x = get_url_or_webjump(x);
145 if (typeof(x) == "string")
147 else if ((x instanceof Ci.nsIDOMNode) ||
148 (x instanceof Ci.nsIDOMWindow))
150 spec = load_spec_from_element(x);
151 } else if (typeof(x) == "object") {
154 if (! load_spec_uri_string(spec))
155 throw new Error("Invalid load-spec");
156 spec.__proto__ = load_spec.prototype;
159 load_spec.prototype = {
160 constructor: load_spec,
161 toString: function () "[object load_spec]"
164 function load_spec_document (x) {
168 function load_spec_element (x) {
172 function load_spec_title (x) {
176 return x.document.title;
180 function load_spec_mime_type (x) {
184 return x.document.contentType || "application/octet-stream";
185 return mime_type_from_uri(load_spec_uri(x));
188 function load_spec_filename (x) {
192 function load_spec_filename_extension (x) {
193 return x.filename_extension;
196 function get_web_navigation_for_frame (frame) {
197 var ifr = frame.QueryInterface(Ci.nsIInterfaceRequestor);
198 return ifr.getInterface(Ci.nsIWebNavigation);
201 function get_SHEntry_for_document (doc) {
203 var frame = doc.defaultView;
204 var webNav = get_web_navigation_for_frame(frame);
205 var pageLoader = webNav.QueryInterface(Ci.nsIWebPageDescriptor);
206 var desc = pageLoader.currentDescriptor.QueryInterface(Ci.nsISHEntry);
208 } catch (e) { return null; }
211 function load_spec_set_properties_from_sh_entry (x) {
212 var sh_entry = get_SHEntry_for_document(x.document);
213 if (sh_entry != null) {
214 x.cache_key = sh_entry;
215 x.referrer = sh_entry.referrerURI;
216 x.post_data = sh_entry.postData;
220 function load_spec_referrer (x) {
224 load_spec_set_properties_from_sh_entry(x);
227 if (x.source_frame) {
228 x.referrer = x.source_frame.document.documentURIObject;
234 function load_spec_post_data (x) {
237 if (x.raw_post_data) {
238 let y = x.raw_post_data;
239 if (typeof(y) == "string")
240 y = string_input_stream(y);
241 x.post_data = mime_input_stream(y, [["Content-Type", x.request_mime_type]]);
245 load_spec_set_properties_from_sh_entry(x);
251 function load_spec_raw_post_data (x) {
252 return x.raw_post_data;
255 function load_spec_request_mime_type (x) {
256 return x.request_mime_type;
259 function load_spec_cache_key (x) {
263 load_spec_set_properties_from_sh_entry(x);
269 function load_spec_source_frame (x) {
271 return x.source_frame;
273 return x.document.defaultView;
277 function load_spec_uri_string (x) {
280 if (x.document && x.document.defaultView)
281 return x.document.defaultView.location.href;
283 return x.document.documentURI;
287 function load_spec_uri (x) {
288 if (x.document && x.document.defaultView)
289 return make_uri(x.document.defaultView.location.href);
291 return x.document.documentURIObject;
292 return make_uri(load_spec_uri_string(x));
295 function load_spec_flags (x) {
296 return x.load_spec_flags;
299 function load_spec_mime_info (x) {
300 var type = load_spec_mime_type(x);
301 return mime_info_from_mime_type(type);
304 function load_spec_default_shell_command (x) {
305 var mime_type = load_spec_mime_type(x);
306 return external_content_handlers.get(mime_type);
309 function load_spec_forced_charset (x) {
310 return x.forced_charset;
313 define_variable('forced_charset_list', null,
314 "Alist mapping url-regexps to forced charsets. The first match "+
317 /* Target can be either a content_buffer or an nsIWebNavigation */
318 function apply_load_spec (target, spec) {
319 if (! (spec instanceof load_spec))
320 spec = load_spec(spec);
321 var uri = load_spec_uri_string(spec);
322 var flags = load_spec_flags(spec);
323 var referrer = load_spec_referrer(spec);
324 var post_data = load_spec_post_data(spec);
325 var forced_charset = load_spec_forced_charset(spec);
327 if (! forced_charset && forced_charset_list)
328 forced_charset = predicate_alist_match(forced_charset_list, uri);
330 if (forced_charset) {
332 var atomservice = Cc['@mozilla.org/atom-service;1']
333 .getService(Ci.nsIAtomService);
334 target.web_navigation.documentCharsetInfo.forcedCharset =
335 atomservice.getAtom(forced_charset);
340 flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
342 if (target instanceof content_buffer) {
344 target.web_navigation.loadURI(uri, flags, referrer, post_data, null /* headers */);
345 target._display_uri = uri;
346 buffer_description_change_hook.run(target);
348 /* Ignore error for now */
352 target.loadURI(uri, flags, referrer, post_data, null /* headers */);
354 /* Ignore error for now */
359 provide("load-spec");