2
Copyright (C) 2013 Eder Sosa <eder.sohe@gmail.com>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Lesser General Public
6
License as published by the Free Software Foundation; either
7
version 2.1 of the License, or (at your option) any later version.
9
See the file COPYING for the full license text.
12
#include <midori/midori.h>
21
static tabs2onePriv* priv;
24
tabs2one_private_new ()
26
tabs2onePriv* priv = g_slice_new (tabs2onePriv);
28
priv->filename = NULL;
34
void tabs2one_private_destroy (tabs2onePriv* priv)
36
katze_assign (priv->folder, NULL);
37
katze_assign (priv->filename, NULL);
38
katze_assign (priv->uri, NULL);
39
g_slice_free (tabs2onePriv, priv);
43
tabs2one_dom_click_restore_item_cb (WebKitDOMNode *element,
44
WebKitDOMEvent *dom_event,
45
WebKitWebView *webview);
48
tabs2one_dom_click_remove_item_cb (WebKitDOMNode *element,
49
WebKitDOMEvent *dom_event,
50
WebKitWebView *webview);
53
tabs2one_id_generator (void)
55
GString* id = g_string_new("");
56
GRand* generator = g_rand_new();
57
gint32 id1 = g_rand_int_range (generator, 1000, 9999);
58
gint32 id2 = g_rand_int_range (generator, 1000, 9999);
59
g_rand_free(generator);
60
g_string_printf(id, "%i-%i", id1, id2);
61
return g_string_free(id, FALSE);
65
tabs2one_dom_create_item (WebKitDOMDocument* doc,
70
WebKitDOMElement* body = webkit_dom_document_query_selector(doc, "body", NULL);
71
WebKitDOMElement* item = webkit_dom_document_create_element(doc, "div", NULL);
72
WebKitDOMElement* favicon = webkit_dom_document_create_element(doc, "img", NULL);
73
WebKitDOMElement* link = webkit_dom_document_create_element(doc, "a", NULL);
74
WebKitDOMElement* close_link = webkit_dom_document_create_element(doc, "a", NULL);
75
WebKitDOMElement* close_button = webkit_dom_document_create_element (doc, "img", NULL);
76
WebKitDOMElement* br = webkit_dom_document_create_element(doc, "br", NULL);
77
WebKitDOMText* content = webkit_dom_document_create_text_node(doc, title);
79
webkit_dom_element_set_attribute(item, "id", tabs2one_id_generator(), NULL);
80
webkit_dom_element_set_attribute(item, "class", "item", NULL);
81
webkit_dom_element_set_attribute(item, "style", "padding: 5px;", NULL);
83
webkit_dom_element_set_attribute(close_link, "class", "close-link", NULL);
84
webkit_dom_element_set_attribute(close_link, "target", "_blank", NULL);
85
webkit_dom_element_set_attribute(close_link, "href", "about:blank", NULL);
86
webkit_dom_element_set_attribute(close_button, "src", "res://close.png", NULL);
87
webkit_dom_element_set_attribute(close_button, "width", "16px", NULL);
88
webkit_dom_element_set_attribute(close_button, "height", "16px", NULL);
90
webkit_dom_element_set_attribute(favicon, "src", icon, NULL);
91
webkit_dom_element_set_attribute(favicon, "width", "16px", NULL);
92
webkit_dom_element_set_attribute(favicon, "height", "16px", NULL);
93
webkit_dom_element_set_attribute(favicon, "style", "padding-left: 5px;", NULL);
95
webkit_dom_element_set_attribute(link, "class", "restore-link",NULL);
96
webkit_dom_element_set_attribute(link, "href", uri, NULL);
97
webkit_dom_element_set_attribute(link, "style", "padding-left: 5px;", NULL);
98
webkit_dom_element_set_attribute(link, "target", "_blank", NULL);
100
webkit_dom_node_append_child(WEBKIT_DOM_NODE(link), WEBKIT_DOM_NODE(content), NULL);
101
webkit_dom_node_append_child(WEBKIT_DOM_NODE(item), WEBKIT_DOM_NODE(close_link), NULL);
102
webkit_dom_node_append_child(WEBKIT_DOM_NODE(close_link), WEBKIT_DOM_NODE(close_button), NULL);
103
webkit_dom_node_append_child(WEBKIT_DOM_NODE(item), WEBKIT_DOM_NODE(favicon), NULL);
104
webkit_dom_node_append_child(WEBKIT_DOM_NODE(item), WEBKIT_DOM_NODE(link), NULL);
105
webkit_dom_node_append_child(WEBKIT_DOM_NODE(item), WEBKIT_DOM_NODE(br), NULL);
106
webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(item), NULL);
110
tabs2one_cache_create_dir (void)
112
midori_paths_mkdir_with_parents (priv->folder, 0700);
116
tabs2one_cache_get_filename (void)
118
return priv->filename;
122
tabs2one_cache_get_uri (void)
128
tabs2one_cache_exist (void)
130
return g_file_test (priv->filename, G_FILE_TEST_EXISTS);
134
tabs2one_is_uri_tabs2one_tab (const gchar* uri)
136
return g_str_equal (uri, tabs2one_cache_get_uri ());
140
tabs2one_dom_add_click_listeners (WebKitDOMDocument* doc,
141
WebKitWebView* webview)
143
WebKitDOMNodeList *elements = webkit_dom_document_query_selector_all(doc, ".restore-link", NULL);
147
for (i = 0; i < webkit_dom_node_list_get_length(elements); i++)
149
WebKitDOMNode *element = webkit_dom_node_list_item(elements, i);
150
webkit_dom_event_target_add_event_listener(
151
WEBKIT_DOM_EVENT_TARGET(element), "click",
152
G_CALLBACK (tabs2one_dom_click_restore_item_cb), TRUE, webview);
155
elements = webkit_dom_document_query_selector_all(doc, ".close-link", NULL);
156
for (i = 0; i < webkit_dom_node_list_get_length(elements); i++)
158
WebKitDOMNode *element = webkit_dom_node_list_item(elements, i);
159
webkit_dom_event_target_add_event_listener(
160
WEBKIT_DOM_EVENT_TARGET(element), "click",
161
G_CALLBACK (tabs2one_dom_click_remove_item_cb), TRUE, webview);
166
tabs2one_cache_write_file (WebKitWebView* webview)
168
WebKitDOMDocument* doc = webkit_web_view_get_dom_document(webview);
169
WebKitDOMHTMLDocument* dochtml = (WebKitDOMHTMLDocument*)doc;
170
WebKitDOMHTMLElement* elementhtml = (WebKitDOMHTMLElement*)dochtml;
171
const gchar* content = webkit_dom_html_element_get_inner_html(elementhtml);
175
tabs2one_dom_add_click_listeners (doc, webview);
177
return g_file_set_contents(tabs2one_cache_get_filename (), content, -1, NULL);
181
tabs2one_onload_create_items_cb(WebKitWebView* webview,
182
WebKitWebFrame* webframe,
183
MidoriBrowser* browser)
185
WebKitDOMDocument* doc = webkit_web_view_get_dom_document(webview);
191
GList* tabs = midori_browser_get_tabs (browser);
192
for (; tabs; tabs = g_list_next (tabs))
194
icon = midori_view_get_icon_uri (tabs->data);
195
if (icon == NULL) icon = "";
196
title = midori_view_get_display_title (tabs->data);
197
uri = midori_view_get_display_uri (tabs->data);
199
if (!tabs2one_is_uri_tabs2one_tab (uri))
201
if (!midori_uri_is_blank (uri))
202
tabs2one_dom_create_item(doc, icon, uri, title);
207
if (tabs2one_cache_write_file (webview))
209
tabs = midori_browser_get_tabs (browser);
210
while ((tabs = g_list_next (tabs)))
211
midori_browser_close_tab (browser, tabs->data);
213
tabs2one_dom_add_click_listeners (doc, webview);
214
midori_browser_set_current_uri (browser, tabs2one_cache_get_uri ());
221
tabs2one_reload_connected_events_cb(WebKitWebView* webview,
222
WebKitWebFrame* frame,
225
const gchar* uri = midori_view_get_display_uri(view);
227
if (tabs2one_is_uri_tabs2one_tab (uri))
229
WebKitDOMDocument* doc = webkit_web_view_get_dom_document(webview);
230
tabs2one_dom_add_click_listeners (doc, webview);
236
tabs2one_add_tab_cb (MidoriBrowser* browser,
238
MidoriExtension* extension)
240
WebKitWebView* webview = WEBKIT_WEB_VIEW (midori_view_get_web_view(view));
241
g_signal_connect (webview, "document-load-finished",
242
G_CALLBACK (tabs2one_reload_connected_events_cb), view);
246
tabs2one_dom_click_restore_item_cb (WebKitDOMNode *element,
247
WebKitDOMEvent *dom_event,
248
WebKitWebView *webview)
250
webkit_dom_event_prevent_default (dom_event);
251
MidoriView* view = midori_view_get_for_widget (GTK_WIDGET (webview));
252
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (webview));
253
WebKitDOMNode* item = webkit_dom_node_get_parent_node (element);
254
WebKitDOMNode* body = webkit_dom_node_get_parent_node (item);
255
const gchar* uri = webkit_dom_element_get_attribute(WEBKIT_DOM_ELEMENT(element), "href");
256
midori_browser_add_uri (browser, uri);
258
WebKitDOMDocument* doc = webkit_web_view_get_dom_document (webview);
259
webkit_dom_node_remove_child(body, item, NULL);
260
tabs2one_cache_write_file (webview);
262
WebKitDOMNodeList *elements = webkit_dom_document_query_selector_all(doc, ".restore-link", NULL);
263
if (webkit_dom_node_list_get_length(elements) <= 0){
264
midori_browser_close_tab(browser, GTK_WIDGET(view));
269
tabs2one_dom_click_remove_item_cb (WebKitDOMNode *element,
270
WebKitDOMEvent *dom_event,
271
WebKitWebView *webview)
273
webkit_dom_event_prevent_default (dom_event);
274
MidoriView* view = midori_view_get_for_widget (GTK_WIDGET (webview));
275
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (webview));
276
WebKitDOMNode* item = webkit_dom_node_get_parent_node (element);
277
WebKitDOMNode* body = webkit_dom_node_get_parent_node (item);
279
WebKitDOMDocument* doc = webkit_web_view_get_dom_document (webview);
280
webkit_dom_node_remove_child(body, item, NULL);
281
tabs2one_cache_write_file (webview);
283
WebKitDOMNodeList *elements = webkit_dom_document_query_selector_all(doc, ".close-link", NULL);
284
if (webkit_dom_node_list_get_length(elements) <= 0){
285
midori_browser_close_tab(browser, GTK_WIDGET(view));
290
tabs2one_apply_cb (GtkWidget* menuitem,
291
MidoriBrowser* browser)
293
GtkWidget* tab = NULL;
295
if (!tabs2one_cache_exist ())
297
GString* tpl = g_string_new ("<html>\n<title>");
299
g_string_append_printf (tpl, "%s", _("Tabs to One"));
300
g_string_append (tpl, "</title>\n<head><meta charset=\"utf-8\"></head><body>\n");
301
g_string_append_printf (tpl, "<h2>%s</h2>\n", _("Tabs you collected so far"));
302
g_string_append_printf (tpl, "<div><span>%s</span></div>\n", _("Clicking an item restores a tab."));
303
g_string_append (tpl, "</body>\n</html>\n");
305
g_file_set_contents(tabs2one_cache_get_filename (), g_string_free (tpl, FALSE), -1, NULL);
308
tab = midori_browser_add_uri (browser, tabs2one_cache_get_uri ());
310
WebKitWebView* webview = WEBKIT_WEB_VIEW (midori_view_get_web_view(MIDORI_VIEW (tab)));
311
midori_browser_set_current_tab (browser, tab);
313
g_signal_connect (webview, "document-load-finished",
314
G_CALLBACK (tabs2one_onload_create_items_cb), browser);
318
tabs2one_app_add_browser_cb (MidoriApp* app,
319
MidoriBrowser* browser,
320
MidoriExtension* extension);
323
tabs2one_browser_populate_tool_menu_cb (MidoriBrowser* browser,
325
MidoriExtension* extension)
327
GtkWidget* menuitem = gtk_menu_item_new_with_mnemonic (_("Tabs to _One"));
329
g_signal_connect (menuitem, "activate",
330
G_CALLBACK (tabs2one_apply_cb), browser);
331
gtk_widget_show (menuitem);
332
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
336
tabs2one_deactivate_cb (MidoriExtension* extension,
337
MidoriBrowser* browser)
339
MidoriApp* app = midori_extension_get_app (extension);
341
g_signal_handlers_disconnect_by_func (
342
browser, tabs2one_browser_populate_tool_menu_cb, extension);
343
g_signal_handlers_disconnect_by_func (
344
extension, tabs2one_deactivate_cb, browser);
345
g_signal_handlers_disconnect_by_func (
346
app, tabs2one_app_add_browser_cb, extension);
347
g_signal_handlers_disconnect_by_func (
348
browser, tabs2one_add_tab_cb, extension);
350
tabs2one_private_destroy (priv);
354
tabs2one_app_add_browser_cb (MidoriApp* app,
355
MidoriBrowser* browser,
356
MidoriExtension* extension)
358
g_signal_connect (browser, "populate-tool-menu",
359
G_CALLBACK (tabs2one_browser_populate_tool_menu_cb), extension);
360
g_signal_connect (extension, "deactivate",
361
G_CALLBACK (tabs2one_deactivate_cb), browser);
362
g_signal_connect_after (browser, "add-tab",
363
G_CALLBACK (tabs2one_add_tab_cb), extension);
365
tabs2one_cache_create_dir();
369
tabs2one_activate_cb (MidoriExtension* extension,
372
const gchar* config_dir = midori_extension_get_config_dir (extension);
373
priv = tabs2one_private_new ();
374
KatzeArray* browsers;
375
MidoriBrowser* browser;
376
gchar* filename, *uri;
378
filename = g_build_filename (config_dir, "tabs2one.html", NULL);
379
uri = g_filename_to_uri (filename, NULL, NULL);
381
priv->filename = g_strdup (filename);
382
priv->uri = g_strdup (uri);
383
priv->folder = g_strdup (config_dir);
385
browsers = katze_object_get_object (app, "browsers");
386
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
387
tabs2one_app_add_browser_cb (app, browser, extension);
388
g_object_unref (browsers);
389
g_signal_connect (app, "add-browser",
390
G_CALLBACK (tabs2one_app_add_browser_cb), extension);
397
extension_init (void)
399
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
400
"name", _("Tabs to One"),
401
"description", _("Closes all open tabs and creates new tab with tabs links"),
402
"version", "0.1" MIDORI_VERSION_SUFFIX,
403
"authors", "Eder Sosa <eder.sohe@gmail.com>",
406
g_signal_connect (extension, "activate",
407
G_CALLBACK (tabs2one_activate_cb), NULL);