Merge lp:~midori/midori/moreBeans into lp:midori

Proposed by Christian Dywan on 2015-06-20
Status: Work in progress
Proposed branch: lp:~midori/midori/moreBeans
Merge into: lp:midori
Diff against target: 2151 lines (+954/-804)
29 files modified
CMakeLists.txt (+11/-2)
extensions/CMakeLists.txt (+89/-72)
extensions/about.vala (+6/-1)
extensions/example.py (+14/-0)
extensions/examplepy.plugin (+9/-0)
extensions/extension-manager.vala (+273/-0)
extensions/hsts.web.plugin (+8/-0)
extensions/hsts.web.vala (+176/-0)
extensions/tabs-minimized.c (+0/-87)
extensions/tabs-minimized.plugin (+9/-0)
extensions/tabs-minimized.vala (+68/-0)
extensions/web-extension.web.vala (+68/-0)
ipc/CMakeLists.txt (+50/-0)
ipc/ipc-tab.vala (+19/-0)
katze/katze.vapi (+1/-0)
katze/midori-paths.vala (+38/-6)
midori/main.c (+50/-0)
midori/midori-app.c (+1/-1)
midori/midori-extension.c (+13/-0)
midori/midori-frontend.c (+0/-10)
midori/midori-preferences.c (+1/-31)
midori/midori-settings.vala (+22/-0)
midori/midori-stock.h (+1/-1)
midori/midori-tab.vala (+18/-0)
midori/midori.vapi (+3/-1)
midori/webkit2gtk-web-extension-4.0.vapi (+1/-1)
panels/midori-extensions.c (+0/-544)
panels/midori-extensions.h (+0/-45)
po/POTFILES.in (+5/-2)
To merge this branch: bzr merge lp:~midori/midori/moreBeans
Reviewer Review Type Date Requested Status
Midori Devs 2015-06-20 Pending
Review via email: mp+262521@code.launchpad.net

Commit message

Implement Peas plugin loading for GUI and web process

To post a comment you must log in.
lp:~midori/midori/moreBeans updated on 2015-06-22
6967. By Christian Dywan on 2015-06-21

HSTS and Minimized Tabs implemented with activatables

6968. By Christian Dywan on 2015-06-21

Use HAVE_PEAS for easier build testing

6969. By Christian Dywan on 2015-06-22

Reincarnate Extensions panel as Extension Manager with Peas support

Unmerged revisions

6969. By Christian Dywan on 2015-06-22

Reincarnate Extensions panel as Extension Manager with Peas support

6968. By Christian Dywan on 2015-06-21

Use HAVE_PEAS for easier build testing

6967. By Christian Dywan on 2015-06-21

HSTS and Minimized Tabs implemented with activatables

6966. By Christian Dywan on 2015-06-20

Implement Peas plugin loading for GUI and web process

6965. By Christian Dywan on 2015-06-13

