diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | embed/mozilla/EphyAboutModule.cpp | 175 | ||||
-rw-r--r-- | embed/mozilla/EphyAboutModule.h | 12 | ||||
-rw-r--r-- | embed/mozilla/EphyRedirectChannel.cpp | 32 | ||||
-rw-r--r-- | embed/mozilla/EphyRedirectChannel.h | 50 | ||||
-rw-r--r-- | embed/mozilla/Makefile.am | 10 | ||||
-rw-r--r-- | embed/mozilla/MozRegisterComponents.cpp | 40 | ||||
-rw-r--r-- | src/ephy-session.c | 100 |
8 files changed, 353 insertions, 85 deletions
@@ -1,3 +1,22 @@ +2005-10-12 Christian Persch <chpe@cvs.gnome.org> + + * embed/mozilla/EphyAboutModule.cpp: + * embed/mozilla/EphyAboutModule.h: + A embed/mozilla/EphyRedirectChannel.cpp: + A embed/mozilla/EphyRedirectChannel.h: + * embed/mozilla/Makefile.am: + + Implement about:recover. Build the about module on all geckos, and + only #ifdef the about:neterror implementation for gecko 1.8. + + * src/ephy-session.c: (tab_added_cb), (impl_attach_window), + (ephy_session_autoresume), (write_tab), (ephy_session_save), + (parse_embed), (ephy_session_load): + + Record the page load status and page title in the session file, and + use about:recover when the page was still loading when the browser + crashed. + 2005-10-10 Christian Persch <chpe@cvs.gnome.org> * lib/ephy-string.c: (ephy_string_shorten): diff --git a/embed/mozilla/EphyAboutModule.cpp b/embed/mozilla/EphyAboutModule.cpp index c87d85d83..7a869ff2b 100644 --- a/embed/mozilla/EphyAboutModule.cpp +++ b/embed/mozilla/EphyAboutModule.cpp @@ -38,11 +38,13 @@ #include <nsNetCID.h> #include <nsString.h> #include <nsEscape.h> +#include <nsAutoPtr.h> #include <glib/gi18n.h> #include <gtk/gtk.h> #include "EphyAboutModule.h" +#include "EphyRedirectChannel.h" #include "EphyUtils.h" #include "ephy-debug.h" @@ -71,12 +73,19 @@ EphyAboutModule::NewChannel(nsIURI *aURI, nsCAutoString path; aURI->GetPath (path); +#ifdef HAVE_GECKO_1_8 if (strncmp (path.get(), "neterror?", strlen ("neterror?")) == 0) { return CreateErrorPage (aURI, _retval); } +#endif - if (strncmp (path.get (), "epiphany", strlen ("epiphany")) == 0) + if (strncmp (path.get (), "recover?", strlen ("recover?")) == 0) + { + return CreateRecoverPage (aURI, _retval); + } + + if (strcmp (path.get (), "epiphany") == 0) { return Redirect (nsDependentCString ("file://" SHARE_DIR "/epiphany.xhtml"), _retval); } @@ -121,13 +130,14 @@ EphyAboutModule::Redirect(const nsACString &aURL, } nsresult -EphyAboutModule::ParseErrorURL(const char *aURL, - nsACString &aError, - nsACString &aRawOriginURL, - nsACString &aOriginURL, - nsACString &aOriginCharset) +EphyAboutModule::ParseURL(const char *aURL, + nsACString &aCode, + nsACString &aRawOriginURL, + nsACString &aOriginURL, + nsACString &aOriginCharset, + nsACString &aTitle) { - /* The error page URL is of the form "epiphany:error?e=<error>&u=<URL>&c=<charset>&d=<description>" */ + /* The page URL is of the form "about:neterror?e=<errorcode>&u=<URL>&c=<charset>&d=<description>" */ const char *query = strstr (aURL, "?"); if (!query) return NS_ERROR_FAILURE; @@ -146,7 +156,7 @@ EphyAboutModule::ParseErrorURL(const char *aURL, switch (param[0]) { case 'e': - aError.Assign (nsUnescape (param + 2)); + aCode.Assign (nsUnescape (param + 2)); break; case 'u': aRawOriginURL.Assign (param + 2); @@ -155,6 +165,10 @@ EphyAboutModule::ParseErrorURL(const char *aURL, case 'c': aOriginCharset.Assign (nsUnescape (param + 2)); break; + /* The next one is not used in neterror but recover: */ + case 't': + aTitle.Assign (nsUnescape (param + 2)); + break; case 'd': /* we don't need mozilla's description parameter */ default: @@ -167,6 +181,7 @@ EphyAboutModule::ParseErrorURL(const char *aURL, return NS_OK; } +#ifdef HAVE_GECKO_1_8 nsresult EphyAboutModule::GetErrorMessage(nsIURI *aURI, const char *aError, @@ -344,20 +359,20 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, nsIChannel **_retval) { /* First parse the arguments */ - nsresult rv = NS_ERROR_ILLEGAL_VALUE; + nsresult rv; nsCAutoString spec; rv = aErrorURI->GetSpec (spec); NS_ENSURE_TRUE (NS_SUCCEEDED (rv), rv); - nsCAutoString error, rawurl, url, charset; - rv = ParseErrorURL (spec.get (), error, rawurl, url, charset); + nsCAutoString error, rawurl, url, charset, dummy; + rv = ParseURL (spec.get (), error, rawurl, url, charset, dummy); if (NS_FAILED (rv)) return rv; if (error.IsEmpty () || rawurl.IsEmpty () || url.IsEmpty()) return NS_ERROR_FAILURE; nsCOMPtr<nsIURI> uri; rv = EphyUtils::NewURI(getter_AddRefs (uri), url, charset.get()); /* FIXME can uri be NULL if the original url was invalid? */ - NS_ENSURE_TRUE (NS_SUCCEEDED (rv), rv); + NS_ENSURE_SUCCESS (rv, rv); char *primary = nsnull, *secondary = nsnull, *tertiary = nsnull, *linkintro = nsnull; rv = GetErrorMessage (uri, error.get(), &primary, &secondary, &tertiary, &linkintro); @@ -369,24 +384,95 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, */ if (rv == NS_ERROR_ILLEGAL_VALUE) { - nsCAutoString url(spec); + nsCAutoString newurl(spec); /* remove "about:neterror" part and insert mozilla's error page url */ - url.Cut(0, strlen ("about:neterror")); - url.Insert("chrome://global/content/netError.xhtml", 0); + newurl.Cut(0, strlen ("about:neterror")); + newurl.Insert("chrome://global/content/netError.xhtml", 0); - return Redirect (url, _retval); + return Redirect (newurl, _retval); } NS_ENSURE_SUCCESS (rv, rv); NS_ENSURE_TRUE (primary && secondary, NS_ERROR_FAILURE); - /* open the rendering stream */ + nsCOMPtr<nsIInputStreamChannel> channel; + rv = WritePage (aErrorURI, uri, rawurl, primary /* as title */, GTK_STOCK_DIALOG_ERROR, primary, secondary, tertiary, linkintro, getter_AddRefs (channel)); + NS_ENSURE_SUCCESS (rv, rv); + + rv = channel->SetURI (aErrorURI); + NS_ENSURE_SUCCESS (rv, rv); + + g_free (primary); + + return CallQueryInterface (channel, _retval); +} +#endif /* HAVE_GECKO_1_8 */ + +nsresult +EphyAboutModule::CreateRecoverPage(nsIURI *aRecoverURI, + nsIChannel **_retval) +{ + /* First parse the arguments */ + nsresult rv; + nsCAutoString spec; + rv = aRecoverURI->GetSpec (spec); + NS_ENSURE_TRUE (NS_SUCCEEDED (rv), rv); + + nsCAutoString error, rawurl, url, charset, title; + rv = ParseURL (spec.get (), error, rawurl, url, charset, title); + if (NS_FAILED (rv)) return rv; + if (rawurl.IsEmpty () || url.IsEmpty()) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + rv = EphyUtils::NewURI(getter_AddRefs (uri), url, charset.get()); + NS_ENSURE_SUCCESS (rv, rv); + + char *secondary = g_strdup_printf + (_("The page ā%sā in this tab was not fully loaded yet when " + "the web browser crashed; it could have caused the crash."), + url.get()); + + nsCOMPtr<nsIInputStreamChannel> ischannel; + rv = WritePage (aRecoverURI, uri, rawurl, title.get(), + GTK_STOCK_DIALOG_INFO, title.get() /* as primary */, + secondary, nsnull, nsnull, getter_AddRefs (ischannel)); + NS_ENSURE_SUCCESS (rv, rv); + + rv = ischannel->SetURI (uri); + NS_ENSURE_SUCCESS (rv, rv); + + nsCOMPtr<nsIChannel> channel (do_QueryInterface (ischannel, &rv)); + NS_ENSURE_SUCCESS (rv, rv); + + nsRefPtr<EphyRedirectChannel> redirectChannel (new EphyRedirectChannel (channel)); + if (!redirectChannel) return NS_ERROR_OUT_OF_MEMORY; + + g_free (secondary); + + NS_ADDREF(*_retval = redirectChannel); + + return NS_OK; +} + +nsresult +EphyAboutModule::WritePage(nsIURI *aOriginalURI, + nsIURI *aURI, + const nsACString &aRawURL, + const char *aTitle, + const char *aStockIcon, + const char *aPrimary, + const char *aSecondary, + const char *aTertiary, + const char *aLinkIntro, + nsIInputStreamChannel **_retval) +{ + nsresult rv; nsCOMPtr<nsIStorageStream> storageStream; - rv = NS_NewStorageStream(16384, (PRUint32) -1, getter_AddRefs (storageStream)); + rv = NS_NewStorageStream (16384, (PRUint32) -1, getter_AddRefs (storageStream)); NS_ENSURE_SUCCESS (rv, rv); nsCOMPtr<nsIOutputStream> stream; - rv = storageStream->GetOutputStream(0, getter_AddRefs (stream)); + rv = storageStream->GetOutputStream (0, getter_AddRefs (stream)); NS_ENSURE_SUCCESS (rv, rv); char *language = g_strdup (pango_language_to_string (gtk_get_default_language ())); @@ -405,7 +491,7 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, "\">\n" "<head>\n" "<title>"); - Write (stream, primary); + Write (stream, aTitle); /* no favicon for now, it would pollute the favicon cache */ /* "<link rel=\"icon\" type=\"image/png\" href=\"moz-icon://stock/gtk-dialog-error?size=16\" />\n" */ Write (stream, @@ -418,7 +504,10 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, "left: 12px;\n" "overflow: auto;\n" - "background: -moz-dialog url('moz-icon://stock/gtk-dialog-error?size=dialog') no-repeat 12px 12px;\n" + "background: -moz-dialog url('moz-icon://stock/"); + Write (stream, aStockIcon); + Write (stream, + "?size=dialog') no-repeat 12px 12px;\n" "color: -moz-dialogtext;\n" "font: message-box;\n" "border: 1px solid -moz-dialogtext;\n" @@ -439,29 +528,33 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, "\">\n" "<div id=\"body\">" "<h1>"); - Write (stream, primary); + Write (stream, aTitle); Write (stream, - "</h1>\n" - "<p>"); - Write (stream, secondary); - if (tertiary) + "</h1>\n"); + if (aSecondary) { - Write (stream, " "); - Write (stream, tertiary); + Write (stream, "<p>"); + Write (stream, aSecondary); + if (aTertiary) + { + Write (stream, " "); + Write (stream, aTertiary); + } + Write (stream, "</p>\n"); } - Write (stream, - "</p>\n"); PRBool isHttp = PR_FALSE, isHttps = PR_FALSE; - uri->SchemeIs ("http", &isHttp); - uri->SchemeIs ("https", &isHttps); - if (linkintro && (isHttp || isHttps)) + aURI->SchemeIs ("http", &isHttp); + aURI->SchemeIs ("https", &isHttps); + if (aLinkIntro && (isHttp || isHttps)) { + nsCString raw(aRawURL); + Write (stream, "<p>"); - Write (stream, linkintro); + Write (stream, aLinkIntro); Write (stream, "<ul>\n"); Write (stream, "<li><a href=\"http://www.google.com/search?q=cache:"); - Write (stream, rawurl.get()); + Write (stream, raw.get()); Write (stream, "\">"); /* Translators: The text before the "|" is context to help you decide on * the correct translation. You MUST OMIT it in the translated string. */ @@ -469,7 +562,7 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, Write (stream, "</a></li>\n"); Write (stream, "<li><a href=\"http://web.archive.org/web/*/"); - Write (stream, rawurl.get()); + Write (stream, raw.get()); Write (stream, "\">"); /* Translators: The text before the "|" is context to help you decide on * the correct translation. You MUST OMIT it in the translated string. */ @@ -485,17 +578,16 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, "</html>\n"); g_free (language); - g_free (primary); /* finish the rendering */ nsCOMPtr<nsIInputStream> inputStream; - rv = storageStream->NewInputStream(0, getter_AddRefs (inputStream)); + rv = storageStream->NewInputStream (0, getter_AddRefs (inputStream)); NS_ENSURE_SUCCESS (rv, rv); nsCOMPtr<nsIInputStreamChannel> channel (do_CreateInstance ("@mozilla.org/network/input-stream-channel;1", &rv)); NS_ENSURE_SUCCESS (rv, rv); - rv |= channel->SetURI (aErrorURI); + rv |= channel->SetOriginalURI (aOriginalURI); rv |= channel->SetContentStream (inputStream); rv |= channel->SetContentType (NS_LITERAL_CSTRING ("application/xhtml+xml")); rv |= channel->SetContentCharset (NS_LITERAL_CSTRING ("utf-8")); @@ -506,13 +598,14 @@ EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI, NS_ENSURE_SUCCESS (rv, rv); nsCOMPtr<nsIPrincipal> principal; - rv = securityManager->GetCodebasePrincipal (aErrorURI, getter_AddRefs (principal)); + rv = securityManager->GetCodebasePrincipal (aOriginalURI, getter_AddRefs (principal)); NS_ENSURE_SUCCESS (rv, rv); rv = channel->SetOwner(principal); NS_ENSURE_SUCCESS (rv, rv); - NS_ADDREF(*_retval = channel); + NS_ADDREF (*_retval = channel); + return rv; } diff --git a/embed/mozilla/EphyAboutModule.h b/embed/mozilla/EphyAboutModule.h index 7b9f2f0e9..d829d9b0b 100644 --- a/embed/mozilla/EphyAboutModule.h +++ b/embed/mozilla/EphyAboutModule.h @@ -31,13 +31,19 @@ { 0xa9aea13e, 0x21de, 0x4be8, \ { 0xa0, 0x7e, 0xa0, 0x5f, 0x11, 0x65, 0x8c, 0x55 } } +#ifdef HAVE_GECKO_1_8 #define EPHY_ABOUT_NETERROR_CONTRACTID NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror" #define EPHY_ABOUT_NETERROR_CLASSNAME "Epiphany about:neterror module" +#endif + #define EPHY_ABOUT_EPIPHANY_CONTRACTID NS_ABOUT_MODULE_CONTRACTID_PREFIX "epiphany" #define EPHY_ABOUT_EPIPHANY_CLASSNAME "Epiphany about:epiphany module" +#define EPHY_ABOUT_RECOVER_CONTRACTID NS_ABOUT_MODULE_CONTRACTID_PREFIX "recover" +#define EPHY_ABOUT_RECOVER_CLASSNAME "Epiphany about:recover module" class nsIChannel; class nsIOutputStream; +class nsIInputStreamChannel; class nsIURI; class EphyAboutModule : public nsIAboutModule @@ -51,9 +57,13 @@ class EphyAboutModule : public nsIAboutModule private: nsresult Redirect(const nsACString&, nsIChannel**); - nsresult ParseErrorURL(const char*, nsACString&, nsACString&, nsACString&, nsACString&); + nsresult ParseURL(const char*, nsACString&, nsACString&, nsACString&, nsACString&, nsACString&); +#ifdef HAVE_GECKO_1_8 nsresult GetErrorMessage(nsIURI*, const char*, char**, char**, char**, char**); nsresult CreateErrorPage(nsIURI*, nsIChannel**); +#endif + nsresult CreateRecoverPage(nsIURI*, nsIChannel**); + nsresult WritePage(nsIURI*, nsIURI*, const nsACString&, const char*, const char*, const char*, const char*, const char*, const char*, nsIInputStreamChannel**); nsresult Write(nsIOutputStream*, const char*); }; diff --git a/embed/mozilla/EphyRedirectChannel.cpp b/embed/mozilla/EphyRedirectChannel.cpp new file mode 100644 index 000000000..a147579d9 --- /dev/null +++ b/embed/mozilla/EphyRedirectChannel.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2005 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include "mozilla-config.h" +#include "config.h" + +#include "EphyRedirectChannel.h" + +NS_IMPL_ISUPPORTS2 (EphyWrappedChannel, nsIRequest, nsIChannel) + +NS_IMETHODIMP +EphyRedirectChannel::SetLoadFlags(nsLoadFlags aFlags) +{ + return mChannel->SetLoadFlags (aFlags | LOAD_REPLACE); +} diff --git a/embed/mozilla/EphyRedirectChannel.h b/embed/mozilla/EphyRedirectChannel.h new file mode 100644 index 000000000..e5c378d0b --- /dev/null +++ b/embed/mozilla/EphyRedirectChannel.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef EPHY_REDIRECT_CHANNEL_H +#define EPHY_REDIRECT_CHANNEL_H + +#include <nsCOMPtr.h> +#include <nsIChannel.h> + +class EphyWrappedChannel : public nsIChannel +{ + public: + NS_DECL_ISUPPORTS + NS_FORWARD_NSIREQUEST (mChannel->) + NS_FORWARD_NSICHANNEL (mChannel->) + + EphyWrappedChannel (nsIChannel *aChannel) : mChannel (aChannel) { } + virtual ~EphyWrappedChannel () { } + + protected: + nsCOMPtr<nsIChannel> mChannel; +}; + +class EphyRedirectChannel : public EphyWrappedChannel +{ + public: + EphyRedirectChannel (nsIChannel *aChannel) : EphyWrappedChannel (aChannel) { } + virtual ~EphyRedirectChannel () { } + + NS_IMETHOD SetLoadFlags (nsLoadFlags aFlags); +}; + +#endif /* !EPHY_REDIRECT_CHANNEL_H */ diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am index fd10910fe..86ee39abd 100644 --- a/embed/mozilla/Makefile.am +++ b/embed/mozilla/Makefile.am @@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libephymozillaembed.la libephymozillaembed_la_SOURCES = \ ContentHandler.cpp \ ContentHandler.h \ + EphyAboutModule.cpp \ + EphyAboutModule.h \ EphyContentPolicy.cpp \ EphyContentPolicy.h \ EphyHeaderSniffer.cpp \ @@ -13,6 +15,8 @@ libephymozillaembed_la_SOURCES = \ EphyFind.h \ EphyHistoryListener.cpp \ EphyHistoryListener.h \ + EphyRedirectChannel.cpp \ + EphyRedirectChannel.h \ EphySidebar.cpp \ EphySidebar.h \ EphySingle.cpp \ @@ -64,12 +68,6 @@ libephymozillaembed_la_SOURCES += \ GtkNSSSecurityWarningDialogs.h endif -if HAVE_GECKO_1_8 -libephymozillaembed_la_SOURCES += \ - EphyAboutModule.cpp \ - EphyAboutModule.h -endif - mozilla_include_subdirs = \ caps \ chardet \ diff --git a/embed/mozilla/MozRegisterComponents.cpp b/embed/mozilla/MozRegisterComponents.cpp index bc7ee4709..2e392f408 100644 --- a/embed/mozilla/MozRegisterComponents.cpp +++ b/embed/mozilla/MozRegisterComponents.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2001,2002,2003 Philip Langdale * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2004, 2005 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +30,7 @@ #include "MozDownload.h" #include "EphyContentPolicy.h" #include "EphySidebar.h" +#include "EphyAboutModule.h" #ifdef ENABLE_FILEPICKER #include "FilePicker.h" @@ -42,10 +44,6 @@ #include <nsISecureBrowserUI.h> #endif -#ifdef HAVE_GECKO_1_8 -#include "EphyAboutModule.h" -#endif - #include <nsMemory.h> #include <nsDocShellCID.h> #include <nsIGenericFactory.h> @@ -63,6 +61,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(MozGlobalHistory) NS_GENERIC_FACTORY_CONSTRUCTOR(GPrintingPromptService) NS_GENERIC_FACTORY_CONSTRUCTOR(EphyContentPolicy) NS_GENERIC_FACTORY_CONSTRUCTOR(EphySidebar) +NS_GENERIC_FACTORY_CONSTRUCTOR(EphyAboutModule) #ifdef ENABLE_FILEPICKER NS_GENERIC_FACTORY_CONSTRUCTOR(GFilePicker) @@ -75,9 +74,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(GtkNSSKeyPairDialogs) NS_GENERIC_FACTORY_CONSTRUCTOR(GtkNSSSecurityWarningDialogs) #endif -#ifdef HAVE_GECKO_1_8 -NS_GENERIC_FACTORY_CONSTRUCTOR(EphyAboutModule) -#endif /* class information */ NS_DECL_CLASSINFO(EphySidebar) @@ -205,19 +201,25 @@ static const nsModuleComponentInfo sAppComps[] = { &NS_CLASSINFO_NAME(EphySidebar), nsIClassInfo::DOM_OBJECT }, + { + EPHY_ABOUT_EPIPHANY_CLASSNAME, + EPHY_ABOUT_MODULE_CID, + EPHY_ABOUT_EPIPHANY_CONTRACTID, + EphyAboutModuleConstructor + }, + { + EPHY_ABOUT_RECOVER_CLASSNAME, + EPHY_ABOUT_MODULE_CID, + EPHY_ABOUT_RECOVER_CONTRACTID, + EphyAboutModuleConstructor + }, #ifdef HAVE_GECKO_1_8 -{ - EPHY_ABOUT_EPIPHANY_CLASSNAME, - EPHY_ABOUT_MODULE_CID, - EPHY_ABOUT_EPIPHANY_CONTRACTID, - EphyAboutModuleConstructor -}, -{ - EPHY_ABOUT_NETERROR_CLASSNAME, - EPHY_ABOUT_MODULE_CID, - EPHY_ABOUT_NETERROR_CONTRACTID, - EphyAboutModuleConstructor -}, + { + EPHY_ABOUT_NETERROR_CLASSNAME, + EPHY_ABOUT_MODULE_CID, + EPHY_ABOUT_NETERROR_CONTRACTID, + EphyAboutModuleConstructor + }, #endif }; diff --git a/src/ephy-session.c b/src/ephy-session.c index 4591b4962..58c316b0c 100644 --- a/src/ephy-session.c +++ b/src/ephy-session.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 Jorn Baayen * Copyright (C) 2003, 2004 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2003, 2004, 2005 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +47,7 @@ #include <gtk/gtkdialog.h> #include <gtk/gtkmessagedialog.h> #include <libgnomevfs/gnome-vfs-ops.h> +#include <libgnomevfs/gnome-vfs-utils.h> #include <libxml/tree.h> #include <libxml/xmlwriter.h> @@ -165,7 +166,7 @@ tab_added_cb (GtkWidget *notebook, EphyTab *tab, EphySession *session) { - g_signal_connect (ephy_tab_get_embed (tab), "net_stop", + g_signal_connect (ephy_tab_get_embed (tab), "net-stop", G_CALLBACK (net_stop_cb), session); } @@ -222,11 +223,11 @@ impl_attach_window (EphyExtension *extension, G_CALLBACK (window_focus_in_event_cb), session); notebook = ephy_window_get_notebook (window); - g_signal_connect (notebook, "tab_added", + g_signal_connect (notebook, "tab-added", G_CALLBACK (tab_added_cb), session); - g_signal_connect (notebook, "tab_removed", + g_signal_connect (notebook, "tab-removed", G_CALLBACK (tab_removed_cb), session); - g_signal_connect (notebook, "tabs_reordered", + g_signal_connect (notebook, "tabs-reordered", G_CALLBACK (tabs_reordered_cb), session); /* Set unique identifier as role, so that on restore, the WM can @@ -431,9 +432,10 @@ ephy_session_autoresume (EphySession *session, if (priv->resume_dialog) { - ephy_gui_window_update_user_time (session->priv->resume_dialog, + ephy_gui_window_update_user_time (priv->resume_dialog, user_time); - ephy_gui_window_present (GTK_WINDOW (priv->resume_dialog), user_time); + ephy_gui_window_present (GTK_WINDOW (priv->resume_dialog), + user_time); return TRUE; } @@ -442,10 +444,10 @@ ephy_session_autoresume (EphySession *session, if (g_file_test (saved_session, G_FILE_TEST_EXISTS) && offer_to_resume (session, user_time)) { - session->priv->dont_save = TRUE; + priv->dont_save = TRUE; retval = ephy_session_load (session, saved_session, 0 /* since we've shown the dialogue */); - session->priv->dont_save = FALSE; + priv->dont_save = FALSE; ephy_session_save (session, SESSION_CRASHED); } @@ -517,16 +519,30 @@ static int write_tab (xmlTextWriterPtr writer, EphyTab *tab) { - const char *address; + const char *address, *title; int ret; ret = xmlTextWriterStartElement (writer, (xmlChar *) "embed"); if (ret < 0) return ret; address = ephy_tab_get_address (tab); - ret = xmlTextWriterWriteAttribute (writer, (xmlChar *) "url", (xmlChar *) address); + ret = xmlTextWriterWriteAttribute (writer, (xmlChar *) "url", + (const xmlChar *) address); if (ret < 0) return ret; + title = ephy_tab_get_title (tab); + ret = xmlTextWriterWriteAttribute (writer, (xmlChar *) "title", + (const xmlChar *) title); + if (ret < 0) return ret; + + if (ephy_tab_get_load_status (tab)) + { + ret = xmlTextWriterWriteAttribute (writer, + (const xmlChar *) "loading", + (const xmlChar *) "true"); + if (ret < 0) return ret; + } + ret = xmlTextWriterEndElement (writer); /* embed */ return ret; } @@ -636,19 +652,20 @@ gboolean ephy_session_save (EphySession *session, const char *filename) { + EphySessionPrivate *priv = session->priv; xmlTextWriterPtr writer; GList *w; char *save_to, *tmp_file; int ret; - if (session->priv->dont_save) + if (priv->dont_save) { return TRUE; } LOG ("ephy_sesion_save %s", filename); - if (session->priv->windows == NULL && session->priv->tool_windows == NULL) + if (priv->windows == NULL && priv->tool_windows == NULL) { session_delete (session, filename); return TRUE; @@ -720,24 +737,63 @@ out: } static void -parse_embed (xmlNodePtr child, EphyWindow *window) +parse_embed (xmlNodePtr child, + EphyWindow *window, + EphySession *session) { + EphySessionPrivate *priv = session->priv; + while (child != NULL) { if (strcmp ((char *) child->name, "embed") == 0) { - xmlChar *url; + xmlChar *url, *attr; + char *recover_url, *freeme = NULL; + gboolean was_loading; g_return_if_fail (window != NULL); + /* Check if that tab wasn't fully loaded yet when the session crashed */ + attr = xmlGetProp (child, (const xmlChar *) "loading"); + was_loading = attr != NULL && + xmlStrEqual (attr, (const xmlChar *) "true"); + xmlFree (attr); + url = xmlGetProp (child, (const xmlChar *) "url"); + if (url == NULL) continue; - ephy_shell_new_tab (ephy_shell, window, NULL, (char *) url, + if (!was_loading || + strcmp ((const char *) url, "about:blank") == 0) + { + recover_url = (char *) url; + } + else + { + xmlChar *title; + char *escaped_url, *escaped_title; + + title = xmlGetProp (child, (const xmlChar *) "title"); + escaped_title = gnome_vfs_escape_string (title ? (const char*) title : _("Untitled")); + + escaped_url = gnome_vfs_escape_string ((const char *) url); + freeme = recover_url = + g_strconcat ("about:recover?u=", + escaped_url, + "&c=UTF-8&t=", + escaped_title, NULL); + + xmlFree (title); + g_free (escaped_url); + g_free (escaped_title); + } + + ephy_shell_new_tab (ephy_shell, window, NULL, recover_url, EPHY_NEW_TAB_IN_EXISTING_WINDOW | EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_APPEND_LAST); xmlFree (url); + g_free (freeme); } child = child->next; @@ -801,6 +857,7 @@ restore_geometry (GtkWindow *window, } } + /* * ephy_session_load: * @session: a #EphySession @@ -818,6 +875,7 @@ ephy_session_load (EphySession *session, { xmlDocPtr doc; xmlNodePtr child; + EphyWindow *window; GtkWidget *widget = NULL; char *save_to; @@ -842,12 +900,18 @@ ephy_session_load (EphySession *session, { if (xmlStrEqual (child->name, (const xmlChar *) "window")) { - widget = GTK_WIDGET (ephy_window_new ()); + window = ephy_window_new (); + widget = GTK_WIDGET (window); restore_geometry (GTK_WINDOW (widget), child); - parse_embed (child->children, EPHY_WINDOW (widget)); ephy_gui_window_update_user_time (widget, user_time); + /* Now add the tabs */ + parse_embed (child->children, window, session); + + /* Set focus to something sane */ + gtk_widget_grab_focus (ephy_window_get_notebook (window)); + gtk_widget_show (widget); } else if (xmlStrEqual (child->name, (const xmlChar *) "toolwindow")) |