/* A tab to a browser was added */ static void _cookie_permission_manager_on_add_tab(CookiePermissionManager *self, MidoriView *inView, gpointer inUserData) { /* Listen to starting network requests */ WebKitWebView *webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView)); 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); }
static void formhistory_deactivate_tab (MidoriView* view, MidoriExtension* extension) { GtkWidget* web_view = midori_view_get_web_view (view); g_signal_handlers_disconnect_by_func ( web_view, formhistory_window_object_cleared_cb, extension); g_signal_handlers_disconnect_by_func ( web_view, formhistory_navigation_decision_cb, extension); g_signal_handlers_disconnect_by_func ( web_view, formhistory_frame_loaded_cb, extension); }
static void formhistory_add_tab_cb (MidoriBrowser* browser, MidoriView* view, MidoriExtension* extension) { GtkWidget* web_view = midori_view_get_web_view (view); g_signal_connect (web_view, "window-object-cleared", G_CALLBACK (formhistory_window_object_cleared_cb), extension); g_signal_connect (web_view, "navigation-policy-decision-requested", G_CALLBACK (formhistory_navigation_decision_cb), extension); g_signal_connect (web_view, "onload-event", G_CALLBACK (formhistory_frame_loaded_cb), extension); }
static void mouse_gestures_deactivate_tabs (MidoriView* view, MidoriBrowser* browser) { GtkWidget* web_view = midori_view_get_web_view (view); g_object_disconnect (web_view, "any_signal::button-press-event", mouse_gestures_button_press_event_cb, browser, "any_signal::motion-notify-event", mouse_gestures_motion_notify_event_cb, browser, "any_signal::button-release-event", mouse_gestures_button_release_event_cb, view, NULL); }
static void mouse_gestures_add_tab_cb (MidoriBrowser* browser, MidoriView* view, MidoriExtension* extension) { GtkWidget* web_view = midori_view_get_web_view (view); g_object_connect (web_view, "signal::button-press-event", mouse_gestures_button_press_event_cb, browser, "signal::motion-notify-event", mouse_gestures_motion_notify_event_cb, browser, "signal::button-release-event", mouse_gestures_button_release_event_cb, view, NULL); }
/* Finalize this object */ static void cookie_permission_manager_finalize(GObject *inObject) { 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); priv->database=NULL; g_object_notify_by_pspec(inObject, CookiePermissionManagerProperties[PROP_DATABASE]); } g_signal_handler_disconnect(priv->cookieJar, priv->cookieJarChangedID); g_object_steal_data(G_OBJECT(priv->cookieJar), "cookie-permission-manager"); g_signal_handlers_disconnect_by_data(priv->application, self); 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); }
static void night_mode_tabs_view_notify_uri_cb (MidoriView* view, GParamSpec* pspec, MidoriExtension* extension) { gchar* exception = NULL; gchar *script=NULL; FILE *fp; int file_size; gboolean result; const gchar* uri = midori_view_get_display_uri (view); if (!*uri) return; if (g_night_mode) { if (!midori_uri_is_blank (uri)) { gchar* hostname = midori_uri_parse_hostname (uri, NULL); if (hostname) { if((fp=fopen(midori_paths_get_res_filename("night_mode/nightingale_view_content.js"),"r"))!=NULL) { fseek(fp,0,SEEK_END); file_size=ftell(fp); fseek(fp,0,SEEK_SET); script=(char *)malloc(file_size * sizeof(char)+1); fread(script,file_size,sizeof(char),fp); script[file_size*sizeof(char)]='\0'; fclose(fp); result = midori_view_execute_script (view, script, &exception); free(script); script=NULL; } g_free (hostname); } } } else { GtkWidget* current_web_view = midori_view_get_web_view (MIDORI_VIEW (view)); webkit_web_view_run_javascript(WEBKIT_WEB_VIEW (current_web_view), night_mode_remove, NULL, NULL, NULL); } }
static void night_mode_deactivated_cb (MidoriExtension* extension, MidoriBrowser* browser) { if(night_mode_button) gtk_widget_destroy (night_mode_button); g_signal_handlers_disconnect_by_func (extension, night_mode_deactivated_cb, browser); if(g_night_mode) { GList* children = midori_browser_get_tabs (MIDORI_BROWSER (browser)); for (; children; children = g_list_next (children)) { GtkWidget* current_web_view = midori_view_get_web_view (MIDORI_VIEW (children->data)); webkit_web_view_run_javascript(WEBKIT_WEB_VIEW (current_web_view), night_mode_remove, NULL, NULL, NULL); } g_list_free (children); g_signal_handlers_disconnect_by_func (browser, night_mode_extension_browser_add_tab_cb, NULL); } }
/* A tab of a browser was added */ static void _interface_tweaks_on_add_tab(InterfaceTweaks *self, MidoriView *inView, gpointer inUserData) { g_return_if_fail(IS_INTERFACE_TWEAKS(self)); g_return_if_fail(MIDORI_IS_VIEW(inView)); g_return_if_fail(MIDORI_IS_BROWSER(inUserData)); WebKitWebView *webkitView; /* Connect signals to midori view and webkit webview to monitor loading state */ g_signal_connect_swapped(inView, "notify::minimized", G_CALLBACK(_interface_tweaks_on_notify_minimized_tab_for_close_button), self); _interface_tweaks_on_notify_minimized_tab_for_close_button(self, NULL, inView); g_signal_connect_swapped(inView, "notify::minimized", G_CALLBACK(_interface_tweaks_on_notify_minimized_tab_for_group_tabs), self); _interface_tweaks_on_notify_minimized_tab_for_group_tabs(self, NULL, inView); webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(inView)); g_signal_connect_swapped(webkitView, "notify::load-status", G_CALLBACK(_interface_tweaks_on_notify_view_load_status), self); _interface_tweaks_on_notify_view_load_status(self, NULL, webkitView); }
static gint _cookie_permission_manager_ask_for_policy(CookiePermissionManager *self, MidoriView *inView, SoupMessage *inMessage, GSList *inUnknownCookies) { /* 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)); modalInfo=g_new0(CookiePermissionManagerModalInfobar, 1); /* Create a copy of cookies and sort them */ sortedCookies=_cookie_permission_manager_get_number_domains_and_cookies(self, inUnknownCookies, &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 */ G_TYPE_STRING, /* PATH_COLUMN */ G_TYPE_STRING, /* NAME_COLUMN */ G_TYPE_STRING, /* VALUE_COLUMN */ G_TYPE_STRING /* EXPIRE_DATE_COLUMN */); for(cookies=sortedCookies; cookies; cookies=cookies->next) { SoupCookie *cookie=(SoupCookie*)cookies->data; SoupDate *cookieDate=soup_cookie_get_expires(cookie); 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, &listIter, DOMAIN_COLUMN, soup_cookie_get_domain(cookie), PATH_COLUMN, soup_cookie_get_path(cookie), NAME_COLUMN, soup_cookie_get_name(cookie), VALUE_COLUMN, soup_cookie_get_value(cookie), EXPIRE_DATE_COLUMN, text, -1); g_free(text); } #endif /* Create description text */ 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 text=g_strdup_printf(_("The website %s wants to store a cookie."), cookieDomain); } else { text=g_strdup_printf(_("Multiple websites want to store %d cookies in total."), numberCookies); } /* 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); /* 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_full(G_OBJECT(infobar), "cookie-permission-manager-infobar-data", modalInfo, (GDestroyNotify)g_free); /* FIXME: Find a way to add "details" widget */ #ifndef NO_INFOBAR_DETAILS /* Get content area of infobar */ contentArea=gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar)); /* Create list and set up columns of list */ list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(listStore)); #ifndef HAVE_GTK3 gtk_widget_set_size_request(list, -1, 100); #endif renderer=gtk_cell_renderer_text_new(); column=gtk_tree_view_column_new_with_attributes(_("Domain"), renderer, "text", DOMAIN_COLUMN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); renderer=gtk_cell_renderer_text_new(); column=gtk_tree_view_column_new_with_attributes(_("Path"), renderer, "text", PATH_COLUMN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); renderer=gtk_cell_renderer_text_new(); column=gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); renderer=gtk_cell_renderer_text_new(); column=gtk_tree_view_column_new_with_attributes(_("Value"), renderer, "text", VALUE_COLUMN, NULL); g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, "width-chars", 30, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); renderer=gtk_cell_renderer_text_new(); column=gtk_tree_view_column_new_with_attributes(_("Expire date"), renderer, "text", EXPIRE_DATE_COLUMN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); scrolled=gtk_scrolled_window_new(NULL, NULL); #ifdef HAVE_GTK3 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), 100); #endif gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(expander), scrolled); gtk_widget_show_all(vbox); gtk_container_add(GTK_CONTAINER(contentArea), vbox); /* Set state of expander based on config 'show-details-when-ask' */ 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 /* Show all widgets of info bar */ gtk_widget_show_all(infobar); /* 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); /* 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); 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(modalInfo->response!=COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED) { const gchar *lastDomain=NULL; /* Iterate through cookies and store decision for each domain once */ for(cookies=sortedCookies; cookies; cookies=cookies->next) { SoupCookie *cookie=(SoupCookie*)cookies->data; const gchar *cookieDomain=soup_cookie_get_domain(cookie); if(*cookieDomain=='.') cookieDomain++; /* Store decision if new domain found while iterating through cookies */ if(!lastDomain || g_ascii_strcasecmp(lastDomain, cookieDomain)!=0) { gchar *sql; gchar *error=NULL; gint success; sql=sqlite3_mprintf("INSERT OR REPLACE INTO policies (domain, value) VALUES ('%q', %d);", cookieDomain, 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); sqlite3_free(sql); lastDomain=cookieDomain; } } } /* Free up allocated resources */ g_slist_free(sortedCookies); /* Return response */ return(modalInfo->response==COOKIE_PERMISSION_MANAGER_POLICY_UNDETERMINED ? COOKIE_PERMISSION_MANAGER_POLICY_BLOCK : modalInfo->response); }
/* Application property has changed */ static void _interface_tweaks_on_application_changed(InterfaceTweaks *self, MidoriApp *inApplication) { g_return_if_fail(IS_INTERFACE_TWEAKS(self)); g_return_if_fail(inApplication==NULL || MIDORI_IS_APP(inApplication)); InterfaceTweaksPrivate *priv=INTERFACE_TWEAKS(self)->priv; GtkNotebook *notebook; MidoriBrowser *browser; GList *browsers, *browsersIter; GList *tabs, *tabsIter; WebKitWebView *webkitView; InterfaceTweaksLocationbarLookup locationbar; /* Release resources on current application object */ if(priv->application) { g_signal_handlers_disconnect_by_data(priv->application, self); browsers=midori_app_get_browsers(priv->application); for(browsersIter=browsers; browsersIter; browsersIter=g_list_next(browsersIter)) { browser=MIDORI_BROWSER(browsersIter->data); g_signal_handlers_disconnect_by_data(browser, self); tabs=midori_browser_get_tabs(MIDORI_BROWSER(browsersIter->data)); for(tabsIter=tabs; tabsIter; tabsIter=g_list_next(tabsIter)) { g_signal_handlers_disconnect_by_data(tabsIter->data, self); webkitView=WEBKIT_WEB_VIEW(midori_view_get_web_view(MIDORI_VIEW(tabsIter->data))); g_signal_handlers_disconnect_by_data(webkitView, self); } g_list_free(tabs); notebook=NULL; g_object_get(browser, "notebook", ¬ebook, NULL); if(notebook) { g_signal_handlers_disconnect_by_data(notebook, self); g_object_unref(notebook); } _interface_tweaks_find_browser_locationbar(browser, &locationbar); if(locationbar.widget) { GtkEntry *entry=GTK_ENTRY(locationbar.widget); GtkEntryCompletion *completion; gulong hookID; guint keyPressSignalID; g_signal_handlers_disconnect_by_data(entry, self); completion=gtk_entry_get_completion(GTK_ENTRY(entry)); if(completion) { g_signal_handlers_disconnect_by_data(completion, self); gtk_entry_set_completion(entry, NULL); } hookID=GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(entry), "interface-tweaks-hook-id")); if(hookID!=0) { keyPressSignalID=g_signal_lookup("key-press-event", GTK_TYPE_ENTRY); g_signal_remove_emission_hook(keyPressSignalID, hookID); hookID=0L; g_object_set_data(G_OBJECT(entry), "interface-tweaks-hook-id", GSIZE_TO_POINTER(hookID)); } } } g_list_free(browsers); g_object_unref(priv->application); priv->application=NULL; } /* Set new application object */ if(!inApplication) return; priv->application=g_object_ref(inApplication); /* Set up all current open browser windows */ browsers=midori_app_get_browsers(priv->application); for(browsersIter=browsers; browsersIter; browsersIter=g_list_next(browsersIter)) { _interface_tweaks_on_add_browser(self, MIDORI_BROWSER(browsersIter->data), priv->application); } g_list_free(browsers); /* Listen to new browser windows opened */ g_signal_connect_swapped(priv->application, "add-browser", G_CALLBACK(_interface_tweaks_on_add_browser), self); /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), InterfaceTweaksProperties[PROP_APPLICATION]); }