Implement HSTS as a web extension

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-06-18 05:03:38 +0000
3+++ CMakeLists.txt 2015-06-22 22:20:28 +0000
4@@ -193,6 +193,12 @@
5 add_definitions("-DHAVE_GCR")
6 set(OPTS_INCLUDE_DIRS ${OPTS_INCLUDE_DIRS} ${GCR_INCLUDE_DIRS})
7 set(OPTS_LIBRARIES ${OPTS_LIBRARIES} ${GCR_LIBRARIES})
8+
9+ pkg_check_modules(PEAS REQUIRED libpeas-1.0>=1.4)
10+ set(OPTS_INCLUDE_DIRS ${OPTS_INCLUDE_DIRS} ${PEAS_INCLUDE_DIRS})
11+ set(OPTS_LIBRARIES ${OPTS_LIBRARIES} ${PEAS_LIBRARIES})
12+ set(PKGS ${PKGS} libpeas-1.0)
13+ set(VALAFLAGS ${VALAFLAGS} -D HAVE_PEAS)
14 endif ()
15
16 if (HALF_BRO_INCOM_WEBKIT2)
17@@ -204,7 +210,6 @@
18 add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"")
19 add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit2gtk-4.0_VERSION}\"")
20 set(PKGS ${PKGS} gtk+-3.0)
21- # set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-web-extension-4.0.vapi")
22 set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-4.0.vapi")
23 set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3)
24 set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2)
25@@ -272,9 +277,13 @@
26 install(FILES AUTHORS COPYING ChangeLog EXPAT README DESTINATION ${CMAKE_INSTALL_DOCDIR})
27
28 add_subdirectory (midori)
29-add_subdirectory (extensions)
30+if (HALF_BRO_INCOM_WEBKIT2)
31+ set(LIBMIDORI2 "${CMAKE_PROJECT_NAME}-ipc")
32+ add_subdirectory (ipc)
33+endif ()
34 enable_testing()
35 add_subdirectory (tests)
36+add_subdirectory (extensions)
37 add_subdirectory (po)
38 add_subdirectory (icons)
39 add_subdirectory (data)
40
41=== modified file 'extensions/CMakeLists.txt'
42--- extensions/CMakeLists.txt 2015-04-19 14:06:12 +0000
43+++ extensions/CMakeLists.txt 2015-06-22 22:20:28 +0000
44@@ -8,9 +8,9 @@
45 ${DEPS_INCLUDE_DIRS}
46 ${OPTS_INCLUDE_DIRS}
47 ${DEPS_GTK_INCLUDE_DIRS}
48- ${OPTS_GTK_INCLUDE_DIRS}
49 ${CMAKE_BINARY_DIR}
50 "${CMAKE_BINARY_DIR}/midori"
51+ "${CMAKE_BINARY_DIR}/ipc"
52 )
53 file(GLOB EXTENSIONS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
54 if (HALF_BRO_INCOM_WEBKIT2)
55@@ -23,6 +23,11 @@
56 "nsplugin-manager.vala"
57 "tabs2one.c"
58 )
59+else ()
60+ list(REMOVE_ITEM EXTENSIONS
61+ "hsts.web.vala"
62+ "web-extension.web.vala"
63+ )
64 endif ()
65
66 # FIXME: re-enable webmedia extension
67@@ -36,99 +41,111 @@
68 list(REMOVE_ITEM EXTENSIONS "tabs2one.c")
69 endif()
70
71-foreach(UNIT_SRC ${EXTENSIONS})
72- string(FIND ${UNIT_SRC} ".c" UNIT_EXTENSION)
73- if (UNIT_EXTENSION GREATER -1)
74- string(REPLACE ".c" "" UNIT ${UNIT_SRC})
75- add_library(${UNIT} MODULE ${UNIT_SRC})
76- target_link_libraries(${UNIT}
77- ${LIBMIDORI}
78- )
79- set_target_properties(${UNIT} PROPERTIES
80- COMPILE_FLAGS ${CFLAGS}
81- )
82- install(TARGETS ${UNIT}
83- LIBRARY DESTINATION ${EXTENSIONDIR}
84- )
85+include(ValaPrecompile)
86+
87+macro(build_extension name)
88+ set(source "${ARGN}")
89+ set(SOURCE_VALA "")
90+
91+ set(PLUGIN "${CMAKE_CURRENT_SOURCE_DIR}/${name}.plugin")
92+ if (EXISTS ${PLUGIN})
93+ file(COPY ${PLUGIN} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
94 endif ()
95-endforeach ()
96
97-foreach(UNIT_SRC ${EXTENSIONS})
98- string(FIND ${UNIT_SRC} "." UNIT_EXTENSION)
99- if (UNIT_EXTENSION EQUAL -1)
100- file(GLOB UNIT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.c")
101- file(GLOB UNIT_FILES_VALA RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.vala")
102- if (UNIT_FILES_VALA)
103- include(ValaPrecompile)
104- vala_precompile(UNIT_SRC_C ${UNIT_SRC}
105- ${UNIT_FILES_VALA}
106+ foreach(FILE ${source})
107+ string(FIND ${FILE} ".web." WEB_EXTENSION)
108+ string(FIND ${FILE} ".vala" VALA_EXTENSION)
109+ if (WEB_EXTENSION GREATER -1)
110+ string(REPLACE ".vala" "" WEB_NAME "${name}_${FILE}")
111+ string(REPLACE "." "_" WEB_NAME "${WEB_NAME}")
112+ vala_precompile(WEB_EXTENSION_C "${WEB_NAME}"
113+ ${FILE}
114 PACKAGES
115 ${PKGS}
116 OPTIONS
117 ${VALAFLAGS}
118- --use-header="${CMAKE_PROJECT_NAME}-core.h"
119- GENERATE_HEADER
120- "${UNIT_SRC}"
121- GENERATE_HEADER
122- ${UNIT}
123+ GENERATE_HEADER
124+ ${FILE}
125 CUSTOM_VAPIS
126- ${EXTRA_VAPIS}
127- "${CMAKE_SOURCE_DIR}/midori/midori.vapi"
128- "${CMAKE_BINARY_DIR}/midori/${LIBMIDORI}.vapi"
129+ "${CMAKE_BINARY_DIR}/ipc/${LIBMIDORI2}.vapi"
130+ "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-web-extension-4.0.vapi"
131 )
132- set(UNIT_FILES ${UNIT_FILES} ${UNIT_SRC_C})
133- endif ()
134- if (UNIT_FILES)
135- add_library(${UNIT_SRC} MODULE ${UNIT_FILES})
136- target_link_libraries(${UNIT_SRC}
137- ${LIBMIDORI}
138- )
139- install(TARGETS ${UNIT_SRC}
140+ add_library(${WEB_NAME} MODULE ${WEB_EXTENSION_C})
141+ target_link_libraries(${WEB_NAME}
142+ ${LIBMIDORI2}
143+ )
144+ install(TARGETS ${WEB_NAME}
145 LIBRARY DESTINATION ${EXTENSIONDIR}
146 )
147- # extensions with vala code get the lenient VALA_CFLAGS
148- # others get the usual CFLAGS with -Wall and -Werror
149- if (UNIT_FILES_VALA)
150- set_target_properties(${UNIT_SRC} PROPERTIES
151- COMPILE_FLAGS ${VALA_CFLAGS}
152- )
153- else ()
154- set_target_properties(${UNIT_SRC} PROPERTIES
155- COMPILE_FLAGS ${CFLAGS}
156- )
157- endif ()
158+ # Extensions with Vala code get the lenient VALA_CFLAGS
159+ set_target_properties(${WEB_NAME} PROPERTIES
160+ COMPILE_FLAGS ${VALA_CFLAGS}
161+ )
162+ list(REMOVE_ITEM source ${FILE})
163+
164+ # Mandatory unit testing
165+ add_test(NAME "test-${WEB_NAME}" COMMAND $<TARGET_FILE:midori> -t $<TARGET_FILE:${WEB_NAME}>)
166+ contain_test("test-${WEB_NAME}" $<TARGET_FILE:midori> -t $<TARGET_FILE:${WEB_NAME}>)
167+ elseif (VALA_EXTENSION GREATER -1)
168+ list(APPEND SOURCE_VALA ${FILE})
169 endif ()
170- endif ()
171-endforeach ()
172-
173-foreach(UNIT_SRC ${EXTENSIONS})
174- string(FIND ${UNIT_SRC} ".vala" UNIT_EXTENSION)
175- if (UNIT_EXTENSION GREATER -1)
176- string(REPLACE ".vala" "" UNIT ${UNIT_SRC})
177- include(ValaPrecompile)
178- vala_precompile(UNIT_SRC_C ${UNIT}
179- ${UNIT_SRC}
180+ endforeach()
181+ if (SOURCE_VALA)
182+ vala_precompile(SOURCE_C ${name}
183+ ${SOURCE_VALA}
184 PACKAGES
185 ${PKGS}
186 OPTIONS
187- ${VALAFLAGS}
188- --use-header="${CMAKE_PROJECT_NAME}-core.h"
189+ ${VALAFLAGS}
190 GENERATE_HEADER
191- ${UNIT}
192+ ${name}
193 CUSTOM_VAPIS
194- ${EXTRA_VAPIS}
195+ ${EXTRA_VAPIS}
196 "${CMAKE_SOURCE_DIR}/midori/midori.vapi"
197 "${CMAKE_BINARY_DIR}/midori/${LIBMIDORI}.vapi"
198 )
199- add_library(${UNIT} MODULE ${UNIT_SRC_C})
200- target_link_libraries(${UNIT}
201+ set(source ${SOURCE_C})
202+ endif ()
203+ if (source)
204+ add_library(${name} MODULE ${source})
205+ target_link_libraries(${name}
206 ${LIBMIDORI}
207 )
208- set_target_properties(${UNIT} PROPERTIES
209- COMPILE_FLAGS "${VALA_CFLAGS}"
210- )
211- install(TARGETS ${UNIT}
212+ install(TARGETS ${name}
213 LIBRARY DESTINATION ${EXTENSIONDIR}
214 )
215+ if (SOURCE_VALA)
216+ # Extensions with Vala code get the lenient VALA_CFLAGS
217+ set_target_properties(${name} PROPERTIES
218+ COMPILE_FLAGS ${VALA_CFLAGS}
219+ )
220+ else ()
221+ set_target_properties(${name} PROPERTIES
222+ COMPILE_FLAGS ${CFLAGS}
223+ )
224+ endif ()
225+ # Optional unit test
226+ add_test(NAME "test-${name}" COMMAND $<TARGET_FILE:midori> -t $<TARGET_FILE:${name}>)
227+ contain_test("test-${name}" $<TARGET_FILE:midori> -t $<TARGET_FILE:${name}>)
228+ endif ()
229+endmacro(build_extension)
230+
231+foreach(UNIT_SRC ${EXTENSIONS})
232+ string(FIND ${UNIT_SRC} ".c" UNIT_EXTENSION)
233+ if (UNIT_EXTENSION GREATER -1)
234+ string(REPLACE ".c" "" UNIT ${UNIT_SRC})
235+ build_extension(${UNIT} ${UNIT_SRC})
236+ endif ()
237+
238+ string(FIND ${UNIT_SRC} "." UNIT_EXTENSION)
239+ if (UNIT_EXTENSION GREATER -1)
240+ file(GLOB UNIT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.c" "${UNIT_SRC}/*.vala")
241+ build_extension(${UNIT_SRC} ${UNIT_FILES})
242+ endif ()
243+
244+ string(FIND ${UNIT_SRC} ".vala" UNIT_EXTENSION)
245+ if (UNIT_EXTENSION GREATER -1)
246+ string(REPLACE ".vala" "" UNIT ${UNIT_SRC})
247+ build_extension(${UNIT} ${UNIT_SRC})
248 endif ()
249 endforeach ()
250
251=== modified file 'extensions/about.vala'
252--- extensions/about.vala 2015-06-11 22:33:48 +0000
253+++ extensions/about.vala 2015-06-22 22:20:28 +0000
254@@ -140,7 +140,12 @@
255 GLib.StringBuilder ns_plugins = new GLib.StringBuilder ();
256 view.list_plugins (ns_plugins, true);
257
258- /* TODO: list active extensions */
259+#if HAVE_PEAS
260+ ns_plugins.append_printf ("</table><h2>%s</h2><table>", _("Extensions"));
261+ var engine = Peas.Engine.get_default ();
262+ foreach (unowned Peas.PluginInfo info in engine.get_plugin_list ())
263+ ns_plugins.append_printf ("<tr><td>%s <em>%s</em></td></tr>\n", info.get_name (), info.get_module_name ());
264+#endif
265
266 this.load_html (view, contents.printf (
267 _("Version numbers in brackets show the version used at runtime."),
268
269=== added file 'extensions/example.py'
270--- extensions/example.py 1970-01-01 00:00:00 +0000
271+++ extensions/example.py 2015-06-22 22:20:28 +0000
272@@ -0,0 +1,14 @@
273+# -*- coding: utf-8 py-indent-offset: 4 -*-
274+from gi.repository import GObject, Gtk, Peas
275+import os, gettext
276+
277+class ExamplePlugin(GObject.Object, Peas.Activatable):
278+ __gtype_name__ = "ExamplePlugin"
279+ object = GObject.property(type=GObject.Object)
280+
281+ def __init__(self):
282+ print("Example init")
283+ GObject.Object.__init__(self)
284+
285+ def do_activate(self):
286+ print("Example %s" % (self.object.props.uri))
287
288=== added file 'extensions/examplepy.plugin'
289--- extensions/examplepy.plugin 1970-01-01 00:00:00 +0000
290+++ extensions/examplepy.plugin 2015-06-22 22:20:28 +0000
291@@ -0,0 +1,9 @@
292+[Plugin]
293+Loader=python
294+Module=example
295+IAge=3
296+Name=Example in Python
297+Name[de]=Beispiel in Python
298+Author=Christian Dywan <christian@twotoasts.de>
299+Copyright=Copyright © 2015 Christian Dywan
300+Website=http://www.midori-browser.org
301
302=== added file 'extensions/extension-manager.vala'
303--- extensions/extension-manager.vala 1970-01-01 00:00:00 +0000
304+++ extensions/extension-manager.vala 2015-06-22 22:20:28 +0000
305@@ -0,0 +1,273 @@
306+/*
307+ Copyright (C) 2008-2015 Christian Dywan <christian@twotoasts.de>
308+
309+ This library is free software; you can redistribute it and/or
310+ modify it under the terms of the GNU Lesser General Public
311+ License as published by the Free Software Foundation; either
312+ version 2.1 of the License, or (at your option) any later version.
313+
314+ See the file COPYING for the full license text.
315+*/
316+
317+namespace Extensions {
318+ public class Sidebar : Gtk.VBox, Midori.Viewable {
319+ Gtk.Toolbar? toolbar = null;
320+ Gtk.ListStore store = new Gtk.ListStore (1, typeof (GLib.Object));
321+ Gtk.TreeView treeview;
322+ Midori.App app;
323+
324+ void on_add_item (Katze.Array extensions, GLib.Object item) {
325+ var extension = (Midori.Extension)item;
326+ Gtk.TreeIter iter;
327+ store.append (out iter);
328+ store.set (iter, 0, extension);
329+ extension.activate.connect (on_activate);
330+ extension.deactivate.connect (on_deactivate);
331+ }
332+
333+ void on_activate (Midori.Extension extension, Midori.App app) {
334+ treeview.queue_draw ();
335+ }
336+
337+ void on_deactivate (Midori.Extension extension) {
338+ treeview.queue_draw ();
339+ }
340+
341+ public unowned string get_stock_id () {
342+ return Midori.Stock.EXTENSION;
343+ }
344+
345+ public unowned string get_label () {
346+ return _("Extensions");
347+ }
348+
349+ public Gtk.Widget get_toolbar () {
350+ if (toolbar == null) {
351+ toolbar = new Gtk.Toolbar ();
352+ toolbar.set_icon_size (Gtk.IconSize.BUTTON);
353+ }
354+ return toolbar;
355+ }
356+
357+ internal Sidebar (Midori.App app) {
358+ Gtk.TreeViewColumn column;
359+
360+ treeview = new Gtk.TreeView.with_model (store);
361+ treeview.button_press_event.connect (on_button_pressed);
362+ store.set_sort_column_id (0, Gtk.SortType.ASCENDING);
363+ store.set_sort_func (0, tree_sort_func);
364+ treeview.headers_visible = false;
365+
366+ column = new Gtk.TreeViewColumn ();
367+ Gtk.CellRendererToggle renderer_toggle = new Gtk.CellRendererToggle ();
368+ column.pack_start (renderer_toggle, false);
369+ column.set_cell_data_func (renderer_toggle, on_render_tick);
370+ renderer_toggle.toggled.connect (on_renderer_toggled);
371+ treeview.append_column (column);
372+
373+ column = new Gtk.TreeViewColumn ();
374+ Gtk.CellRendererPixbuf renderer_icon = new Gtk.CellRendererPixbuf ();
375+ column.pack_start (renderer_icon, false);
376+ column.set_cell_data_func (renderer_icon, on_render_icon);
377+ treeview.append_column (column);
378+
379+ column = new Gtk.TreeViewColumn ();
380+ column.set_sizing (Gtk.TreeViewColumnSizing.AUTOSIZE);
381+ Gtk.CellRendererText renderer_text = new Gtk.CellRendererText ();
382+ column.pack_start (renderer_text, true);
383+ column.set_expand (true);
384+ column.set_cell_data_func (renderer_text, on_render_text);
385+ treeview.append_column (column);
386+
387+ column = new Midori.ExtensionsColumn ();
388+ (column as Midori.ExtensionsColumn).row_clicked.connect (on_preferences_clicked);
389+ Gtk.CellRendererPixbuf renderer_preferences = new Gtk.CellRendererPixbuf ();
390+ column.pack_start (renderer_preferences, false);
391+ column.set_sizing (Gtk.TreeViewColumnSizing.FIXED);
392+ column.set_fixed_width (30);
393+ column.set_cell_data_func (renderer_preferences, on_render_preferences);
394+ treeview.append_column (column);
395+ treeview.row_activated.connect (on_row_activated);
396+
397+ treeview.show ();
398+ pack_start (treeview, true, true, 0);
399+ assert (treeview.get_n_columns () > 0);
400+
401+ Katze.Array extensions = app.extensions;
402+ extensions.add_item.connect (on_add_item);
403+ foreach (GLib.Object extension in extensions.get_items ())
404+ on_add_item (extensions, extension);
405+
406+ this.app = app;
407+
408+#if HAVE_PEAS
409+ var engine = Peas.Engine.get_default ();
410+ engine.rescan_plugins ();
411+ foreach (unowned Peas.PluginInfo info in engine.get_plugin_list ()) {
412+ var extension = (Midori.Extension)GLib.Object.new (typeof (Midori.Extension),
413+ name: info.get_name (),
414+ description: info.get_description (),
415+ version: info.get_version () + Midori.VERSION_SUFFIX,
416+ website: info.get_website (),
417+ authors: string.joinv (",", info.get_authors ()));
418+ extension.set_data<string?> ("filename", info.get_module_name ());
419+ extension.activate.connect ((app) => { engine.try_load_plugin (info); });
420+ extension.deactivate.connect (() => { engine.try_unload_plugin (info); });
421+ extensions.add_item (extension);
422+ }
423+#endif
424+ }
425+
426+ int tree_sort_func (Gtk.TreeModel model, Gtk.TreeIter a, Gtk.TreeIter b) {
427+ Midori.Extension e1, e2;
428+ model.get (a, 0, out e1);
429+ model.get (b, 0, out e2);
430+ return strcmp (e1.name, e2.name);
431+ }
432+
433+ bool on_button_pressed (Gtk.Widget widget, Gdk.EventButton event) {
434+ bool ret = false;
435+ Gtk.TreePath path;
436+ Gtk.TreeViewColumn column;
437+ if (treeview.get_path_at_pos ((int)event.x, (int)event.y, out path, out column, null, null)) {
438+ if (path != null) {
439+ if (column is Midori.ExtensionsColumn) {
440+ uint signal_id = Signal.lookup ("row-clicked", typeof (Midori.ExtensionsColumn));
441+ if (signal_id > 0 && Signal.has_handler_pending (column, signal_id, 0, false)) {
442+ (column as Midori.ExtensionsColumn).row_clicked (treeview, path);
443+ ret = true;
444+ }
445+ }
446+ }
447+ }
448+ return ret;
449+ }
450+
451+ void on_renderer_toggled (Gtk.CellRendererToggle renderer, string path) {
452+ Gtk.TreeIter iter;
453+ if (store.get_iter_from_string (out iter, path)) {
454+ Midori.Extension extension;
455+ store.get (iter, 0, out extension);
456+ if (extension.is_active ())
457+ extension.deactivate ();
458+ else if (extension.is_prepared ())
459+ extension.activate (app);
460+ /* Make it easy for listeners to see that extensions changed */
461+ app.extensions.update ();
462+ }
463+ }
464+
465+ void on_render_tick (Gtk.CellLayout column, Gtk.CellRenderer renderer,
466+ Gtk.TreeModel model, Gtk.TreeIter iter) {
467+
468+ Midori.Extension extension;
469+ model.get (iter, 0, out extension);
470+ renderer.set ("activatable", extension.is_prepared (),
471+ "active", extension.is_active ()
472+ || extension.get_data<string>("static") != null,
473+ "xpad", 4);
474+ }
475+
476+ void on_render_icon (Gtk.CellLayout column, Gtk.CellRenderer renderer,
477+ Gtk.TreeModel model, Gtk.TreeIter iter) {
478+
479+ Midori.Extension extension;
480+ model.get (iter, 0, out extension);
481+ renderer.set ("stock-id", Midori.Stock.EXTENSION,
482+ "stock-size", Gtk.IconSize.BUTTON,
483+ "sensitive", extension.is_prepared (),
484+ "xpad", 4);
485+ }
486+
487+ void on_render_text (Gtk.CellLayout column, Gtk.CellRenderer renderer,
488+ Gtk.TreeModel model, Gtk.TreeIter iter) {
489+
490+ Midori.Extension extension;
491+ model.get (iter, 0, out extension);
492+ renderer.set ("markup", Markup.printf_escaped ("<b>%s</b> %s\n%s",
493+ extension.name, extension.version ?? "", extension.description),
494+ "ellipsize", Pango.EllipsizeMode.END,
495+ "sensitive", extension.is_prepared ());
496+ }
497+
498+ void on_render_preferences (Gtk.CellLayout column, Gtk.CellRenderer renderer,
499+ Gtk.TreeModel model, Gtk.TreeIter iter) {
500+
501+ Midori.Extension extension;
502+ model.get (iter, 0, out extension);
503+ renderer.set ("stock-id", Gtk.Stock.PREFERENCES,
504+ "stock-size", Gtk.IconSize.BUTTON,
505+ "visible", extension.has_preferences (),
506+ "sensitive", extension.is_active (),
507+ "xpad", 4);
508+ }
509+
510+ void on_preferences_clicked (Gtk.TreeView treeview, Gtk.TreePath path) {
511+ Gtk.TreeIter iter;
512+ if (store.get_iter (out iter, path)) {
513+ Midori.Extension extension;
514+ store.get (iter, 0, out extension);
515+ if (extension.is_active ())
516+ extension.open_preferences ();
517+ }
518+ }
519+
520+ void on_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) {
521+ Gtk.TreeIter iter;
522+ if (store.get_iter (out iter, path)) {
523+ Midori.Extension extension;
524+ store.get (iter, 0, out extension);
525+ if (extension.is_active ())
526+ extension.deactivate ();
527+ else if (extension.is_prepared ())
528+ extension.activate (app);
529+ /* Make it easy for listeners to see that extensions changed */
530+ app.extensions.update ();
531+ }
532+ }
533+ }
534+
535+ class Manager : Midori.Extension {
536+ void activated (Midori.App app) {
537+ foreach (var browser in app.get_browsers ())
538+ browser_added (browser);
539+ app.add_browser.connect (browser_added);
540+ }
541+
542+ void browser_added (Midori.Browser browser) {
543+ browser.show_preferences.connect (show_preferences);
544+ }
545+
546+ void show_preferences (Katze.Preferences preferences) {
547+ /* Check for new extensions */
548+ Midori.Extension.load_from_folder (get_app (), null, false);
549+ /* Hide if there are no extensions at all */
550+ if (get_app ().extensions.is_empty ())
551+ return;
552+ /* Reset frozen list: allow active extensions to be saved */
553+ get_app ().set_data<string[]?> ("extensions", null);
554+
555+ var viewable = new Sidebar (get_app ());
556+ viewable.show ();
557+ var scrolled = new Gtk.ScrolledWindow (null, null);
558+ /* For lack of a better way of keeping descriptions visible */
559+ scrolled.show ();
560+ scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
561+ viewable.get_children ().nth_data (0).reparent (scrolled);
562+ var category = preferences.add_category (_("Extensions"), Midori.Stock.EXTENSION);
563+ category.pack_start (scrolled, true, true, 0);
564+ }
565+
566+ internal Manager () {
567+ GLib.Object (name: "Extension Manager",
568+ description: "Manage your extensions",
569+ version: "0.2" + Midori.VERSION_SUFFIX,
570+ authors: "Christian Dywan <christian@twotoasts.de>");
571+ activate.connect (activated);
572+ }
573+ }
574+}
575+
576+public Midori.Extension extension_init () {
577+ return new Extensions.Manager ();
578+}
579
580=== added file 'extensions/hsts.web.plugin'
581--- extensions/hsts.web.plugin 1970-01-01 00:00:00 +0000
582+++ extensions/hsts.web.plugin 2015-06-22 22:20:28 +0000
583@@ -0,0 +1,8 @@
584+[Plugin]
585+Module=hsts_web_hsts_web
586+IAge=3
587+Name=HSTS
588+Description=HTTP Strict Transport Security
589+Author=Christian Dywan <christian@twotoasts.de>
590+Copyright=Copyright © 2015 Christian Dywan
591+Website=http://www.midori-browser.org
592
593=== added file 'extensions/hsts.web.vala'
594--- extensions/hsts.web.vala 1970-01-01 00:00:00 +0000
595+++ extensions/hsts.web.vala 2015-06-22 22:20:28 +0000
596@@ -0,0 +1,176 @@
597+/*
598+ Copyright (C) 2012-2014 Christian Dywan <christian@twotoasts.de>
599+
600+ This library is free software; you can redistribute it and/or
601+ modify it under the terms of the GNU Lesser General Public
602+ License as published by the Free Software Foundation; either
603+ version 2.1 of the License, or (at your option) any later version.
604+
605+ See the file COPYING for the full license text.
606+*/
607+
608+namespace HSTS {
609+ public class Directive {
610+ public Soup.Date? expires = null;
611+ public bool sub_domains = false;
612+
613+ public Directive (bool include_sub_domains) {
614+ expires = new Soup.Date.from_now (int.MAX);
615+ sub_domains = include_sub_domains;
616+ }
617+
618+ public Directive.from_header (string header) {
619+ var param_list = Soup.header_parse_param_list (header);
620+ if (param_list == null)
621+ return;
622+
623+ string? max_age = param_list.lookup ("max-age");
624+ if (max_age != null)
625+ expires = new Soup.Date.from_now (max_age.to_int ());
626+ if ("includeSubDomains" in header)
627+ sub_domains = true;
628+ Soup.header_free_param_list (param_list);
629+ }
630+
631+ public bool is_valid () {
632+ return expires != null && !expires.is_past ();
633+ }
634+ }
635+
636+ public class Whitelist : Object {
637+ HashTable<string, Directive> whitelist;
638+ string preset = "/etc/xdg/midori/hsts";
639+ File config;
640+
641+ public Whitelist () {
642+ whitelist = new HashTable<string, Directive> (str_hash, str_equal);
643+ read_cache.begin (File.new_for_path (preset));
644+ // FIXME: config = File.new_for_path (Midori.Paths.get_config_filename_for_writing ("hsts"));
645+ string config_dir = Path.build_path (Path.DIR_SEPARATOR_S,
646+ Environment.get_user_config_dir (), "midori");
647+ config = File.new_for_path (Path.build_path (Path.DIR_SEPARATOR_S, config_dir, "hsts"));
648+ read_cache.begin (config);
649+ }
650+
651+ async void read_cache (File file) {
652+ try {
653+ var stream = new DataInputStream (yield file.read_async ());
654+ do {
655+ string? line = yield stream.read_line_async ();
656+ if (line == null)
657+ break;
658+ string[] parts = line.split (" ", 2);
659+ if (parts[0] == null || parts[1] == null)
660+ break;
661+ var directive = new Directive.from_header (parts[1]);
662+ if (directive.is_valid ())
663+ append_to_whitelist (parts[0], directive);
664+ } while (true);
665+ } catch (IOError.NOT_FOUND exist_error) {
666+ /* It's no error if no cache file exists */
667+ } catch (Error error) {
668+ warning ("Failed to read cache %s: %s", file.get_path (), error.message);
669+ }
670+ }
671+
672+ public bool should_secure_host (string host) {
673+ Directive? directive = whitelist.lookup (host);
674+ if (directive == null)
675+ directive = whitelist.lookup ("*." + host);
676+ return directive != null && directive.is_valid ();
677+ }
678+
679+ void append_to_whitelist (string host, Directive directive) {
680+ whitelist.insert (host, directive);
681+ if (directive.sub_domains)
682+ whitelist.insert ("*." + host, directive);
683+ }
684+
685+ async void append_to_cache (string host, string header) {
686+ /* FIXME: Don't write in private browsing */
687+
688+ try {
689+ var stream = yield config.append_to_async (FileCreateFlags.NONE);
690+ yield stream.write_async ((host + " " + header + "\n").data);
691+ yield stream.flush_async ();
692+ }
693+ catch (Error error) {
694+ critical ("Failed to update %s: %s", config.get_path (), error.message);
695+ }
696+ }
697+
698+ public Directive? strict_transport_security_handled (string host, Soup.MessageHeaders headers) {
699+ unowned string? hsts = headers.get_one ("Strict-Transport-Security");
700+ if (hsts == null)
701+ return null;
702+
703+ var directive = new Directive.from_header (hsts);
704+ if (directive.is_valid ()) {
705+ append_to_whitelist (host, directive);
706+ append_to_cache.begin (host, hsts);
707+ }
708+ return directive;
709+ }
710+
711+ }
712+
713+ public class WebPage : Peas.ExtensionBase, Midori.WebPageActivatable {
714+ Whitelist whitelist;
715+ bool debug = false;
716+
717+ public WebKit.WebPage web_page { owned get; set; }
718+
719+ construct {
720+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "hsts") == 0)
721+ debug = true;
722+ whitelist = new Whitelist ();
723+ }
724+
725+ public void document_loaded (WebKit.DOM.Document dom_document) {
726+ }
727+
728+ public bool send_request (WebKit.URIRequest request, WebKit.URIResponse? redirected_response) {
729+ Soup.MessageHeaders? headers = request.get_http_headers ();
730+ if (headers == null || !request.uri.contains ("/"))
731+ return false;
732+
733+ string host = request.uri.split ("/")[2];
734+ if (whitelist.should_secure_host (host)) {
735+ request.uri = request.uri.replace ("http://", "https://");
736+ if (debug)
737+ stdout.printf ("HSTS: Enforce %s\n", host);
738+ } else if (request.uri.has_prefix ("http://")) {
739+ var directive = whitelist.strict_transport_security_handled (host, headers);
740+ if (debug)
741+ stdout.printf ("HSTS: %s valid? %s\n",
742+ host, directive != null ? directive.is_valid ().to_string () : "/");
743+ }
744+ return false;
745+ }
746+ }
747+}
748+
749+[ModuleInit]
750+public static void peas_register_types (GLib.TypeModule module) {
751+ var object_module = (Peas.ObjectModule)module;
752+ object_module.register_extension_type (typeof (Midori.WebPageActivatable), typeof (HSTS.WebPage));
753+}
754+
755+void hsts_directive () {
756+ HSTS.Directive d;
757+ d = new HSTS.Directive.from_header ("max-age=31536000");
758+ assert (d.is_valid () && !d.sub_domains);
759+ d = new HSTS.Directive.from_header ("max-age=15768000 ; includeSubDomains");
760+ assert (d.is_valid () && d.sub_domains);
761+
762+ /* Invalid */
763+ d = new HSTS.Directive.from_header ("");
764+ assert (!d.is_valid () && !d.sub_domains);
765+ d = new HSTS.Directive.from_header ("includeSubDomains");
766+ assert (!d.is_valid () && d.sub_domains);
767+}
768+
769+public void extension_test () {
770+ Test.add_func ("/hsts/directive", hsts_directive);
771+}
772+
773
774=== removed file 'extensions/tabs-minimized.c'
775--- extensions/tabs-minimized.c 2011-11-08 00:53:53 +0000
776+++ extensions/tabs-minimized.c 1970-01-01 00:00:00 +0000
777@@ -1,87 +0,0 @@
778-/*
779- Copyright (C) 2008-2010 Christian Dywan <christian@twotoasts.de>
780-
781- This library is free software; you can redistribute it and/or
782- modify it under the terms of the GNU Lesser General Public
783- License as published by the Free Software Foundation; either
784- version 2.1 of the License, or (at your option) any later version.
785-
786- See the file COPYING for the full license text.
787-*/
788-
789-#include <midori/midori.h>
790-
791-static void
792-tabs_minimized_app_add_browser_cb (MidoriApp* app,
793- MidoriBrowser* browser,
794- MidoriExtension* extension);
795-
796-static void
797-tabs_minimized_add_tab_cb (MidoriBrowser* browser,
798- MidoriView* tab,
799- MidoriExtension* extension);
800-
801-static void
802-tabs_minimized_deactivate_cb (MidoriExtension* extension,
803- MidoriBrowser* browser)
804-{
805- MidoriApp* app = midori_extension_get_app (extension);
806-
807- g_signal_handlers_disconnect_by_func (
808- extension, tabs_minimized_deactivate_cb, browser);
809- g_signal_handlers_disconnect_by_func (
810- app, tabs_minimized_app_add_browser_cb, extension);
811- g_signal_handlers_disconnect_by_func (
812- browser, tabs_minimized_add_tab_cb, extension);
813-}
814-
815-static void
816-tabs_minimized_add_tab_cb (MidoriBrowser* browser,
817- MidoriView* tab,
818- MidoriExtension* extension)
819-{
820- g_object_set (tab, "minimized", TRUE, NULL);
821-}
822-
823-static void
824-tabs_minimized_app_add_browser_cb (MidoriApp* app,
825- MidoriBrowser* browser,
826- MidoriExtension* extension)
827-{
828- g_signal_connect (browser, "add-tab",
829- G_CALLBACK (tabs_minimized_add_tab_cb), extension);
830- g_signal_connect (extension, "deactivate",
831- G_CALLBACK (tabs_minimized_deactivate_cb), browser);
832-}
833-
834-static void
835-tabs_minimized_activate_cb (MidoriExtension* extension,
836- MidoriApp* app)
837-{
838- KatzeArray* browsers;
839- MidoriBrowser* browser;
840-
841- browsers = katze_object_get_object (app, "browsers");
842- KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
843- tabs_minimized_app_add_browser_cb (app, browser, extension);
844- g_object_unref (browsers);
845- g_signal_connect (app, "add-browser",
846- G_CALLBACK (tabs_minimized_app_add_browser_cb), extension);
847-}
848-
849-MidoriExtension*
850-extension_init (void)
851-{
852- MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
853- "name", _("Only Icons on Tabs by default"),
854- "description", _("New tabs have no label by default"),
855- "version", "0.1" MIDORI_VERSION_SUFFIX,
856- "authors", "MonkeyOfDoom <pixelmonkey@ensellitis.com>",
857- NULL);
858-
859- g_signal_connect (extension, "activate",
860- G_CALLBACK (tabs_minimized_activate_cb), NULL);
861-
862- return extension;
863-}
864-
865
866=== added file 'extensions/tabs-minimized.plugin'
867--- extensions/tabs-minimized.plugin 1970-01-01 00:00:00 +0000
868+++ extensions/tabs-minimized.plugin 2015-06-22 22:20:28 +0000
869@@ -0,0 +1,9 @@
870+[Plugin]
871+Module=tabs-minimized
872+IAge=3
873+Name=Only Icons on Tabs by default
874+Description=New tabs have no label by default
875+Version=0.1
876+Author=MonkeyOfDoom <pixelmonkey@ensellitis.com>
877+Copyright=Copyright © 2008-2010 Christian Dywan
878+Website=http://www.midori-browser.org
879
880=== added file 'extensions/tabs-minimized.vala'
881--- extensions/tabs-minimized.vala 1970-01-01 00:00:00 +0000
882+++ extensions/tabs-minimized.vala 2015-06-22 22:20:28 +0000
883@@ -0,0 +1,68 @@
884+/*
885+ Copyright (C) 2008-2010 Christian Dywan <christian@twotoasts.de>
886+
887+ This library is free software; you can redistribute it and/or
888+ modify it under the terms of the GNU Lesser General Public
889+ License as published by the Free Software Foundation; either
890+ version 2.1 of the License, or (at your option) any later version.
891+
892+ See the file COPYING for the full license text.
893+*/
894+
895+namespace Minimizer {
896+ class Manager : Midori.Extension {
897+ internal Manager () {
898+ GLib.Object (name: _("Only Icons on Tabs by default"),
899+ description: _("New tabs have no label by default"),
900+ version: "0.1" + Midori.VERSION_SUFFIX,
901+ authors: "MonkeyOfDoom <pixelmonkey@ensellitis.com>");
902+ activate.connect (activated);
903+ deactivate.connect (deactivated);
904+ }
905+
906+ void activated (Midori.App app) {
907+ foreach (var browser in app.get_browsers ())
908+ browser_added (browser);
909+ app.add_browser.connect (browser_added);
910+ }
911+
912+ void deactivated () {
913+ var app = get_app ();
914+ app.add_browser.disconnect (browser_added);
915+ foreach (var browser in app.get_browsers ())
916+ browser.add_tab.disconnect (tab_added);
917+ }
918+
919+ void browser_added (Midori.Browser browser) {
920+ browser.add_tab.connect (tab_added);
921+ foreach (var tab in browser.get_tabs ())
922+ tab_added (tab);
923+ }
924+
925+ void tab_added (Midori.Tab tab) {
926+ tab.minimized = true;
927+ }
928+ }
929+}
930+
931+public Midori.Extension extension_init () {
932+ return new Minimizer.Manager ();
933+}
934+
935+#if HAVE_PEAS
936+namespace Minimizer {
937+ public class Tab : Peas.ExtensionBase, Midori.TabActivatable {
938+ public Midori.Tab tab { owned get; set; }
939+
940+ public void created (string uri) {
941+ tab.minimized = true;
942+ }
943+ }
944+}
945+
946+[ModuleInit]
947+public static void peas_register_types (GLib.TypeModule module) {
948+ var object_module = (Peas.ObjectModule)module;
949+ object_module.register_extension_type (typeof (Midori.TabActivatable), typeof (Minimizer.Tab));
950+}
951+#endif
952
953=== added file 'extensions/web-extension.web.vala'
954--- extensions/web-extension.web.vala 1970-01-01 00:00:00 +0000
955+++ extensions/web-extension.web.vala 2015-06-22 22:20:28 +0000
956@@ -0,0 +1,68 @@
957+/*
958+ Copyright (C) 2015 Christian Dywan <christian@twotoasts.de>
959+
960+ This library is free software; you can redistribute it and/or
961+ modify it under the terms of the GNU Lesser General Public
962+ License as published by the Free Software Foundation; either
963+ version 2.1 of the License, or (at your option) any later version.
964+
965+ See the file COPYING for the full license text.
966+*/
967+
968+namespace WebExtension {
969+ public class Extension : Object {
970+ bool debug = false;
971+ Peas.Engine engine;
972+
973+ public Extension (WebKit.WebExtension web_extension, GLib.Variant user_data) {
974+ debug = (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0);
975+ if (debug)
976+ stdout.printf ("WebKit.WebExtension: %s\n", user_data.print (true));
977+ var config = (GLib.HashTable<string, string>)user_data;
978+ var keyfile = new GLib.KeyFile ();
979+ try {
980+ keyfile.load_from_file (config["config_dir"] + "/config", GLib.KeyFileFlags.NONE);
981+ string plugins = keyfile.get_string ("settings", "plugins");
982+
983+ engine = Peas.Engine.get_default ();
984+ engine.enable_loader ("python");
985+ foreach (unowned string path in config["plugin_dirs"].split (","))
986+ engine.add_search_path (path, null);
987+ engine.loaded_plugins = plugins.split (",");
988+
989+ web_extension.page_created.connect (page_created);
990+ } catch (GLib.Error error) {
991+ // Missing config file or plugins key is no error
992+ }
993+ }
994+
995+ void page_created (WebKit.WebPage web_page) {
996+ var extensions = new Peas.ExtensionSet (null,
997+ typeof (Midori.WebPageActivatable), "web-page", web_page);
998+ web_page.set_data<Peas.ExtensionSet> ("extensions", extensions);
999+ web_page.send_request.connect (send_request);
1000+ }
1001+
1002+ public void document_loaded (WebKit.WebPage web_page) {
1003+ var extensions = web_page.get_data<Peas.ExtensionSet> ("extensions");
1004+ extensions.foreach ((@set, info, extension) => {
1005+ ((Midori.WebPageActivatable)extension).document_loaded (web_page.get_dom_document ());
1006+ });
1007+ }
1008+
1009+ bool send_request (WebKit.WebPage web_page, WebKit.URIRequest request, WebKit.URIResponse? redirected_response) {
1010+ bool block = false;
1011+ var extensions = web_page.get_data<Peas.ExtensionSet> ("extensions");
1012+ extensions.foreach ((@set, info, extension) => {
1013+ if (((Midori.WebPageActivatable)extension).send_request (request, redirected_response))
1014+ block = true;
1015+ });
1016+ return block;
1017+ }
1018+ }
1019+}
1020+
1021+WebExtension.Extension? web_extension;
1022+public void webkit_web_extension_initialize_with_user_data (WebKit.WebExtension extension, GLib.Variant user_data) {
1023+ web_extension = new WebExtension.Extension (extension, user_data);
1024+}
1025
1026=== added directory 'ipc'
1027=== added file 'ipc/CMakeLists.txt'
1028--- ipc/CMakeLists.txt 1970-01-01 00:00:00 +0000
1029+++ ipc/CMakeLists.txt 2015-06-22 22:20:28 +0000
1030@@ -0,0 +1,50 @@
1031+include(ValaPrecompile)
1032+
1033+set(LIBMIDORI2_VERSION 0.6.0)
1034+set(LIBMIDORI2_SOVERSION 0)
1035+file(GLOB LIBMIDORI2_SOURCE *.vala)
1036+
1037+vala_precompile(LIBMIDORI2_SOURCE_C ${LIBMIDORI2}
1038+ ${LIBMIDORI2_SOURCE}
1039+PACKAGES
1040+ ${PKGS}
1041+CUSTOM_VAPIS
1042+ "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-web-extension-4.0.vapi"
1043+OPTIONS
1044+ ${VALAFLAGS}
1045+GENERATE_VAPI
1046+ "${LIBMIDORI2}"
1047+GENERATE_HEADER
1048+ "${LIBMIDORI2}"
1049+)
1050+
1051+add_library("${LIBMIDORI2}" SHARED ${LIBMIDORI2_SOURCE_C})
1052+target_link_libraries("${LIBMIDORI2}"
1053+ ${DEPS_LIBRARIES}
1054+ ${PEAS_LIBRARIES}
1055+ )
1056+set_target_properties("${LIBMIDORI2}" PROPERTIES
1057+ COMPILE_FLAGS "${VALA_CFLAGS}"
1058+ POSITION_INDEPENDENT_CODE ON
1059+ VERSION ${LIBMIDORI2_VERSION}
1060+ SOVERSION ${LIBMIDORI2_SOVERSION}
1061+ )
1062+
1063+include_directories(
1064+ ${CMAKE_SOURCE_DIR}
1065+ ${CMAKE_CURRENT_SOURCE_DIR}
1066+ ${CMAKE_BINARY_DIR}
1067+ ${DEPS_INCLUDE_DIRS}
1068+ ${OPTS_INCLUDE_DIRS}
1069+ ${DEPS_GTK_INCLUDE_DIRS}
1070+ )
1071+if (WIN32)
1072+ install(TARGETS ${LIBMIDORI2}
1073+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR}
1074+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
1075+ )
1076+else ()
1077+ install(TARGETS ${LIBMIDORI2}
1078+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1079+ )
1080+endif ()
1081
1082=== added file 'ipc/ipc-tab.vala'
1083--- ipc/ipc-tab.vala 1970-01-01 00:00:00 +0000
1084+++ ipc/ipc-tab.vala 2015-06-22 22:20:28 +0000
1085@@ -0,0 +1,19 @@
1086+/*
1087+ Copyright (C) 2015 Christian Dywan <christian@twotoasts.de>
1088+
1089+ This library is free software; you can redistribute it and/or
1090+ modify it under the terms of the GNU Lesser General Public
1091+ License as published by the Free Software Foundation; either
1092+ version 2.1 of the License, or (at your option) any later version.
1093+
1094+ See the file COPYING for the full license text.
1095+*/
1096+
1097+namespace Midori {
1098+ public interface WebPageActivatable : GLib.Object {
1099+ public abstract WebKit.WebPage web_page { owned get; set; }
1100+
1101+ public abstract void document_loaded (WebKit.DOM.Document dom_document);
1102+ public abstract bool send_request (WebKit.URIRequest request, WebKit.URIResponse? redirected_response);
1103+ }
1104+}
1105
1106=== modified file 'katze/katze.vapi'
1107--- katze/katze.vapi 2014-02-22 14:06:19 +0000
1108+++ katze/katze.vapi 2015-06-22 22:20:28 +0000
1109@@ -21,6 +21,7 @@
1110 public uint get_length ();
1111 public GLib.List<unowned Item> get_items ();
1112 public bool is_empty ();
1113+ public void update ();
1114 }
1115
1116 [CCode (cheader_filename = "katze/katze.h")]
1117
1118=== modified file 'katze/midori-paths.vala'
1119--- katze/midori-paths.vala 2015-06-11 22:33:48 +0000
1120+++ katze/midori-paths.vala 2015-06-22 22:20:28 +0000
1121@@ -99,6 +99,7 @@
1122
1123 public static void init (RuntimeMode new_mode, string? config) {
1124 assert (mode == RuntimeMode.UNDEFINED);
1125+ assert (exec_path != null);
1126 assert (new_mode != RuntimeMode.UNDEFINED);
1127 mode = new_mode;
1128 if (mode == RuntimeMode.PORTABLE || mode == RuntimeMode.PRIVATE)
1129@@ -147,17 +148,48 @@
1130 user_data_dir = Environment.get_user_data_dir ();
1131 tmp_dir = get_runtime_dir ();
1132 }
1133+
1134+#if HAVE_PEAS
1135+ var paths = new GLib.StringBuilder ();
1136+ paths.append (Path.build_filename (user_data_dir, PACKAGE_NAME, "plugins"));
1137+ paths.append_c (',');
1138+ paths.append (Path.build_filename (get_lib_path (PACKAGE_NAME)));
1139+ string plugin_dirs = paths.str;
1140+
1141+ var engine = Peas.Engine.get_default ();
1142+ engine.ref ();
1143+ engine.load_plugin.connect ((info) => {
1144+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0)
1145+ stdout.printf ("Plugin %s loaded (%s)\n", info.get_name (), info.get_module_name ());
1146+ });
1147+ engine.enable_loader ("python");
1148+ foreach (unowned string path in plugin_dirs.split (","))
1149+ engine.add_search_path (path, null);
1150+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
1151+ stdout.printf ("plugins: %s\n", plugin_dirs);
1152+ foreach (unowned Peas.PluginInfo info in engine.get_plugin_list ())
1153+ stdout.printf ("Plugin %s (%s)\n", info.get_name (), info.get_module_name ());
1154+ }
1155+#endif
1156+
1157 #if HAVE_WEBKIT2
1158+ var context = WebKit.WebContext.get_default ();
1159+#if HAVE_PEAS
1160+ context.set_web_extensions_directory (get_lib_path (PACKAGE_NAME));
1161+ context.initialize_web_extensions.connect (() => {
1162+ var user_data = new GLib.HashTable<string, string> (str_hash, str_equal);
1163+ user_data.insert ("config_dir", config_dir);
1164+ user_data.insert ("plugin_dirs", plugin_dirs);
1165+ context.set_web_extensions_initialization_user_data (user_data);
1166+ });
1167+#endif
1168 if (cache_dir != null) {
1169- /* Cache and extension dir MUST be set no later than here to work */
1170- WebKit.WebContext.get_default ().set_web_extensions_directory (
1171- Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "wk2ext"));
1172- WebKit.WebContext.get_default ().set_disk_cache_directory (
1173+ context.set_disk_cache_directory (
1174 Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "web"));
1175 }
1176
1177 if (config_dir != null) {
1178- var cookie_manager = WebKit.WebContext.get_default ().get_cookie_manager ();
1179+ var cookie_manager = context.get_cookie_manager ();
1180 cookie_manager.set_persistent_storage (Path.build_filename (config_dir, "cookies.db"),
1181 WebKit.CookiePersistentStorage.SQLITE);
1182 }
1183@@ -165,7 +197,7 @@
1184 if (user_data_dir != null) {
1185 string folder = Path.build_filename (user_data_dir, "webkit", "icondatabase");
1186 #if HAVE_WEBKIT2
1187- WebKit.WebContext.get_default ().set_favicon_database_directory (folder);
1188+ context.set_favicon_database_directory (folder);
1189 #else
1190 WebKit.get_favicon_database ().set_path (folder);
1191 #endif
1192
1193=== modified file 'midori/main.c'
1194--- midori/main.c 2014-04-23 03:34:23 +0000
1195+++ midori/main.c 2015-06-22 22:20:28 +0000
1196@@ -62,6 +62,7 @@
1197 gchar* config;
1198 gboolean private;
1199 gboolean portable;
1200+ gchar* test;
1201 gboolean plain;
1202 gboolean diagnostic_dialog = FALSE;
1203 gboolean debug = FALSE;
1204@@ -85,6 +86,8 @@
1205 { "portable", 'P', 0, G_OPTION_ARG_NONE, &portable,
1206 N_("Portable mode, all runtime files are stored in one place"), NULL },
1207 #endif
1208+ { "test", 't', 0, G_OPTION_ARG_STRING, &test,
1209+ N_("Run unit tests for the specified extension"), NULL },
1210 { "plain", '\0', 0, G_OPTION_ARG_NONE, &plain,
1211 N_("Plain GTK+ window with WebKit, akin to GtkLauncher"), NULL },
1212 { "diagnostic-dialog", 'd', 0, G_OPTION_ARG_NONE, &diagnostic_dialog,
1213@@ -118,6 +121,7 @@
1214 config = NULL;
1215 private = FALSE;
1216 portable = FALSE;
1217+ test = NULL;
1218 plain = FALSE;
1219 run = FALSE;
1220 snapshot = NULL;
1221@@ -287,6 +291,52 @@
1222 return 0;
1223 }
1224
1225+ if (test != NULL)
1226+ {
1227+ g_assert (g_module_supported ());
1228+
1229+ GModule* module = g_module_open (test, G_MODULE_BIND_LOCAL);
1230+ if (module == NULL)
1231+ g_error (_("Failed to load %s."), test);
1232+
1233+ midori_test_init (&argc, &argv);
1234+
1235+ typedef void (*extension_test_func)(void);
1236+ extension_test_func extension_test;
1237+ /* Midori.Extension */
1238+ typedef GObject* (*extension_init_func)(void);
1239+ extension_init_func extension_init;
1240+ /* WebKit.WebExtension */
1241+ typedef void (*webkit_web_extension_initialize_func)(GObject* extension);
1242+ webkit_web_extension_initialize_func web_extension_init;
1243+
1244+ if (g_module_symbol (module, "extension_init",
1245+ (gpointer) &extension_init))
1246+ {
1247+ /* It's fine to conditionally return no extension */
1248+ if (!(extension_init ()))
1249+ return 0;
1250+ midori_paths_init (MIDORI_RUNTIME_MODE_NORMAL, NULL);
1251+
1252+ /* Not all extensions have unit tests :-( */
1253+ if (!g_module_symbol (module, "extension_test", (gpointer) &extension_test))
1254+ return 0;
1255+ }
1256+ else if (g_module_symbol (module, "webkit_web_extension_initialize",
1257+ (gpointer) &web_extension_init)
1258+ || g_module_symbol (module, "webkit_web_extension_initialize_with_user_data",
1259+ (gpointer) &web_extension_init))
1260+ {
1261+ if (!g_module_symbol (module, "extension_test", (gpointer) &extension_test))
1262+ g_error (_("%s doesn't provide unit tests."), test);
1263+ }
1264+ else
1265+ g_error (_("%s doesn't look like a Midori extension."), test);
1266+
1267+ extension_test ();
1268+ return g_test_run ();
1269+ }
1270+
1271 if (plain)
1272 {
1273 GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1274
1275=== modified file 'midori/midori-app.c'
1276--- midori/midori-app.c 2015-04-14 19:13:57 +0000
1277+++ midori/midori-app.c 2015-06-22 22:20:28 +0000
1278@@ -1183,7 +1183,7 @@
1279
1280 { STOCK_BOOKMARKS, N_("_Bookmarks"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_B },
1281 { STOCK_BOOKMARK_ADD, N_("Add Boo_kmark") },
1282- { STOCK_EXTENSION, N_("_Extensions") },
1283+ { MIDORI_STOCK_EXTENSION, N_("_Extensions") },
1284 { STOCK_HISTORY, N_("_History"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_H },
1285 { STOCK_SCRIPT, N_("_Userscripts") },
1286 { STOCK_STYLE, N_("User_styles") },
1287
1288=== modified file 'midori/midori-extension.c'
1289--- midori/midori-extension.c 2014-04-05 19:15:34 +0000
1290+++ midori/midori-extension.c 2015-06-22 22:20:28 +0000
1291@@ -562,6 +562,7 @@
1292 g_assert (midori_extension_activate_gracefully (app, extension_path, "libtabby." G_MODULE_SUFFIX, activate));
1293 g_assert (midori_extension_activate_gracefully (app, extension_path, "libopen-with." G_MODULE_SUFFIX, activate));
1294 g_assert (midori_extension_activate_gracefully (app, extension_path, "libflummi." G_MODULE_SUFFIX, activate));
1295+ g_assert (midori_extension_activate_gracefully (app, extension_path, "libextension-manager." G_MODULE_SUFFIX, activate));
1296
1297 gint i = 0;
1298 const gchar* filename;
1299@@ -623,6 +624,17 @@
1300 if ((extension = g_hash_table_lookup (modules, module)))
1301 return extension;
1302
1303+ if (module && g_module_symbol (module, "peas_register_types", (gpointer) &extension_init))
1304+ {
1305+ /* Peas plugin: not handled here */
1306+ return NULL;
1307+ }
1308+ if (module && g_module_symbol (module, "webkit_web_extension_initialize_with_user_data", (gpointer) &extension_init))
1309+ {
1310+ /* WebKit2 web extension: not handled here */
1311+ return NULL;
1312+ }
1313+
1314 if (module && g_module_symbol (module, "extension_init",
1315 (gpointer) &extension_init))
1316 {
1317@@ -684,6 +696,7 @@
1318 && strcmp (filename, "libabout." G_MODULE_SUFFIX)
1319 && strcmp (filename, "libtabby." G_MODULE_SUFFIX)
1320 && strcmp (filename, "libopen-with." G_MODULE_SUFFIX)
1321+ && strcmp (filename, "libextension-manager." G_MODULE_SUFFIX)
1322 && strcmp (filename, "libflummi." G_MODULE_SUFFIX))
1323 katze_array_add_item (extensions, extension);
1324
1325
1326=== modified file 'midori/midori-frontend.c'
1327--- midori/midori-frontend.c 2015-06-12 20:43:52 +0000
1328+++ midori/midori-frontend.c 2015-06-22 22:20:28 +0000
1329@@ -261,14 +261,6 @@
1330 }
1331
1332 static void
1333-midori_browser_show_preferences_cb (MidoriBrowser* browser,
1334- KatzePreferences* preferences,
1335- MidoriApp* app)
1336-{
1337- midori_preferences_add_extension_category (preferences, app);
1338-}
1339-
1340-static void
1341 midori_app_add_browser_cb (MidoriApp* app,
1342 MidoriBrowser* browser,
1343 gpointer user_data)
1344@@ -287,8 +279,6 @@
1345 /* Extensions */
1346 g_signal_connect (browser, "show-preferences",
1347 G_CALLBACK (midori_browser_privacy_preferences_cb), NULL);
1348- g_signal_connect (browser, "show-preferences",
1349- G_CALLBACK (midori_browser_show_preferences_cb), app);
1350
1351 g_object_unref (panel);
1352 }
1353
1354=== modified file 'midori/midori-preferences.c'
1355--- midori/midori-preferences.c 2015-06-06 13:03:43 +0000
1356+++ midori/midori-preferences.c 2015-06-22 22:20:28 +0000
1357@@ -14,7 +14,6 @@
1358 #include "midori-app.h"
1359 #include "midori-core.h"
1360 #include "midori-extension.h"
1361-#include "panels/midori-extensions.h"
1362 #include "midori-platform.h"
1363
1364 #include <string.h>
1365@@ -603,35 +602,6 @@
1366 midori_preferences_add_extension_category (KatzePreferences* preferences,
1367 MidoriApp* app)
1368 {
1369- KatzeArray* array;
1370- GtkWidget* scrolled;
1371- GtkWidget* addon;
1372- GList* children;
1373- GtkWidget* page;
1374-
1375- array = katze_object_get_object (app, "extensions");
1376-
1377- midori_extension_load_from_folder (app, NULL, FALSE);
1378- /* Reset frozen list: allow active extensions to be saved */
1379- g_object_set_data (G_OBJECT (app), "extensions", NULL);
1380-
1381- /* Hide if there are no extensions at all */
1382- if (!katze_array_get_nth_item (array, 0))
1383- {
1384- g_object_unref (array);
1385- return;
1386- }
1387- g_object_unref (array);
1388-
1389- scrolled = gtk_scrolled_window_new (NULL, NULL);
1390- /* For lack of a better way of keeping descriptions visible */
1391- g_object_set (scrolled, "visible", TRUE, "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
1392- addon = g_object_new (MIDORI_TYPE_EXTENSIONS, "app", app, NULL);
1393- children = gtk_container_get_children (GTK_CONTAINER (addon));
1394- gtk_widget_reparent (g_list_nth_data (children, 0), scrolled);
1395- g_list_free (children);
1396- page = katze_preferences_add_category (preferences,
1397- _("Extensions"), STOCK_EXTENSION);
1398- gtk_box_pack_start (GTK_BOX (page), scrolled, TRUE, TRUE, 4);
1399+ /* Superseded by extension-manager */
1400 }
1401
1402
1403=== modified file 'midori/midori-settings.vala'
1404--- midori/midori-settings.vala 2013-11-24 21:50:38 +0000
1405+++ midori/midori-settings.vala 2015-06-22 22:20:28 +0000
1406@@ -65,6 +65,28 @@
1407 /* Since: 0.4.8 */
1408 public uint inactivity_reset { get; set; default = 0; }
1409
1410+#if HAVE_PEAS
1411+ /* Since: 0.6.0 */
1412+ public string plugins { get; set; }
1413+
1414+ construct {
1415+ var engine = Peas.Engine.get_default ();
1416+ notify["plugins"].connect (() => {
1417+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0)
1418+ stdout.printf ("Plugins: %s\n", plugins);
1419+ engine.loaded_plugins = plugins.split (",");
1420+ });
1421+ engine.notify["loaded-plugins"].connect (() => {
1422+ string plugins_ = string.joinv (",", engine.loaded_plugins);
1423+ if (plugins == plugins_)
1424+ return;
1425+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0)
1426+ stdout.printf ("Plugins: %s\n", plugins_);
1427+ plugins = plugins_;
1428+ });
1429+ }
1430+#endif
1431+
1432 string? default_theme_name_ = null;
1433 /* Since: 0.5.5 */
1434 public string? default_theme_name { get {
1435
1436=== modified file 'midori/midori-stock.h'
1437--- midori/midori-stock.h 2013-04-22 23:01:10 +0000
1438+++ midori/midori-stock.h 2015-06-22 22:20:28 +0000
1439@@ -15,7 +15,7 @@
1440 /* Stock items */
1441
1442 #define STOCK_BOOKMARKS "user-bookmarks"
1443-#define STOCK_EXTENSION "extension"
1444+#define MIDORI_STOCK_EXTENSION "extension"
1445 #define STOCK_HISTORY "document-open-recent"
1446 #define MIDORI_STOCK_WEB_BROWSER "web-browser"
1447 #define STOCK_NEWS_FEED "internet-news-reader"
1448
1449=== modified file 'midori/midori-tab.vala'
1450--- midori/midori-tab.vala 2015-04-19 14:06:12 +0000
1451+++ midori/midori-tab.vala 2015-06-22 22:20:28 +0000
1452@@ -42,6 +42,12 @@
1453 NETWORK
1454 }
1455
1456+ public interface TabActivatable : GLib.Object {
1457+ public abstract Midori.Tab tab { owned get; set; }
1458+
1459+ public abstract void created (string uri);
1460+ }
1461+
1462 public class Tab : Gtk.VBox {
1463 public Tab related { get; set construct; }
1464 public WebKit.WebView web_view { get; private set; }
1465@@ -141,6 +147,18 @@
1466 #endif
1467 /* Load something to avoid a bug where WebKit might not set a main frame */
1468 web_view.load_uri ("");
1469+
1470+#if HAVE_PEAS
1471+ var extensions = new Peas.ExtensionSet (null,
1472+ typeof (TabActivatable), "tab", this);
1473+ extensions.extension_added.connect ((info, extension) => {
1474+ ((TabActivatable)extension).created (uri);
1475+ });
1476+ extensions.foreach ((@set, info, extension) => {
1477+ ((TabActivatable)extension).created (uri);
1478+ });
1479+ set_data<Peas.ExtensionSet> ("extensions", extensions);
1480+#endif
1481 }
1482
1483 public void inject_stylesheet (string stylesheet) {
1484
1485=== modified file 'midori/midori.vapi'
1486--- midori/midori.vapi 2015-05-24 00:19:21 +0000
1487+++ midori/midori.vapi 2015-06-22 22:20:28 +0000
1488@@ -8,6 +8,7 @@
1489 public const string VERSION_SUFFIX;
1490 [CCode (cheader_filename = "midori/midori-stock.h")]
1491 namespace Stock {
1492+ public const string EXTENSION;
1493 public const string WEB_BROWSER;
1494 public const string TRANSFER;
1495 public const string PLUGINS;
1496@@ -131,7 +132,7 @@
1497 [CCode (cheader_filename = "midori/midori-extension.h")]
1498 public class Extension : GLib.Object {
1499 [CCode (has_construct_function = false)]
1500- public Extension ();
1501+ protected Extension ();
1502 public unowned Midori.App get_app ();
1503
1504 public void install_boolean (string name, bool default_value);
1505@@ -168,6 +169,7 @@
1506 public signal void activate (Midori.App app);
1507 public bool is_prepared ();
1508 public bool is_active ();
1509+ public bool has_preferences ();
1510 public signal void deactivate ();
1511 public signal void open_preferences ();
1512
1513
1514=== modified file 'midori/webkit2gtk-web-extension-4.0.vapi'
1515--- midori/webkit2gtk-web-extension-4.0.vapi 2015-04-19 14:06:12 +0000
1516+++ midori/webkit2gtk-web-extension-4.0.vapi 2015-06-22 22:20:28 +0000
1517@@ -2686,7 +2686,7 @@
1518 public class URIRequest : GLib.Object {
1519 [CCode (has_construct_function = false)]
1520 public URIRequest (string uri);
1521- public Soup.MessageHeaders get_http_headers ();
1522+ public unowned Soup.MessageHeaders get_http_headers ();
1523 public unowned string get_uri ();
1524 public void set_uri (string uri);
1525 public string uri { get; set construct; }
1526
1527=== removed file 'panels/midori-extensions.c'
1528--- panels/midori-extensions.c 2013-06-21 23:18:01 +0000
1529+++ panels/midori-extensions.c 1970-01-01 00:00:00 +0000
1530@@ -1,544 +0,0 @@
1531-/*
1532- Copyright (C) 2008-2009 Christian Dywan <christian@twotoasts.de>
1533-
1534- This library is free software; you can redistribute it and/or
1535- modify it under the terms of the GNU Lesser General Public
1536- License as published by the Free Software Foundation; either
1537- version 2.1 of the License, or (at your option) any later version.
1538-
1539- See the file COPYING for the full license text.
1540-*/
1541-
1542-#include "midori-extensions.h"
1543-
1544-#include "midori-app.h"
1545-#include "midori-extension.h"
1546-#include "midori-platform.h"
1547-#include "midori-core.h"
1548-
1549-#include <glib/gi18n.h>
1550-
1551-struct _MidoriExtensions
1552-{
1553- GtkVBox parent_instance;
1554-
1555- GtkWidget* toolbar;
1556- GtkWidget* treeview;
1557- MidoriApp* app;
1558-};
1559-
1560-struct _MidoriExtensionsClass
1561-{
1562- GtkVBoxClass parent_class;
1563-};
1564-
1565-static void
1566-midori_extensions_viewable_iface_init (MidoriViewableIface* iface);
1567-
1568-G_DEFINE_TYPE_WITH_CODE (MidoriExtensions, midori_extensions, GTK_TYPE_VBOX,
1569- G_IMPLEMENT_INTERFACE (MIDORI_TYPE_VIEWABLE,
1570- midori_extensions_viewable_iface_init));
1571-
1572-enum
1573-{
1574- PROP_0,
1575-
1576- PROP_APP
1577-};
1578-
1579-static void
1580-midori_extensions_set_property (GObject* object,
1581- guint prop_id,
1582- const GValue* value,
1583- GParamSpec* pspec);
1584-
1585-static void
1586-midori_extensions_get_property (GObject* object,
1587- guint prop_id,
1588- GValue* value,
1589- GParamSpec* pspec);
1590-
1591-static void
1592-midori_extensions_finalize (GObject* object);
1593-
1594-static void
1595-midori_extensions_class_init (MidoriExtensionsClass* class)
1596-{
1597- GObjectClass* gobject_class;
1598- GParamFlags flags;
1599-
1600- gobject_class = G_OBJECT_CLASS (class);
1601- gobject_class->set_property = midori_extensions_set_property;
1602- gobject_class->get_property = midori_extensions_get_property;
1603- gobject_class->finalize = midori_extensions_finalize;
1604-
1605- flags = G_PARAM_READWRITE;
1606-
1607- g_object_class_install_property (gobject_class,
1608- PROP_APP,
1609- g_param_spec_object (
1610- "app",
1611- "App",
1612- "The app",
1613- MIDORI_TYPE_APP,
1614- flags));
1615-}
1616-
1617-static const gchar*
1618-midori_extensions_get_label (MidoriViewable* viewable)
1619-{
1620- return _("Extensions");
1621-}
1622-
1623-static const gchar*
1624-midori_extensions_get_stock_id (MidoriViewable* viewable)
1625-{
1626- return STOCK_EXTENSION;
1627-}
1628-
1629-static GtkWidget*
1630-midori_extensions_get_toolbar (MidoriViewable* extensions)
1631-{
1632- if (!MIDORI_EXTENSIONS (extensions)->toolbar)
1633- {
1634- GtkWidget* toolbar;
1635-
1636- toolbar = gtk_toolbar_new ();
1637- MIDORI_EXTENSIONS (extensions)->toolbar = toolbar;
1638- }
1639-
1640- return MIDORI_EXTENSIONS (extensions)->toolbar;
1641-}
1642-
1643-static void
1644-midori_extensions_viewable_iface_init (MidoriViewableIface* iface)
1645-{
1646- iface->get_stock_id = midori_extensions_get_stock_id;
1647- iface->get_label = midori_extensions_get_label;
1648- iface->get_toolbar = midori_extensions_get_toolbar;
1649-}
1650-
1651-static void
1652-midori_extensions_extension_activate_cb (MidoriExtension* extension,
1653- MidoriApp* app,
1654- MidoriExtensions* extensions)
1655-{
1656- gtk_widget_queue_draw (GTK_WIDGET (extensions->treeview));
1657-}
1658-
1659-static void
1660-midori_extensions_extension_deactivate_cb (MidoriExtension* extension,
1661- MidoriExtensions* extensions)
1662-{
1663- gtk_widget_queue_draw (GTK_WIDGET (extensions->treeview));
1664-}
1665-
1666-static void
1667-midori_extensions_add_item_cb (KatzeArray* array,
1668- MidoriExtension* extension,
1669- MidoriExtensions* extensions)
1670-{
1671- GtkTreeIter iter;
1672- GtkTreeModel* model;
1673-
1674- model = gtk_tree_view_get_model (GTK_TREE_VIEW (extensions->treeview));
1675- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
1676- gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, extension, -1);
1677- g_signal_connect (extension, "activate",
1678- G_CALLBACK (midori_extensions_extension_activate_cb), extensions);
1679- g_signal_connect (extension, "deactivate",
1680- G_CALLBACK (midori_extensions_extension_deactivate_cb), extensions);
1681-}
1682-
1683-static void
1684-midori_extensions_set_property (GObject* object,
1685- guint prop_id,
1686- const GValue* value,
1687- GParamSpec* pspec)
1688-{
1689- MidoriExtensions* extensions = MIDORI_EXTENSIONS (object);
1690-
1691- switch (prop_id)
1692- {
1693- case PROP_APP:
1694- {
1695- KatzeArray* array;
1696- MidoriExtension* extension;
1697-
1698- /* FIXME: Handle NULL and subsequent assignments */
1699- extensions->app = g_value_get_object (value);
1700- array = katze_object_get_object (extensions->app, "extensions");
1701- g_signal_connect (array, "add-item",
1702- G_CALLBACK (midori_extensions_add_item_cb), extensions);
1703-
1704- KATZE_ARRAY_FOREACH_ITEM (extension, array)
1705- midori_extensions_add_item_cb (array, extension, extensions);
1706- g_object_unref (array);
1707- }
1708- break;
1709- default:
1710- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1711- break;
1712- }
1713-}
1714-
1715-static void
1716-midori_extensions_get_property (GObject* object,
1717- guint prop_id,
1718- GValue* value,
1719- GParamSpec* pspec)
1720-{
1721- MidoriExtensions* extensions = MIDORI_EXTENSIONS (object);
1722-
1723- switch (prop_id)
1724- {
1725- case PROP_APP:
1726- g_value_set_object (value, extensions->app);
1727- break;
1728- default:
1729- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1730- break;
1731- }
1732-}
1733-
1734-static void
1735-midori_extensions_treeview_render_tick_cb (GtkTreeViewColumn* column,
1736- GtkCellRenderer* renderer,
1737- GtkTreeModel* model,
1738- GtkTreeIter* iter,
1739- GtkWidget* treeview)
1740-{
1741- MidoriExtension* extension;
1742-
1743- gtk_tree_model_get (model, iter, 0, &extension, -1);
1744-
1745- g_object_set (renderer,
1746- "activatable", midori_extension_is_prepared (extension),
1747- "active", midori_extension_is_active (extension) || g_object_get_data (G_OBJECT (extension), "static"),
1748- "xpad", 4,
1749- NULL);
1750-
1751- g_object_unref (extension);
1752-}
1753-
1754-static void
1755-midori_extensions_treeview_render_icon_cb (GtkTreeViewColumn* column,
1756- GtkCellRenderer* renderer,
1757- GtkTreeModel* model,
1758- GtkTreeIter* iter,
1759- GtkWidget* treeview)
1760-{
1761- MidoriExtension* extension;
1762- gchar* stock_id;
1763- gtk_tree_model_get (model, iter, 0, &extension, -1);
1764-
1765- stock_id = katze_object_get_object (extension, "stock-id");
1766- g_object_set (renderer, "stock-id", stock_id ? stock_id : STOCK_EXTENSION,
1767- "stock-size", GTK_ICON_SIZE_BUTTON,
1768- "sensitive", midori_extension_is_prepared (extension),
1769- "xpad", 4, NULL);
1770- g_free (stock_id);
1771- g_object_unref (extension);
1772-}
1773-
1774-static void
1775-midori_extensions_treeview_render_preferences_cb (GtkTreeViewColumn* column,
1776- GtkCellRenderer* renderer,
1777- GtkTreeModel* model,
1778- GtkTreeIter* iter,
1779- GtkWidget* treeview)
1780-{
1781- MidoriExtension* extension;
1782- gtk_tree_model_get (model, iter, 0, &extension, -1);
1783-
1784- g_object_set (renderer, "stock-id", GTK_STOCK_PREFERENCES,
1785- "stock-size", GTK_ICON_SIZE_BUTTON,
1786- "visible", midori_extension_has_preferences (extension),
1787- "sensitive", midori_extension_is_active (extension),
1788- "xpad", 4, NULL);
1789- g_object_unref (extension);
1790-}
1791-
1792-static void
1793-midori_extensions_treeview_render_text_cb (GtkTreeViewColumn* column,
1794- GtkCellRenderer* renderer,
1795- GtkTreeModel* model,
1796- GtkTreeIter* iter,
1797- GtkWidget* treeview)
1798-{
1799- MidoriExtension* extension;
1800- gchar* name;
1801- gchar* version;
1802- gchar* desc;
1803- gchar* text;
1804-
1805- gtk_tree_model_get (model, iter, 0, &extension, -1);
1806-
1807- name = katze_object_get_string (extension, "name");
1808- version = katze_object_get_string (extension, "version");
1809- desc = katze_object_get_string (extension, "description");
1810- if (katze_object_get_boolean (extension, "use-markup"))
1811- text = g_strdup_printf ("<b>%s</b> %s\n%s",
1812- name, version && *version ? version : "", desc);
1813- else
1814- text = g_markup_printf_escaped ("<b>%s</b> %s\n%s",
1815- name, version && *version ? version : "", desc);
1816- g_free (name);
1817- g_free (version);
1818- g_free (desc);
1819-
1820- g_object_set (renderer,
1821- "markup", text,
1822- "ellipsize", PANGO_ELLIPSIZE_END,
1823- "sensitive", midori_extension_is_prepared (extension),
1824- NULL);
1825-
1826- g_free (text);
1827- g_object_unref (extension);
1828-}
1829-
1830-static void
1831-midori_extensions_treeview_row_activated_cb (GtkTreeView* treeview,
1832- GtkTreePath* path,
1833- GtkTreeViewColumn* column,
1834- MidoriExtensions* extensions)
1835-{
1836- GtkTreeModel* model;
1837- GtkTreeIter iter;
1838-
1839- model = gtk_tree_view_get_model (treeview);
1840- if (gtk_tree_model_get_iter (model, &iter, path))
1841- {
1842- MidoriExtension* extension;
1843- KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
1844-
1845- gtk_tree_model_get (model, &iter, 0, &extension, -1);
1846- if (midori_extension_is_active (extension))
1847- midori_extension_deactivate (extension);
1848- else if (midori_extension_is_prepared (extension))
1849- g_signal_emit_by_name (extension, "activate", extensions->app);
1850- /* Make it easy for listeners to see that extensions changed */
1851- katze_array_update (array);
1852-
1853- g_object_unref (array);
1854- g_object_unref (extension);
1855- }
1856-}
1857-
1858-static void
1859-midori_extensions_cell_renderer_toggled_cb (GtkCellRendererToggle* renderer,
1860- const gchar* path,
1861- MidoriExtensions* extensions)
1862-{
1863- GtkTreeModel* model;
1864- GtkTreeIter iter;
1865-
1866- model = gtk_tree_view_get_model (GTK_TREE_VIEW (extensions->treeview));
1867- if (gtk_tree_model_get_iter_from_string (model, &iter, path))
1868- {
1869- MidoriExtension* extension;
1870- KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
1871-
1872- gtk_tree_model_get (model, &iter, 0, &extension, -1);
1873- if (midori_extension_is_active (extension))
1874- midori_extension_deactivate (extension);
1875- else if (midori_extension_is_prepared (extension))
1876- g_signal_emit_by_name (extension, "activate", extensions->app);
1877- /* Make it easy for listeners to see that extensions changed */
1878- katze_array_update (array);
1879-
1880- g_object_unref (array);
1881- g_object_unref (extension);
1882- }
1883-}
1884-
1885-static gint
1886-midori_extensions_tree_sort_func (GtkTreeModel* model,
1887- GtkTreeIter* a,
1888- GtkTreeIter* b,
1889- gpointer data)
1890-{
1891- MidoriExtension* e1, *e2;
1892- gchar* name1, *name2;
1893- gint result = 0;
1894-
1895- gtk_tree_model_get (model, a, 0, &e1, -1);
1896- gtk_tree_model_get (model, b, 0, &e2, -1);
1897-
1898- name1 = katze_object_get_string (e1, "name");
1899- name2 = katze_object_get_string (e2, "name");
1900-
1901- g_object_unref (e1);
1902- g_object_unref (e2);
1903-
1904- result = g_strcmp0 (name1, name2);
1905-
1906- g_free (name1);
1907- g_free (name2);
1908-
1909- return result;
1910-}
1911-
1912-static void
1913-midori_extensions_treeview_column_preference_clicked_cb (GtkWidget* widget,
1914- GtkTreeView* treeview,
1915- GtkTreePath* path)
1916-{
1917- GtkTreeModel* model;
1918- GtkTreeIter iter;
1919-
1920- model = gtk_tree_view_get_model (treeview);
1921- if (gtk_tree_model_get_iter (model, &iter, path))
1922- {
1923- MidoriExtension* extension;
1924-
1925- gtk_tree_model_get (model, &iter, 0, &extension, -1);
1926- if (midori_extension_is_active (extension))
1927- g_signal_emit_by_name (extension, "open-preferences");
1928- g_object_unref (extension);
1929- }
1930-
1931-}
1932-
1933-static gboolean
1934-midori_extensions_treeview_button_pressed_cb (GtkWidget* view,
1935- GdkEventButton* bevent,
1936- gpointer data)
1937-{
1938- gboolean ret = FALSE;
1939- GtkTreePath* path;
1940- GtkTreeViewColumn* column;
1941- guint signal_id;
1942-
1943- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view),
1944- bevent->x, bevent->y, &path, &column, NULL, NULL))
1945- {
1946- if (path != NULL)
1947- {
1948- if (MIDORI_IS_EXTENSIONS_COLUMN (column))
1949- {
1950- signal_id = g_signal_lookup ("row-clicked", G_OBJECT_TYPE (column));
1951-
1952- if (signal_id && g_signal_has_handler_pending (column, signal_id, 0, FALSE)) {
1953- g_signal_emit (column, signal_id, 0, GTK_TREE_VIEW (view), path);
1954- ret = TRUE;
1955- }
1956- }
1957- gtk_tree_path_free (path);
1958- }
1959- }
1960- return ret;
1961-}
1962-
1963-static gboolean
1964-extensions_column_search_equal_func (GtkTreeModel* model,
1965- gint column,
1966- const gchar* key,
1967- GtkTreeIter* iter,
1968- gpointer search_data)
1969-{
1970- MidoriExtension* extension;
1971- gchar* name;
1972- gchar* lower;
1973- gboolean match;
1974-
1975- gtk_tree_model_get (model, iter, 0, &extension, -1);
1976- name = katze_object_get_string (extension, "name");
1977- lower = g_utf8_strdown (name, -1);
1978- match = !strstr (lower, key);
1979-
1980- g_free (lower);
1981- g_free (name);
1982-
1983- return match;
1984-}
1985-
1986-static void
1987-midori_extensions_init (MidoriExtensions* extensions)
1988-{
1989- /* Create the treeview */
1990- GtkTreeViewColumn* column;
1991- GtkCellRenderer* renderer_icon;
1992- GtkCellRenderer* renderer_text;
1993- GtkCellRenderer* renderer_toggle;
1994- GtkCellRenderer* renderer_preferences;
1995- GtkListStore* liststore = gtk_list_store_new (1, G_TYPE_OBJECT);
1996- extensions->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
1997- g_object_connect (extensions->treeview,
1998- "signal::button-press-event",
1999- midori_extensions_treeview_button_pressed_cb, NULL,
2000- NULL);
2001- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore),
2002- 0, GTK_SORT_ASCENDING);
2003- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore),
2004- 0, midori_extensions_tree_sort_func, NULL, NULL);
2005- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (extensions->treeview), FALSE);
2006- column = gtk_tree_view_column_new ();
2007- renderer_toggle = gtk_cell_renderer_toggle_new ();
2008- gtk_tree_view_column_pack_start (column, renderer_toggle, FALSE);
2009- gtk_tree_view_column_set_cell_data_func (column, renderer_toggle,
2010- (GtkTreeCellDataFunc)midori_extensions_treeview_render_tick_cb,
2011- extensions->treeview, NULL);
2012- g_signal_connect (renderer_toggle, "toggled",
2013- G_CALLBACK (midori_extensions_cell_renderer_toggled_cb), extensions);
2014- gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column);
2015- column = gtk_tree_view_column_new ();
2016- renderer_icon = gtk_cell_renderer_pixbuf_new ();
2017- gtk_tree_view_column_pack_start (column, renderer_icon, FALSE);
2018- gtk_tree_view_column_set_cell_data_func (column, renderer_icon,
2019- (GtkTreeCellDataFunc)midori_extensions_treeview_render_icon_cb,
2020- extensions->treeview, NULL);
2021- gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column);
2022- column = gtk_tree_view_column_new ();
2023- gtk_tree_view_column_set_expand (column, TRUE);
2024- renderer_text = gtk_cell_renderer_text_new ();
2025- gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
2026- gtk_tree_view_column_set_cell_data_func (column, renderer_text,
2027- (GtkTreeCellDataFunc)midori_extensions_treeview_render_text_cb,
2028- extensions->treeview, NULL);
2029- gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column);
2030- column = GTK_TREE_VIEW_COLUMN (midori_extensions_column_new ());
2031- g_signal_connect (column,
2032- "row-clicked",
2033- G_CALLBACK (midori_extensions_treeview_column_preference_clicked_cb),
2034- NULL);
2035- renderer_preferences = gtk_cell_renderer_pixbuf_new ();
2036- gtk_tree_view_column_pack_start (column, renderer_preferences, FALSE);
2037- gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
2038- gtk_tree_view_column_set_fixed_width (column, 30);
2039- gtk_tree_view_column_set_cell_data_func (column, renderer_preferences,
2040- (GtkTreeCellDataFunc)midori_extensions_treeview_render_preferences_cb,
2041- extensions->treeview, NULL);
2042- gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column);
2043- g_object_unref (liststore);
2044- g_object_connect (extensions->treeview,
2045- "signal::row-activated",
2046- midori_extensions_treeview_row_activated_cb, extensions,
2047- NULL);
2048- gtk_tree_view_set_search_column (GTK_TREE_VIEW (extensions->treeview), 0);
2049- gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (extensions->treeview),
2050- extensions_column_search_equal_func, NULL, NULL);
2051- gtk_widget_show (extensions->treeview);
2052- gtk_box_pack_start (GTK_BOX (extensions), extensions->treeview, TRUE, TRUE, 0);
2053-}
2054-
2055-static void
2056-midori_extensions_finalize (GObject* object)
2057-{
2058- MidoriExtensions* extensions = MIDORI_EXTENSIONS (object);
2059- KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
2060- MidoriExtension* extension;
2061-
2062- KATZE_ARRAY_FOREACH_ITEM (extension, array)
2063- {
2064- g_signal_handlers_disconnect_by_func (extension,
2065- midori_extensions_extension_activate_cb, extensions);
2066- g_signal_handlers_disconnect_by_func (extension,
2067- midori_extensions_extension_deactivate_cb, extensions);
2068- }
2069- g_signal_handlers_disconnect_by_func (array,
2070- midori_extensions_add_item_cb, extensions);
2071-
2072- g_object_unref (array);
2073-}
2074-
2075
2076=== removed file 'panels/midori-extensions.h'
2077--- panels/midori-extensions.h 2008-12-04 00:44:33 +0000
2078+++ panels/midori-extensions.h 1970-01-01 00:00:00 +0000
2079@@ -1,45 +0,0 @@
2080-/*
2081- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
2082-
2083- This library is free software; you can redistribute it and/or
2084- modify it under the terms of the GNU Lesser General Public
2085- License as published by the Free Software Foundation; either
2086- version 2.1 of the License, or (at your option) any later version.
2087-
2088- See the file COPYING for the full license text.
2089-*/
2090-
2091-#ifndef __MIDORI_EXTENSIONS_H__
2092-#define __MIDORI_EXTENSIONS_H__
2093-
2094-#include <gtk/gtk.h>
2095-
2096-#include <katze/katze.h>
2097-
2098-G_BEGIN_DECLS
2099-
2100-#define MIDORI_TYPE_EXTENSIONS \
2101- (midori_extensions_get_type ())
2102-#define MIDORI_EXTENSIONS(obj) \
2103- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_EXTENSIONS, MidoriExtensions))
2104-#define MIDORI_EXTENSIONS_CLASS(klass) \
2105- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_EXTENSIONS, MidoriExtensionsClass))
2106-#define MIDORI_IS_EXTENSIONS(obj) \
2107- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_EXTENSIONS))
2108-#define MIDORI_IS_EXTENSIONS_CLASS(klass) \
2109- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_EXTENSIONS))
2110-#define MIDORI_EXTENSIONS_GET_CLASS(obj) \
2111- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_EXTENSIONS, MidoriExtensionsClass))
2112-
2113-typedef struct _MidoriExtensions MidoriExtensions;
2114-typedef struct _MidoriExtensionsClass MidoriExtensionsClass;
2115-
2116-GType
2117-midori_extensions_get_type (void);
2118-
2119-GtkWidget*
2120-midori_extensions_new (void);
2121-
2122-G_END_DECLS
2123-
2124-#endif /* __MIDORI_EXTENSIONS_H__ */
2125
2126=== modified file 'po/POTFILES.in'
2127--- po/POTFILES.in 2015-05-24 00:19:21 +0000
2128+++ po/POTFILES.in 2015-06-22 22:20:28 +0000
2129@@ -27,7 +27,7 @@
2130 midori/sokoke.c
2131 toolbars/midori-findbar.c
2132 panels/midori-bookmarks.c
2133-panels/midori-extensions.c
2134+extensions/extensions.vala
2135 panels/midori-history.c
2136 katze/katze-http-auth.c
2137 katze/katze-utils.c
2138@@ -65,9 +65,12 @@
2139 extensions/status-clock.c
2140 extensions/statusbar-features.c
2141 extensions/tab-panel.c
2142-extensions/tabs-minimized.c
2143+extensions/tabs-minimized.vala
2144 extensions/tabs2one.c
2145 extensions/toolbar-editor.c
2146+extensions/hsts.web.vala
2147+extensions/web-extension.web.vala
2148+ipc/ipc-tab.vala
2149 katze/katze-cellrenderercomboboxtext.c
2150 katze/midori-hsts.vala
2151 katze/katze-separatoraction.vala

Subscribers

People subscribed via source and target branches

to all changes: