Updating branch refs/heads/master
         to 3de3a71f4fb26c3c77802d5dd25f241cc216245f (commit)
       from 7c49465bf169c21918658438d9456bdeef0fe259 (commit)

commit 3de3a71f4fb26c3c77802d5dd25f241cc216245f
Author: Christian Dywan <christ...@twotoasts.de>
Date:   Sat Mar 23 12:29:55 2013 +0100

    Merged cookie permissions as of 2013-03-08
    
    Fixes: https://bugs.launchpad.net/midori/+bug/1139496
    Fixes: https://bugs.launchpad.net/midori/+bug/1145197

 .../cookie-permission-manager-preferences-window.c |   69 +++-
 .../cookie-permissions/cookie-permission-manager.c |  399 +++++++++++++-------
 2 files changed, 321 insertions(+), 147 deletions(-)

diff --git 
a/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c 
b/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
index c7ccc5b..33fb2d6 100644
--- 
a/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
+++ 
b/extensions/cookie-permissions/cookie-permission-manager-preferences-window.c
@@ -189,7 +189,7 @@ static void 
_cookie_permission_manager_preferences_on_add_domain_entry_changed(C
                checkAsciiDomain++;
        }
 
-       /* If we have not reached the trimmed end of string something must have 
gone wrong
+       /* If we have not reached the trimmed end of string something must have 
gone wrong 
         * and domain entered is invalid. If domain name entered excluding dots 
is longer
         * than 255 character it is also invalid.
         */
