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.
52 require("webjump.js");
54 function page_fragment_load_spec (elem
) {
55 var uri
= makeURLAbsolute(elem
.ownerDocument
.documentURI
,
56 "#" + (elem
.id
|| elem
.name
));
57 var title
= elem
.ownerDocument
.title
;
58 if (elem
.textContent
) {
59 if (title
) title
+= ' - ';
60 title
+= elem
.textContent
;
67 spec
.__proto__
= load_spec
.prototype;
71 function load_spec_from_element (elem
) {
73 if (elem
instanceof Ci
.nsIDOMWindow
)
74 spec
.document
= elem
.document
;
76 else if (elem
instanceof Ci
.nsIDOMHTMLFrameElement
||
77 elem
instanceof Ci
.nsIDOMHTMLIFrameElement
)
78 spec
.document
= elem
.contentDocument
;
84 if ((elem
instanceof Ci
.nsIDOMHTMLAnchorElement
||
85 elem
instanceof Ci
.nsIDOMHTMLAreaElement
||
86 elem
instanceof Ci
.nsIDOMHTMLLinkElement
) &&
87 elem
.hasAttribute("href"))
90 title
= elem
.title
|| elem
.textContent
;
92 else if (elem
instanceof Ci
.nsIDOMHTMLImageElement
) {
94 title
= elem
.title
|| elem
.alt
;
96 else if (elem
.hasAttribute("id") ||
97 (elem
instanceof Ci
.nsIDOMHTMLAnchorElement
&&
98 elem
.hasAttribute("name"))) {
99 return page_fragment_load_spec(elem
);
103 while (node
&& !(node
instanceof Ci
.nsIDOMHTMLAnchorElement
))
104 node
= node
.parentNode
;
106 if (node
.hasAttribute("href"))
115 if (node
.nodeType
== Ci
.nsIDOMNode
.ELEMENT_NODE
) {
116 url
= node
.getAttributeNS(XLINK_NS
, "href");
119 node
= node
.parentNode
;
122 url
= makeURLAbsolute(node
.baseURI
, url
);
123 title
= node
.title
|| node
.textContent
;
126 if (url
&& url
.length
> 0) {
127 if (title
&& title
.length
== 0)
130 spec
.source_frame
= elem
.ownerDocument
.defaultView
;
138 function load_spec (x
) {
140 if (typeof(x
) == "string")
141 x
= get_url_or_webjump(x
);
142 if (typeof(x
) == "string")
144 else if ((x
instanceof Ci
.nsIDOMNode
) ||
145 (x
instanceof Ci
.nsIDOMWindow
))
147 spec
= load_spec_from_element(x
);
148 } else if (typeof(x
) == "object") {
151 if (! load_spec_uri_string(spec
))
152 throw new Error("Invalid load-spec");
153 spec
.__proto__
= load_spec
.prototype;
156 load_spec
.prototype = {
157 constructor: load_spec
,
158 toString: function () "#<load_spec>",
163 filename_extension
: null,
164 forced_charset
: null,
165 load_spec_flags
: null,
170 request_mime_type
: null,
176 function load_spec_document (x
) {
180 function load_spec_element (x
) {
184 function load_spec_title (x
) {
188 return x
.document
.title
;
192 function load_spec_mime_type (x
) {
196 return x
.document
.contentType
|| "application/octet-stream";
197 return mime_type_from_uri(load_spec_uri(x
));
200 function load_spec_filename (x
) {
204 function load_spec_filename_extension (x
) {
205 return x
.filename_extension
;
208 function get_web_navigation_for_frame (frame
) {
209 var ifr
= frame
.QueryInterface(Ci
.nsIInterfaceRequestor
);
210 return ifr
.getInterface(Ci
.nsIWebNavigation
);
213 function get_SHEntry_for_document (doc
) {
215 var frame
= doc
.defaultView
;
216 var webNav
= get_web_navigation_for_frame(frame
);
217 var pageLoader
= webNav
.QueryInterface(Ci
.nsIWebPageDescriptor
);
218 var desc
= pageLoader
.currentDescriptor
.QueryInterface(Ci
.nsISHEntry
);
220 } catch (e
) { return null; }
223 function load_spec_set_properties_from_sh_entry (x
) {
224 var sh_entry
= get_SHEntry_for_document(x
.document
);
225 if (sh_entry
!= null) {
226 x
.cache_key
= sh_entry
;
227 x
.referrer
= sh_entry
.referrerURI
;
228 x
.post_data
= sh_entry
.postData
;
232 function load_spec_referrer (x
) {
236 load_spec_set_properties_from_sh_entry(x
);
239 if (x
.source_frame
) {
240 x
.referrer
= x
.source_frame
.document
.documentURIObject
;
246 function load_spec_post_data (x
) {
249 if (x
.raw_post_data
) {
250 let y
= x
.raw_post_data
;
251 if (typeof y
== "string")
252 y
= string_input_stream(y
);
253 x
.post_data
= mime_input_stream(y
, [["Content-Type", x
.request_mime_type
]]);
257 load_spec_set_properties_from_sh_entry(x
);
263 function load_spec_raw_post_data (x
) {
264 return x
.raw_post_data
;
267 function load_spec_request_mime_type (x
) {
268 return x
.request_mime_type
;
271 function load_spec_cache_key (x
) {
275 load_spec_set_properties_from_sh_entry(x
);
281 function load_spec_source_frame (x
) {
283 return x
.source_frame
;
285 return x
.document
.defaultView
;
289 function load_spec_uri_string (x
) {
292 if (x
.document
&& x
.document
.defaultView
)
293 return x
.document
.defaultView
.location
.href
;
295 return x
.document
.documentURI
;
299 function load_spec_uri (x
) {
300 if (x
.document
&& x
.document
.defaultView
)
301 return make_uri(x
.document
.defaultView
.location
.href
);
303 return x
.document
.documentURIObject
;
304 return make_uri(load_spec_uri_string(x
));
307 function load_spec_flags (x
) {
308 return x
.load_spec_flags
;
311 function load_spec_mime_info (x
) {
312 var type
= load_spec_mime_type(x
);
313 return mime_info_from_mime_type(type
);
316 function load_spec_default_shell_command (x
) {
317 var mime_type
= load_spec_mime_type(x
);
318 return external_content_handlers
.get(mime_type
);
321 function load_spec_forced_charset (x
) {
322 return x
.forced_charset
;
325 define_variable('forced_charset_list', null,
326 "Alist mapping url-regexps to forced charsets. The first match "+
329 /* Target can be either a content_buffer or an nsIWebNavigation */
330 function apply_load_spec (target
, spec
) {
331 if (! (spec
instanceof load_spec
))
332 spec
= load_spec(spec
);
333 var uri
= load_spec_uri_string(spec
);
334 var flags
= load_spec_flags(spec
);
335 var referrer
= load_spec_referrer(spec
);
336 var post_data
= load_spec_post_data(spec
);
337 var forced_charset
= load_spec_forced_charset(spec
);
339 if (! forced_charset
&& forced_charset_list
)
340 forced_charset
= predicate_alist_match(forced_charset_list
, uri
);
342 if (forced_charset
) {
344 var atomservice
= Cc
['@mozilla.org/atom-service;1']
345 .getService(Ci
.nsIAtomService
);
346 target
.web_navigation
.documentCharsetInfo
.forcedCharset
=
347 atomservice
.getAtom(forced_charset
);
352 flags
= Ci
.nsIWebNavigation
.LOAD_FLAGS_NONE
;
354 if (target
instanceof content_buffer
) {
356 target
.web_navigation
.loadURI(uri
, flags
, referrer
, post_data
, null /* headers */);
357 target
._display_uri
= uri
;
358 buffer_description_change_hook
.run(target
);
360 /* Ignore error for now */
364 target
.loadURI(uri
, flags
, referrer
, post_data
, null /* headers */);
366 /* Ignore error for now */
371 provide("load-spec");