Changed EphyHistoryWindow to use the new backend, some things still remain (selected_...
[ephy-soc.git] / embed / mozilla / mozilla-embed-persist.cpp
blobb3b686c0686bc13462e24b742903fa1c152c1cf3
1 /*
2 * Copyright © 2000, 2001, 2002 Marco Pesenti Gritti
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * $Id: mozilla-embed-persist.cpp 6952 2007-03-11 19:42:02Z chpe $
21 #include "mozilla-config.h"
22 #include "config.h"
24 #include <stddef.h>
26 #include <nsStringAPI.h>
28 #include <nsCOMPtr.h>
29 #include <nsComponentManagerUtils.h>
30 #include <nsCWebBrowserPersist.h>
31 #include <nsICacheEntryDescriptor.h>
32 #include <nsICacheService.h>
33 #include <nsICacheSession.h>
34 #include <nsIDOMSerializer.h>
35 #include <nsIFile.h>
36 #include <nsIHistoryEntry.h>
37 #include <nsIInputStream.h>
38 #include <nsIIOService.h>
39 #include <nsILocalFile.h>
40 #include <nsISHEntry.h>
41 #include <nsIURI.h>
42 #include <nsIWebBrowserPersist.h>
43 #include <nsNetCID.h>
44 #include <nsNetError.h>
45 #include <nsServiceManagerUtils.h>
46 #include <nsXPCOM.h>
48 #include "EphyBrowser.h"
49 #include "EphyHeaderSniffer.h"
50 #include "EphyUtils.h"
51 #include "MozDownload.h"
53 #include "ephy-debug.h"
54 #include "ephy-embed-shell.h"
55 #include "ephy-file-helpers.h"
56 #include "mozilla-embed.h"
58 #include "mozilla-embed-persist.h"
60 static void
61 mozilla_embed_persist_class_init (MozillaEmbedPersistClass *klass);
62 static void
63 mozilla_embed_persist_init (MozillaEmbedPersist *ges);
64 static void
65 mozilla_embed_persist_finalize (GObject *object);
67 #define MOZILLA_EMBED_PERSIST_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), MOZILLA_TYPE_EMBED_PERSIST, MozillaEmbedPersistPrivate))
69 struct MozillaEmbedPersistPrivate
71 nsCOMPtr<nsIWebBrowserPersist> mPersist;
74 static GObjectClass *parent_class = NULL;
76 GType
77 mozilla_embed_persist_get_type (void)
79 static GType type = 0;
81 if (G_UNLIKELY (type == 0))
83 const GTypeInfo our_info =
85 sizeof (MozillaEmbedPersistClass),
86 NULL, /* base_init */
87 NULL, /* base_finalize */
88 (GClassInitFunc) mozilla_embed_persist_class_init,
89 NULL, /* class_finalize */
90 NULL, /* class_data */
91 sizeof (MozillaEmbedPersist),
92 0, /* n_preallocs */
93 (GInstanceInitFunc) mozilla_embed_persist_init
96 type = g_type_register_static (EPHY_TYPE_EMBED_PERSIST,
97 "MozillaEmbedPersist",
98 &our_info, (GTypeFlags) 0);
101 return type;
104 static void
105 mozilla_embed_persist_init (MozillaEmbedPersist *persist)
107 persist->priv = MOZILLA_EMBED_PERSIST_GET_PRIVATE (persist);
109 persist->priv->mPersist = do_CreateInstance (NS_WEBBROWSERPERSIST_CONTRACTID);
112 static void
113 mozilla_embed_persist_finalize (GObject *object)
115 MozillaEmbedPersist *persist = MOZILLA_EMBED_PERSIST (object);
117 persist->priv->mPersist = nsnull;
119 G_OBJECT_CLASS (parent_class)->finalize (object);
122 void
123 mozilla_embed_persist_completed (MozillaEmbedPersist *persist)
125 g_signal_emit_by_name (persist, "completed");
126 g_object_unref (persist);
129 void
130 mozilla_embed_persist_cancelled (MozillaEmbedPersist *persist)
132 g_signal_emit_by_name (persist, "cancelled");
133 g_object_unref (persist);
136 static void
137 impl_cancel (EphyEmbedPersist *persist)
139 nsCOMPtr<nsIWebBrowserPersist> bpersist =
140 MOZILLA_EMBED_PERSIST (persist)->priv->mPersist;
141 nsCOMPtr<nsICancelable> cancelable (do_QueryInterface (bpersist));
142 if (cancelable)
144 cancelable->Cancel (NS_BINDING_ABORTED);
147 g_object_unref (persist);
150 static gboolean
151 impl_save (EphyEmbedPersist *persist)
153 nsresult rv;
154 char *filename;
155 char *uri;
156 gint64 max_size;
157 EphyEmbed *embed;
158 EphyEmbedPersistFlags flags;
159 EphyEmbedSingle *single;
161 single = EPHY_EMBED_SINGLE (ephy_embed_shell_get_embed_single (embed_shell));
163 g_object_ref (persist);
165 g_object_get (persist,
166 "source", &uri,
167 "dest", &filename,
168 "flags", &flags,
169 "embed", &embed,
170 "max_size", &max_size,
171 (char *) NULL);
173 g_return_val_if_fail (!(flags & EPHY_EMBED_PERSIST_COPY_PAGE)
174 || embed != NULL, FALSE);
176 EphyBrowser *browser = NULL;
177 if (embed)
179 browser = (EphyBrowser *) _mozilla_embed_get_ephy_browser (MOZILLA_EMBED(embed));
181 g_object_unref (embed);
183 NS_ENSURE_TRUE (browser, FALSE);
185 /* we must have one of uri or browser */
186 g_assert (browser != NULL || uri != NULL);
188 /* Get the uri to save to */
189 nsCOMPtr<nsIURI> inURI;
190 if (uri)
192 /* FIXME: origin charset!! */
193 rv = EphyUtils::NewURI (getter_AddRefs(inURI), nsCString(uri));
194 NS_ENSURE_SUCCESS (rv, FALSE);
196 else
198 rv = browser->GetDocumentURI (getter_AddRefs (inURI));
199 NS_ENSURE_SUCCESS (rv, FALSE);
202 /* Get post data */
203 nsCOMPtr<nsIInputStream> postData;
204 /* FIXME: don't do this on COPY_PAGE to ensure we don't end up reposting? */
205 if (browser)
207 PRInt32 sindex;
209 nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(browser->mWebBrowser));
210 nsCOMPtr<nsISHistory> sessionHistory;
211 webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
212 nsCOMPtr<nsIHistoryEntry> entry;
213 sessionHistory->GetIndex(&sindex);
214 sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
215 nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
216 if (shEntry)
218 shEntry->GetPostData(getter_AddRefs(postData));
222 /* Get the DOM document if a uri is not specified */
223 nsCOMPtr<nsIDOMDocument> DOMDocument;
224 if (!uri)
226 if (flags & EPHY_EMBED_PERSIST_MAINDOC)
228 browser->GetDocument (getter_AddRefs(DOMDocument));
230 else
232 browser->GetTargetDocument (getter_AddRefs(DOMDocument));
234 NS_ENSURE_TRUE (DOMDocument, FALSE);
238 /* Get the current page descriptor */
239 nsCOMPtr<nsISupports> cacheDescriptor;
240 if (browser)
242 browser->GetPageDescriptor(getter_AddRefs (cacheDescriptor));
245 /* Try to get a descriptor from the cache session */
246 /* FIXME: what about https?? */
247 PRBool isHttp = PR_FALSE, isHttps = PR_FALSE;
248 if (!cacheDescriptor &&
249 (flags & EPHY_EMBED_PERSIST_FROM_CACHE) &&
250 inURI &&
251 ((NS_SUCCEEDED (inURI->SchemeIs ("http", &isHttp)) && isHttp) ||
252 (NS_SUCCEEDED (inURI->SchemeIs ("https", &isHttps)) && isHttps )))
254 nsCOMPtr<nsICacheService> cacheService
255 (do_GetService(NS_CACHESERVICE_CONTRACTID));
256 if (cacheService)
258 nsCOMPtr<nsICacheSession> cacheSession;
259 rv = cacheService->CreateSession ("HTTP",
260 nsICache::STORE_ANYWHERE,
261 PR_TRUE,
262 getter_AddRefs (cacheSession));
263 if (NS_SUCCEEDED (rv) && cacheSession)
265 nsCOMPtr<nsICacheEntryDescriptor> descriptor;
267 nsCString spec;
268 inURI->GetSpec (spec);
270 rv = cacheSession->OpenCacheEntry
271 (spec,
272 nsICache::ACCESS_READ,
273 PR_FALSE, getter_AddRefs (descriptor));
275 cacheDescriptor = do_QueryInterface (descriptor);
277 LOG ("Getting cache descriptor for '%s' rv=%x", spec.get(), rv);
282 LOG ("Cache descriptor %p", cacheDescriptor.get());
284 /* if we have COPY_PAGE, we *need* to have a page descriptor, else we'll re-fetch
285 * the page, which will possibly give a different page than the original which we
286 * need for view source
288 NS_ENSURE_TRUE (!(flags & EPHY_EMBED_PERSIST_COPY_PAGE) || cacheDescriptor, FALSE);
290 if (filename == NULL || filename[0] == '\0')
292 /* Get a temp filename to save to */
293 char *tmp_filename, *base;
294 base = g_build_filename (g_get_tmp_dir (), "sav-XXXXXX", (char *) NULL);
295 tmp_filename = ephy_file_tmp_filename (base, "html");
296 g_free (base);
297 if (tmp_filename == NULL) return FALSE;
299 nsCOMPtr<nsILocalFile> tmpFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
300 NS_ENSURE_TRUE (tmpFile, FALSE);
302 tmpFile->InitWithNativePath (nsCString (tmp_filename));
303 g_free (tmp_filename);
305 /* Create an header sniffer and do the save */
306 nsCOMPtr<nsIWebBrowserPersist> webPersist =
307 MOZILLA_EMBED_PERSIST (persist)->priv->mPersist;
308 NS_ENSURE_TRUE (webPersist, FALSE);
310 EphyHeaderSniffer* sniffer = new EphyHeaderSniffer
311 (webPersist, MOZILLA_EMBED_PERSIST (persist),
312 tmpFile, inURI, DOMDocument, postData, single);
313 if (!sniffer) return FALSE;
315 webPersist->SetProgressListener(sniffer);
316 rv = webPersist->SaveURI(inURI, cacheDescriptor, nsnull /* FIXME: Referrer */, nsnull, nsnull, tmpFile);
317 if (NS_FAILED (rv)) return FALSE;
319 else
321 /* Filename to save to */
322 nsCOMPtr<nsILocalFile> destFile;
323 NS_NewNativeLocalFile (nsCString(filename),
324 PR_TRUE, getter_AddRefs(destFile));
325 NS_ENSURE_TRUE (destFile, FALSE);
327 rv = InitiateMozillaDownload (DOMDocument, inURI, destFile,
328 nsnull, inURI, MOZILLA_EMBED_PERSIST (persist),
329 postData, cacheDescriptor, max_size);
330 if (NS_FAILED (rv)) return FALSE;
333 g_free (uri);
334 g_free (filename);
336 return TRUE;
339 static char *
340 impl_to_string (EphyEmbedPersist *persist)
342 EphyEmbed *embed;
343 nsCOMPtr<nsIDOMDocument> DOMDocument;
344 EphyEmbedPersistFlags flags;
345 EphyBrowser *browser;
346 nsresult rv = NS_OK;
348 g_object_ref (persist);
350 g_object_get (persist,
351 "flags", &flags,
352 "embed", &embed,
353 (char *) NULL);
354 g_object_unref (persist);
355 g_return_val_if_fail (embed != NULL, NULL);
357 browser = (EphyBrowser *) _mozilla_embed_get_ephy_browser (MOZILLA_EMBED(embed));
358 g_return_val_if_fail (browser != NULL, NULL);
360 if (flags & EPHY_EMBED_PERSIST_MAINDOC)
362 rv = browser->GetDocument (getter_AddRefs(DOMDocument));
364 else
366 rv = browser->GetTargetDocument (getter_AddRefs(DOMDocument));
369 nsCString cOutString;
370 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(DOMDocument);
371 if (node)
373 nsString outString;
374 nsCOMPtr<nsIDOMSerializer> serializer;
375 serializer = do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv);
376 if (serializer)
378 serializer->SerializeToString(node, outString);
380 NS_UTF16ToCString (outString, NS_CSTRING_ENCODING_UTF8, cOutString);
384 g_object_unref (embed);
386 return g_strdup (cOutString.get());
389 static GObject *
390 mozilla_embed_persist_constructor (GType type, guint n_construct_properties,
391 GObjectConstructParam *construct_params)
393 /* this will ensure that mozilla is started up */
394 ephy_embed_shell_get_embed_single (embed_shell);
396 return parent_class->constructor (type, n_construct_properties,
397 construct_params);
400 static void
401 mozilla_embed_persist_class_init (MozillaEmbedPersistClass *klass)
403 GObjectClass *object_class = G_OBJECT_CLASS (klass);
404 EphyEmbedPersistClass *persist_class = EPHY_EMBED_PERSIST_CLASS (klass);
406 parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
408 object_class->finalize = mozilla_embed_persist_finalize;
409 object_class->constructor = mozilla_embed_persist_constructor;
411 persist_class->save = impl_save;
412 persist_class->cancel = impl_cancel;
413 persist_class->to_string = impl_to_string;
415 g_type_class_add_private (object_class, sizeof(MozillaEmbedPersistPrivate));