@@ -282,21 +282,19 @@ static void 
_cookie_permission_manager_preferences_window_manager_database_chang
 {
        CookiePermissionManagerPreferencesWindowPrivate *priv=self->priv;
        CookiePermissionManager                                                 
*manager=COOKIE_PERMISSION_MANAGER(inUserData);
-       sqlite3                                                                 
                *database;
+       const gchar                                                             
                *databaseFilename;
 
        /* Close connection to any open database */
        if(priv->database) sqlite3_close(priv->database);
        priv->database=NULL;
 
        /* Get pointer to new database and open database */
-       g_object_get(manager, "database", &database, NULL);
-       if(database)
+       g_object_get(manager, "database-filename", &databaseFilename, NULL);
+       if(databaseFilename)
        {
-               const gchar                                                     
                *databaseFile;
                gint                                                            
                success;
 
-               databaseFile=sqlite3_db_filename(database, NULL);
-               success=sqlite3_open(databaseFile, &priv->database);
+               success=sqlite3_open(databaseFilename, &priv->database);
                if(success!=SQLITE_OK)
                {
                        g_warning(_("Could not open database of extenstion: 
%s"), sqlite3_errmsg(priv->database));
@@ -465,6 +463,27 @@ void 
_cookie_permission_manager_preferences_on_delete_all(CookiePermissionManage
        _cookie_permission_manager_preferences_window_fill(self);
 }
 
+/* Sorting callbacks */
+static gint 
_cookie_permission_manager_preferences_sort_string_callback(GtkTreeModel 
*inModel,
+                                                                               
                                                                GtkTreeIter 
*inLeft,
+                                                                               
                                                                GtkTreeIter 
*inRight,
+                                                                               
                                                                gpointer 
inUserData)
+{
+       gchar           *left, *right;
+       gint            column=GPOINTER_TO_INT(inUserData);
+       gint            result;
+
+       gtk_tree_model_get(inModel, inLeft, column, &left, -1);
+       gtk_tree_model_get(inModel, inRight, column, &right, -1);
+
+       result=g_strcmp0(left, right);
+
+       g_free(left);
+       g_free(right);
+
+       return(result);
+}
+
 /* IMPLEMENTATION: GObject */
 
 /* Finalize this object */
@@ -527,16 +546,18 @@ static void 
cookie_permission_manager_preferences_window_set_property(GObject *i
                        {
                                priv->manager=g_object_ref(manager);
 
-                               
priv->signalManagerChangedDatabaseID=g_signal_connect_swapped(priv->manager,
-                                                                               
                                                                                
        "notify::database",
-                                                                               
                                                                                
        
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_database_changed),
-                                                                               
                                                                                
        self);
-                               
priv->signalManagerAskForUnknownPolicyID=g_signal_connect_swapped(priv->manager,
-                                                                               
                                                                                
        "notify::ask-for-unknown-policy",
-                                                                               
                                                                                
        
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed),
-                                                                               
                                                                                
        self);
-
+                               priv->signalManagerChangedDatabaseID=
+                                       g_signal_connect_swapped(priv->manager,
+                                                                               
                "notify::database-filename",
+                                                                               
                
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_database_changed),
+                                                                               
                self);
                                
_cookie_permission_manager_preferences_window_manager_database_changed(self, 
NULL, priv->manager);
+
+                               priv->signalManagerAskForUnknownPolicyID=
+                                       g_signal_connect_swapped(priv->manager,
+                                                                               
                "notify::ask-for-unknown-policy",
+                                                                               
                
G_CALLBACK(_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed),
+                                                                               
                self);
                                
_cookie_permission_manager_preferences_window_manager_ask_for_unknown_policy_changed(self,
 NULL, priv->manager);
                        }
                        break;
@@ -598,6 +619,7 @@ static void 
cookie_permission_manager_preferences_window_class_init(CookiePermis
 static void 
cookie_permission_manager_preferences_window_init(CookiePermissionManagerPreferencesWindow
 *self)
 {
        CookiePermissionManagerPreferencesWindowPrivate         *priv;
+       GtkTreeSortable                                                         
                *sortableList;
        GtkCellRenderer                                                         
                *renderer;
        GtkTreeViewColumn                                                       
                *column;
        GtkWidget                                                               
                        *widget;
@@ -654,6 +676,19 @@ static void 
cookie_permission_manager_preferences_window_init(CookiePermissionMa
                                                                                
G_TYPE_STRING,  /* DOMAIN_COLUMN */
                                                                                
G_TYPE_STRING   /* POLICY_COLUMN */);
 
+       sortableList=GTK_TREE_SORTABLE(priv->listStore);
+       gtk_tree_sortable_set_sort_func(sortableList,
+                                                                               
DOMAIN_COLUMN,
+                                                                               
(GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
+                                                                               
GINT_TO_POINTER(DOMAIN_COLUMN),
+                                                                               
NULL);
+       gtk_tree_sortable_set_sort_func(sortableList,
+                                                                               
POLICY_COLUMN,
+                                                                               
(GtkTreeIterCompareFunc)_cookie_permission_manager_preferences_sort_string_callback,
+                                                                               
GINT_TO_POINTER(POLICY_COLUMN),
+                                                                               
NULL);
+       gtk_tree_sortable_set_sort_column_id(sortableList, DOMAIN_COLUMN, 
GTK_SORT_ASCENDING);
+
        /* Set up domain addition widgets */
 #ifdef HAVE_GTK3
        hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
@@ -706,6 +741,7 @@ static void 
cookie_permission_manager_preferences_window_init(CookiePermissionMa
                                                                                
                        renderer,
                                                                                
                        "text", DOMAIN_COLUMN,
                                                                                
                        NULL);
+       gtk_tree_view_column_set_sort_column_id(column, DOMAIN_COLUMN);
        gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
 
        renderer=gtk_cell_renderer_text_new();
@@ -713,6 +749,7 @@ static void 
cookie_permission_manager_preferences_window_init(CookiePermissionMa
                                                                                
                        renderer,
                                                                                
                        "text", POLICY_COLUMN,
                                                                                
                        NULL);
+       gtk_tree_view_column_set_sort_column_id(column, POLICY_COLUMN);
        gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
 
        scrolled=gtk_scrolled_window_new(NULL, NULL);
diff --git a/extensions/cookie-permissions/cookie-permission-manager.c 
b/extensions/cookie-permissions/cookie-permission-manager.c
index 84f99af..2fca15c 100644
--- a/extensions/cookie-permissions/cookie-permission-manager.c
+++ b/extensions/cookie-permissions/cookie-permission-manager.c
@@ -13,6 +13,9 @@
 
 #include <errno.h>
 
+/* Remove next line if we found a way to show details in infobar */
+#define NO_INFOBAR_DETAILS
+
 /* Define this class in GObject system */
 G_DEFINE_TYPE(CookiePermissionManager,
                                cookie_permission_manager,
@@ -27,9 +30,9 @@ enum
        PROP_APPLICATION,
 
        PROP_DATABASE,
+       PROP_DATABASE_FILENAME,
        PROP_ASK_FOR_UNKNOWN_POLICY,
 
-
        PROP_LAST
 };
 
@@ -45,12 +48,9 @@ struct _CookiePermissionManagerPrivate
        MidoriExtension                                 *extension;
        MidoriApp                                               *application;
        sqlite3                                                 *database;
+       gchar                                                   
*databaseFilename;
        gboolean                                                
askForUnknownPolicy;
 
-       /* Session related */
-       void(*oldRequestQueued)(SoupSessionFeature *inFeature, SoupSession 
*inSession, SoupMessage *inMessage);
-       void(*oldRequestUnqueued)(SoupSessionFeature *inFeature, SoupSession 
*inSession, SoupMessage *inMessage);
-
        /* Cookie jar related */
        SoupSession                                             *session;
        SoupCookieJar                                   *cookieJar;
@@ -68,6 +68,14 @@ enum
        N_COLUMN
 };
 
+struct _CookiePermissionManagerModalInfobar
+{
+       GMainLoop                                               *mainLoop;
+       gint                                                    response;
+};
+
+typedef struct _CookiePermissionManagerModalInfobar            
CookiePermissionManagerModalInfobar;
+
 /* IMPLEMENTATION: Private variables and methods */
 
 /* Show common error dialog */
@@ -105,7 +113,6 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
 {
        CookiePermissionManagerPrivate  *priv=self->priv;
        const gchar                                             *configDir;
-       gchar                                                   *databaseFile;
        gchar                                                   *error=NULL;
        gint                                                    success;
        sqlite3_stmt                                    *statement=NULL;
@@ -113,9 +120,14 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
        /* Close any open database */
        if(priv->database)
        {
+               g_free(priv->databaseFilename);
+               priv->databaseFilename=NULL;
+
                sqlite3_close(priv->database);
                priv->database=NULL;
+
                g_object_notify_by_pspec(G_OBJECT(self), 
CookiePermissionManagerProperties[PROP_DATABASE]);
+               g_object_notify_by_pspec(G_OBJECT(self), 
CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
        }
 
        /* Build path to database file */
@@ -127,7 +139,7 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
                _cookie_permission_manager_error(self, _("Could not get path to 
configuration of extension."));
                return;
        }
-
+       
        if(katze_mkdir_with_parents(configDir, 0700))
        {
                g_warning(_("Could not create configuration folder for 
extension: %s"), g_strerror(errno));
@@ -137,13 +149,15 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
        }
 
        /* Open database */
-       databaseFile=g_build_filename(configDir, COOKIE_PERMISSION_DATABASE, 
NULL);
-       success=sqlite3_open(databaseFile, &priv->database);
-       g_free(databaseFile);
+       priv->databaseFilename=g_build_filename(configDir, 
COOKIE_PERMISSION_DATABASE, NULL);
+       success=sqlite3_open(priv->databaseFilename, &priv->database);
        if(success!=SQLITE_OK)
        {
                g_warning(_("Could not open database of extenstion: %s"), 
sqlite3_errmsg(priv->database));
 
+               g_free(priv->databaseFilename);
+               priv->databaseFilename=NULL;
+
                if(priv->database) sqlite3_close(priv->database);
                priv->database=NULL;
 
@@ -188,6 +202,9 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
                        sqlite3_free(error);
                }
 
+               g_free(priv->databaseFilename);
+               priv->databaseFilename=NULL;
+
                sqlite3_close(priv->database);
                priv->database=NULL;
                return;
@@ -237,6 +254,7 @@ static void 
_cookie_permission_manager_open_database(CookiePermissionManager *se
        sqlite3_finalize(statement);
 
        g_object_notify_by_pspec(G_OBJECT(self), 
CookiePermissionManagerProperties[PROP_DATABASE]);
+       g_object_notify_by_pspec(G_OBJECT(self), 
CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
 }
 
 /* Get policy for cookies from domain */
@@ -361,6 +379,8 @@ static GSList* 
_cookie_permission_manager_get_number_domains_and_cookies(CookieP
        return(sortedList);
 }
 
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
 static void 
_cookie_permission_manager_when_ask_expander_changed(CookiePermissionManager 
*self,
                                                                                
                                                        GParamSpec *inSpec,
                                                                                
                                                        gpointer inUserData)
@@ -369,26 +389,84 @@ static void 
_cookie_permission_manager_when_ask_expander_changed(CookiePermissio
 
        midori_extension_set_boolean(self->priv->extension, 
"show-details-when-ask", gtk_expander_get_expanded(expander));
 }
+#endif
+
+static gboolean 
_cookie_permission_manager_on_infobar_webview_navigate(WebKitWebView *inView,
+                                                                               
                                                                WebKitWebFrame 
*inFrame,
+                                                                               
                                                                
WebKitNetworkRequest *inRequest,
+                                                                               
                                                                
WebKitWebNavigationAction *inAction,
+                                                                               
                                                                
WebKitWebPolicyDecision *inDecision,
+                                                                               
                                                                gpointer 
inUserData)
+{
+       /* Destroy info bar - that calls another callback which quits main loop 
*/
+       GtkWidget               *infobar=GTK_WIDGET(inUserData);
+
+       gtk_widget_destroy(infobar);
+
+       /* Let the default handler decide */
+       return(FALSE);
+}
+
+static void _cookie_permission_manager_on_infobar_destroy(GtkWidget* inInfobar,
+                                                                               
                                        gpointer inUserData)
+{
+       CookiePermissionManagerModalInfobar             
*modalInfo=(CookiePermissionManagerModalInfobar*)inUserData;
+
+       /* Quit main loop */
+       if(g_main_loop_is_running(modalInfo->mainLoop)) 
g_main_loop_quit(modalInfo->mainLoop);
+}
+
+static void _cookie_permission_manager_on_infobar_policy_decision(GtkWidget* 
inInfobar,
+                                                                               
                                                        gint inResponse,
+                                                                               
                                                        gpointer inUserData)
+{
+       CookiePermissionManagerModalInfobar             *modalInfo;
+
+       /* Get modal info struct */
+       
modalInfo=(CookiePermissionManagerModalInfobar*)g_object_get_data(G_OBJECT(inInfobar),
 "cookie-permission-manager-infobar-data");
+
+       /* Store response */
+       modalInfo->response=inResponse;
+
+       /* Quit main loop */
+       if(g_main_loop_is_running(modalInfo->mainLoop)) 
g_main_loop_quit(modalInfo->mainLoop);
+}
 
 static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager 
*self,
+                                                                               
                                MidoriView *inView,
+                                                                               
                                SoupMessage *inMessage,
                                                                                
                                GSList *inUnknownCookies)
 {
-       CookiePermissionManagerPrivate  *priv=self->priv;
-       GtkWidget                                               *dialog;
-       GtkWidget                                               *widget;
-       GtkWidget                                               *contentArea;
-       GtkWidget                                               *vbox, *hbox;
-       GtkWidget                                               *expander;
-       GtkListStore                                    *listStore;
-       GtkTreeIter                                             listIter;
-       GtkWidget                                               *scrolled;
-       GtkWidget                                               *list;
-       GtkCellRenderer                                 *renderer;
-       GtkTreeViewColumn                               *column;
-       gchar                                                   *text;
-       gint                                                    numberDomains, 
numberCookies;
-       gint                                                    response;
-       GSList                                                  *sortedCookies, 
*cookies;
+       /* Ask user for policy of unkndown domains in an undistracting way.
+        * The idea is to put the message not in a modal window but into 
midori's info bar.
+        * Then we'll set up our own GMainLoop to simulate a modal info bar. We 
need to
+        * connect to all possible signals of info bar, web view and so on to 
handle user's
+        * decision and to get out of our own GMainLoop. After that webkit 
resumes processing
+        * data.
+        */
+       CookiePermissionManagerPrivate                  *priv=self->priv;
+       GtkWidget                                                               
*infobar;
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
+       GtkWidget                                                               
*widget;
+       GtkWidget                                                               
*contentArea;
+       GtkWidget                                                               
*vbox, *hbox;
+       GtkWidget                                                               
*expander;
+       GtkListStore                                                    
*listStore;
+       GtkTreeIter                                                             
listIter;
+       GtkWidget                                                               
*scrolled;
+       GtkWidget                                                               
*list;
+       GtkCellRenderer                                                 
*renderer;
+       GtkTreeViewColumn                                               *column;
+#endif
+       gchar                                                                   
*text;
+       gint                                                                    
numberDomains, numberCookies;
+       GSList                                                                  
*sortedCookies, *cookies;
+       WebKitWebView                                                   
*webkitView;
+       CookiePermissionManagerModalInfobar             modalInfo;
+
+       /* Get webkit view of midori view */
+       webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView));
 
        /* Create a copy of cookies and sort them */
        
sortedCookies=_cookie_permission_manager_get_number_domains_and_cookies(self,
@@ -396,6 +474,8 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
                                                                                
                                                                        
&numberDomains,
                                                                                
                                                                        
&numberCookies);
 
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
        /* Create list model and fill in data */
        listStore=gtk_list_store_new(N_COLUMN,
                                                                        
G_TYPE_STRING,  /* DOMAIN_COLUMN */
@@ -409,7 +489,8 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
                SoupCookie                              
*cookie=(SoupCookie*)cookies->data;
                SoupDate                                
*cookieDate=soup_cookie_get_expires(cookie);
 
-               text=soup_date_to_string(cookieDate, SOUP_DATE_HTTP);
+               if(cookieDate) text=soup_date_to_string(cookieDate, 
SOUP_DATE_HTTP);
+                       else text=g_strdup(_("Till session end"));
 
                gtk_list_store_append(listStore, &listIter);
                gtk_list_store_set(listStore,
@@ -423,40 +504,15 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
 
                g_free(text);
        }
-
-       /* Create dialog with text, icon, title and so on */
-       dialog=gtk_dialog_new();
-
-       gtk_window_set_title(GTK_WINDOW(dialog), _("Confirm storing cookie"));
-       gtk_window_set_icon_name(GTK_WINDOW (dialog), "midori");
-
-       /* Get content area and layout widgets */
-       contentArea=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
-
-#ifdef HAVE_GTK3
-       vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-       gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
-#else
-       vbox=gtk_vbox_new(FALSE, 0);
 #endif
 
        /* Create description text */
-#ifdef HAVE_GTK3
-       hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-       gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
-#else
-       hbox=gtk_hbox_new(FALSE, 0);
-#endif
-
-       widget=gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, 
GTK_ICON_SIZE_DIALOG);
-       gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 4);
-
        if(numberDomains==1)
        {
                const gchar                                     
*cookieDomain=soup_cookie_get_domain((SoupCookie*)sortedCookies->data);
 
                if(*cookieDomain=='.') cookieDomain++;
-
+               
                if(numberCookies>1)
                        text=g_strdup_printf(_("The website %s wants to store 
%d cookies."), cookieDomain, numberCookies);
                else
@@ -467,17 +523,33 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
                        text=g_strdup_printf(_("Multiple websites want to store 
%d cookies in total."), numberCookies);
                }
 
-       widget=gtk_label_new(NULL);
-       gtk_label_set_markup(GTK_LABEL(widget), text);
-       gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
-       gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 4);
+       /* Create info bar message and buttons */
+       infobar=midori_view_add_info_bar(inView,
+                                                                               
GTK_MESSAGE_QUESTION,
+                                                                               
text,
+                                                                               
G_CALLBACK(_cookie_permission_manager_on_infobar_policy_decision),
+                                                                               
NULL,
+                                                                               
_("_Accept"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT,
+                                                                               
_("Accept for this _session"), 
COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION,
+                                                                               
_("De_ny"), COOKIE_PERMISSION_MANAGER_POLICY_BLOCK,
+                                                                               
_("Deny _this time"), COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED,
+                                                                               
NULL);
        g_free(text);
 
-       gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
+       /* midori_view_add_info_bar() in version 0.4.8 expects a GObject as 
user data
+        * but I don't want to create an GObject just for a simple struct. So 
set object
+        * data by our own
+        */
+       g_object_set_data(G_OBJECT(infobar), 
"cookie-permission-manager-infobar-data", &modalInfo);
 
-       /* Create expander for details */
-       expander=gtk_expander_new_with_mnemonic(_("_Details"));
-       gtk_box_pack_start(GTK_BOX(vbox), expander, TRUE, TRUE, 5);
+/* FIXME: Find a way to add "details" widget */
+#ifndef NO_INFOBAR_DETAILS
+       /* Get content area of infobar */
+#if HAVE_GTK_INFO_BAR
+       contentArea=gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar));
+#else
+       contentArea=infobar;
+#endif
 
        /* Create list and set up columns of list */
        list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(listStore));
@@ -540,25 +612,36 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
        gtk_expander_set_expanded(GTK_EXPANDER(expander),
                                                                
midori_extension_get_boolean(priv->extension, "show-details-when-ask"));
        g_signal_connect_swapped(expander, "notify::expanded", 
G_CALLBACK(_cookie_permission_manager_when_ask_expander_changed), self);
+#endif
 
-       /* Create buttons for dialog */
-       widget=gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Accept"), 
COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT);
-       gtk_button_set_image(GTK_BUTTON(widget), 
gtk_image_new_from_stock(GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON));
+       /* Show all widgets of info bar */
+       gtk_widget_show_all(infobar);
 
-       gtk_dialog_add_button(GTK_DIALOG(dialog), _("Accept for this 
_session"), COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION);
+       /* Connect signals to quit main loop */
+       g_signal_connect(webkitView, "navigation-policy-decision-requested", 
G_CALLBACK(_cookie_permission_manager_on_infobar_webview_navigate), infobar);
+       g_signal_connect(infobar, "destroy", 
G_CALLBACK(_cookie_permission_manager_on_infobar_destroy), &modalInfo);
 
-       widget=gtk_dialog_add_button(GTK_DIALOG(dialog), _("De_ny"), 
COOKIE_PERMISSION_MANAGER_POLICY_BLOCK);
-       gtk_button_set_image(GTK_BUTTON(widget), 
gtk_image_new_from_stock(GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON));
+       /* Let info bar be modal and set response to default */
+       modalInfo.response=COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED;
+       modalInfo.mainLoop=g_main_loop_new(NULL, FALSE);
 
-       /* Show confirmation dialog and wait for response of user */
-       response=gtk_dialog_run(GTK_DIALOG(dialog));
+       GDK_THREADS_LEAVE();
+       g_main_loop_run(modalInfo.mainLoop);
+       GDK_THREADS_ENTER();
+
+       g_main_loop_unref(modalInfo.mainLoop);
+
+       modalInfo.mainLoop=NULL;
+
+       /* Disconnect signal handler to webkit's web view  */
+       g_signal_handlers_disconnect_by_func(webkitView, 
G_CALLBACK(_cookie_permission_manager_on_infobar_webview_navigate), infobar);
 
        /* Store user's decision in database if it is not a temporary block.
         * We use the already sorted list of cookies to prevent multiple
         * updates of database for the same domain. This sorted list is a copy
         * to avoid a reorder of cookies
         */
-       if(response>=0)
+       if(modalInfo.response!=COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED)
        {
                const gchar                                     
*lastDomain=NULL;
 
@@ -579,7 +662,7 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
 
                                sql=sqlite3_mprintf("INSERT OR REPLACE INTO 
policies (domain, value) VALUES ('%q', %d);",
                                                                                
cookieDomain,
-                                                                               
response);
+                                                                               
modalInfo.response);
                                success=sqlite3_exec(priv->database, sql, NULL, 
NULL, &error);
                                if(success!=SQLITE_OK) g_warning(_("SQL fails: 
%s"), error);
                                if(error) sqlite3_free(error);
@@ -592,10 +675,10 @@ static gint 
_cookie_permission_manager_ask_for_policy(CookiePermissionManager *s
 
        /* Free up allocated resources */
        g_slist_free(sortedCookies);
-       gtk_widget_destroy(dialog);
 
-       /* Return user's selection */
-       return(response>=0 ? response : COOKIE_PERMISSION_MANAGER_POLICY_BLOCK);
+       /* Return response */
+       
return(modalInfo.response==COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED ?
+                       COOKIE_PERMISSION_MANAGER_POLICY_BLOCK : 
modalInfo.response);
 }
 
 /* A cookie was changed outside a request (e.g. Javascript) */
@@ -604,9 +687,6 @@ static void 
_cookie_permission_manager_on_cookie_changed(CookiePermissionManager
                                                                                
                                        SoupCookie *inNewCookie,
                                                                                
                                        SoupCookieJar *inCookieJar)
 {
-       GSList                  *newCookies;
-       gint                    newCookiePolicy;
-
        /* Do not check changed cookies because they must have been allowed 
before.
         * Also do not check removed cookies because they are removed ;)
         */
@@ -615,33 +695,30 @@ static void 
_cookie_permission_manager_on_cookie_changed(CookiePermissionManager
        /* New cookie is a new cookie so check */
        switch(_cookie_permission_manager_get_policy(self, inNewCookie))
        {
-               case COOKIE_PERMISSION_MANAGER_POLICY_BLOCK:
-                       soup_cookie_jar_delete_cookie(inCookieJar, inNewCookie);
+               case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT:
+               case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION:
                        break;
 
                case COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED:
-                       newCookies=g_slist_prepend(NULL, inNewCookie);
-                       
newCookiePolicy=_cookie_permission_manager_ask_for_policy(self, newCookies);
-                       
if(newCookiePolicy==COOKIE_PERMISSION_MANAGER_POLICY_BLOCK)
-                       {
-                               /* Free cookie because it should be blocked */
-                               soup_cookie_jar_delete_cookie(inCookieJar, 
inNewCookie);
-                       }
-                               else
-                               {
-                                       /* Cookie was accept so do nothing (it 
is already added) */
-                               }
-                       g_slist_free(newCookies);
-                       break;
+                       /* Fallthrough!
+                        * The problem here is that we don't know the view to 
ask user
+                        * for policy to follow for this cookie domain. 
Therefore we
+                        * delete the cookie from jar and assume that we will 
be asked
+                        * again in 
_cookie_permission_manager_on_response_received().
+                        */
 
-               case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT:
-               case COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION:
+               default:
+                       soup_cookie_jar_delete_cookie(inCookieJar, inNewCookie);
                        break;
        }
 }
 
 /* We received the HTTP headers of the request and it contains cookie-managing 
headers */
-static void _cookie_permission_manager_process_set_cookie_header(SoupMessage 
*inMessage, gpointer inUserData)
+static void _cookie_permission_manager_on_response_received(WebKitWebView 
*inView,
+                                                                               
                                        WebKitWebFrame *inFrame,
+                                                                               
                                        WebKitWebResource *inResource,
+                                                                               
                                        WebKitNetworkResponse *inResponse,
+                                                                               
                                        gpointer inUserData)
 {
        g_return_if_fail(IS_COOKIE_PERMISSION_MANAGER(inUserData));
 
@@ -652,18 +729,23 @@ static void 
_cookie_permission_manager_process_set_cookie_header(SoupMessage *in
        SoupURI                                                 *firstParty;
        SoupCookieJarAcceptPolicy               cookiePolicy;
        gint                                                    
unknownCookiesPolicy;
+       SoupMessage                                             *message;
 
        /* If policy is to deny all cookies return immediately */
        cookiePolicy=soup_cookie_jar_get_accept_policy(priv->cookieJar);
        if(cookiePolicy==SOUP_COOKIE_JAR_ACCEPT_NEVER) return;
 
+       /* Get SoupMessage */
+       message=webkit_network_response_get_message(inResponse);
+       if(!message || !SOUP_IS_MESSAGE(message)) return;
+
        /* Iterate through cookies in response and check if they should be
         * blocked (remove from cookies list) or accepted (added to cookie jar).
         * If we could not determine what to do collect these cookies and
         * ask user
         */
-       newCookies=soup_cookies_from_response(inMessage);
-       firstParty=soup_message_get_first_party(inMessage);
+       newCookies=soup_cookies_from_response(message);
+       firstParty=soup_message_get_first_party(message);
        for(cookie=newCookies; cookie; cookie=cookie->next)
        {
                switch(_cookie_permission_manager_get_policy(self, 
cookie->data))
@@ -712,7 +794,13 @@ static void 
_cookie_permission_manager_process_set_cookie_header(SoupMessage *in
         */
        if(g_slist_length(unknownCookies)>0)
        {
-               
unknownCookiesPolicy=_cookie_permission_manager_ask_for_policy(self, 
unknownCookies);
+               /* Get view */
+               MidoriView                                      *view;
+
+               view=MIDORI_VIEW(g_object_get_data(G_OBJECT(inView), 
"midori-view"));
+
+               /* Ask for user's decision */
+               
unknownCookiesPolicy=_cookie_permission_manager_ask_for_policy(self, view, 
message, unknownCookies);
                
if(unknownCookiesPolicy==COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT ||
                        
unknownCookiesPolicy==COOKIE_PERMISSION_MANAGER_POLICY_ACCEPT_FOR_SESSION)
                {
@@ -744,33 +832,51 @@ static void 
_cookie_permission_manager_process_set_cookie_header(SoupMessage *in
        g_slist_free(newCookies);
 }
 
-/* A request was started and is in queue now */
-static void _cookie_permission_manager_request_queued(SoupSessionFeature 
*inFeature, SoupSession *inSession, SoupMessage *inMessage)
+/* A tab to a browser was added */
+static void _cookie_permission_manager_on_add_tab(CookiePermissionManager 
*self, MidoriView *inView, gpointer inUserData)
 {
-       /* Get class instance */
-       CookiePermissionManager         
*manager=g_object_get_data(G_OBJECT(inFeature), "cookie-permission-manager");
+       /* Listen to starting network requests */
+       WebKitWebView   
*webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView));
 
-       /* Listen to "got-headers" signals and register handlers for
-        * checking cookie-managing headers in HTTP stream
-        */
-       soup_message_add_header_handler(inMessage,
-                                                                               
"got-headers",
-                                                                               
"Set-Cookie",
-                                                                               
G_CALLBACK(_cookie_permission_manager_process_set_cookie_header),
-                                                                               
manager);
-
-       soup_message_add_header_handler(inMessage,
-                                                                               
"got-headers",
-                                                                               
"Set-Cookie2",
-                                                                               
G_CALLBACK(_cookie_permission_manager_process_set_cookie_header),
-                                                                               
manager);
+       g_object_set_data(G_OBJECT(webkitView), "midori-view", inView);
+       g_signal_connect(webkitView, "resource-response-received", 
G_CALLBACK(_cookie_permission_manager_on_response_received), self);
 }
 
-/* Request has loaded and was unqueued */
-static void _cookie_permission_manager_request_unqueued(SoupSessionFeature 
*inFeature, SoupSession *inSession, SoupMessage *inMessage)
+/* A browser window was added */
+static void _cookie_permission_manager_on_add_browser(CookiePermissionManager 
*self,
+                                                                               
                                MidoriBrowser *inBrowser,
+                                                                               
                                gpointer inUserData)
 {
-       /* Stop listening to HTTP stream */
-       g_signal_handlers_disconnect_by_func(inMessage, 
_cookie_permission_manager_process_set_cookie_header, inFeature);
+       GList   *tabs, *iter;
+
+       /* Set up all current available tabs in browser */
+       tabs=midori_browser_get_tabs(inBrowser);
+       for(iter=tabs; iter; iter=g_list_next(iter))
+       {
+               _cookie_permission_manager_on_add_tab(self, iter->data, 
inBrowser);
+       }
+       g_list_free(tabs);
+
+       /* Listen to new tabs opened in browser and existing ones closed */
+       g_signal_connect_swapped(inBrowser, "add-tab", 
G_CALLBACK(_cookie_permission_manager_on_add_tab), self);
+}
+
+/* Application property has changed */
+static void 
_cookie_permission_manager_on_application_changed(CookiePermissionManager *self)
+{
+       CookiePermissionManagerPrivate          
*priv=COOKIE_PERMISSION_MANAGER(self)->priv;
+       GList                                                           
*browsers, *iter;
+
+       /* Set up all current open browser windows */
+       browsers=midori_app_get_browsers(priv->application);
+       for(iter=browsers; iter; iter=g_list_next(iter))
+       {
+               _cookie_permission_manager_on_add_browser(self, 
MIDORI_BROWSER(iter->data), priv->application);
+       }
+       g_list_free(browsers);
+
+       /* Listen to new browser windows opened and existing ones closed */
+       g_signal_connect_swapped(priv->application, "add-browser", 
G_CALLBACK(_cookie_permission_manager_on_add_browser), self);
 }
 
 /* IMPLEMENTATION: GObject */
@@ -778,9 +884,20 @@ static void 
_cookie_permission_manager_request_unqueued(SoupSessionFeature *inFe
 /* Finalize this object */
 static void cookie_permission_manager_finalize(GObject *inObject)
 {
-       CookiePermissionManagerPrivate  
*priv=COOKIE_PERMISSION_MANAGER(inObject)->priv;
+       CookiePermissionManager                 
*self=COOKIE_PERMISSION_MANAGER(inObject);
+       CookiePermissionManagerPrivate  *priv=self->priv;
+       GList                                                   *browsers, 
*browser;
+       GList                                                   *tabs, *tab;
+       WebKitWebView                                   *webkitView;
 
        /* Dispose allocated resources */
+       if(priv->databaseFilename)
+       {
+               g_free(priv->databaseFilename);
+               priv->databaseFilename=NULL;
+               g_object_notify_by_pspec(inObject, 
CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]);
+       }
+
        if(priv->database)
        {
                sqlite3_close(priv->database);
@@ -789,11 +906,24 @@ static void cookie_permission_manager_finalize(GObject 
*inObject)
        }
 
        g_signal_handler_disconnect(priv->cookieJar, priv->cookieJarChangedID);
+       g_object_steal_data(G_OBJECT(priv->cookieJar), 
"cookie-permission-manager");
 
-       priv->featureIface->request_queued=priv->oldRequestQueued;
-       priv->featureIface->request_unqueued=priv->oldRequestUnqueued;
+       g_signal_handlers_disconnect_by_data(priv->application, self);
 
-       g_object_steal_data(G_OBJECT(priv->cookieJar), 
"cookie-permission-manager");
+       browsers=midori_app_get_browsers(priv->application);
+       for(browser=browsers; browser; browser=g_list_next(browser))
+       {
+               g_signal_handlers_disconnect_by_data(browser->data, self);
+
+               tabs=midori_browser_get_tabs(MIDORI_BROWSER(browser->data));
+               for(tab=tabs; tab; tab=g_list_next(tab))
+               {
+                       
webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(MIDORI_VIEW(tab->data)));
+                       g_signal_handlers_disconnect_by_data(webkitView, self);
+               }
+               g_list_free(tabs);
+       }
+       g_list_free(browsers);
 
        /* Call parent's class finalize method */
        
G_OBJECT_CLASS(cookie_permission_manager_parent_class)->finalize(inObject);
@@ -806,7 +936,7 @@ static void cookie_permission_manager_set_property(GObject 
*inObject,
                                                                                
                        GParamSpec *inSpec)
 {
        CookiePermissionManager         
*self=COOKIE_PERMISSION_MANAGER(inObject);
-
+       
        switch(inPropID)
        {
                /* Construct-only properties */
@@ -817,6 +947,7 @@ static void cookie_permission_manager_set_property(GObject 
*inObject,
 
                case PROP_APPLICATION:
                        self->priv->application=g_value_get_object(inValue);
+                       _cookie_permission_manager_on_application_changed(self);
                        break;
 
                case PROP_ASK_FOR_UNKNOWN_POLICY:
@@ -850,6 +981,10 @@ static void cookie_permission_manager_get_property(GObject 
*inObject,
                        g_value_set_pointer(outValue, self->priv->database);
                        break;
 
+               case PROP_DATABASE_FILENAME:
+                       g_value_set_string(outValue, 
self->priv->databaseFilename);
+                       break;
+
                case PROP_ASK_FOR_UNKNOWN_POLICY:
                        g_value_set_boolean(outValue, 
self->priv->askForUnknownPolicy);
                        break;
@@ -896,6 +1031,13 @@ static void 
cookie_permission_manager_class_init(CookiePermissionManagerClass *k
                                                                _("Pointer to 
sqlite database instance used by this extension"),
                                                                
G_PARAM_READABLE);
 
+       CookiePermissionManagerProperties[PROP_DATABASE_FILENAME]=
+               g_param_spec_string("database-filename",
+                                                               _("Database 
path"),
+                                                               _("Path to 
sqlite database instance used by this extension"),
+                                                               NULL,
+                                                               
G_PARAM_READABLE);
+
        CookiePermissionManagerProperties[PROP_ASK_FOR_UNKNOWN_POLICY]=
                g_param_spec_boolean("ask-for-unknown-policy",
                                                                _("Ask for 
unknown policy"),
@@ -918,6 +1060,7 @@ static void 
cookie_permission_manager_init(CookiePermissionManager *self)
 
        /* Set up default values */
        priv->database=NULL;
+       priv->databaseFilename=NULL;
        priv->askForUnknownPolicy=TRUE;
 
        /* Hijack session's cookie jar to handle cookies requests on our own in 
HTTP streams
@@ -928,12 +1071,6 @@ static void 
cookie_permission_manager_init(CookiePermissionManager *self)
        priv->featureIface=SOUP_SESSION_FEATURE_GET_CLASS(priv->cookieJar);
        g_object_set_data(G_OBJECT(priv->cookieJar), 
"cookie-permission-manager", self);
 
-       priv->oldRequestQueued=priv->featureIface->request_queued;
-       priv->oldRequestUnqueued=priv->featureIface->request_unqueued;
-
-       
priv->featureIface->request_queued=_cookie_permission_manager_request_queued;
-       
priv->featureIface->request_unqueued=_cookie_permission_manager_request_unqueued;
-
        /* Listen to changed cookies set or changed by other sources like 
javascript */
        priv->cookieJarChangedID=g_signal_connect_swapped(priv->cookieJar, 
"changed", G_CALLBACK(_cookie_permission_manager_on_cookie_changed), self);
 }
_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
https://mail.xfce.org/mailman/listinfo/xfce4-commits

Reply via email to