Merge lp:~lemonboy/midori/loginmanager into lp:midori

Proposed by The Lemon Man
Status: Needs review
Proposed branch: lp:~lemonboy/midori/loginmanager
Merge into: lp:midori
Diff against target: 15638 lines (+5924/-5423) (has conflicts)
88 files modified
CMakeLists.txt (+45/-12)
data/error.html (+0/-30)
data/logo-shade.svg (+0/-150)
extensions/CMakeLists.txt (+91/-51)
extensions/about.vala (+31/-33)
extensions/adblock/extension.vala (+10/-25)
extensions/adblock/widgets.vala (+0/-8)
extensions/colorful-tabs.c (+0/-5)
extensions/colorful-tabs.web.vala (+69/-0)
extensions/cookie-manager/cookie-manager.c (+0/-6)
extensions/cookie-permissions/cookie-permission-manager-preferences-window.c (+0/-22)
extensions/cookie-permissions/cookie-permission-manager.c (+0/-6)
extensions/donottrack.web.vala (+141/-0)
extensions/external-download-manager.vala (+9/-7)
extensions/feed-panel/feed-panel.c (+0/-4)
extensions/feed-panel/main.c (+1/-1)
extensions/formhistory/formhistory.c (+1/-1)
extensions/history-list.vala (+15/-13)
extensions/hsts.web.vala (+173/-0)
extensions/login-manager.web.vala (+456/-0)
extensions/nojs/nojs-preferences.c (+0/-18)
extensions/nojs/nojs.c (+1/-1)
extensions/nsplugin-manager.vala (+0/-71)
extensions/open-with.vala (+0/-11)
extensions/shortcuts.c (+1/-1)
extensions/status-clock.c (+1/-1)
extensions/statusbar-features.c (+4/-33)
extensions/tabby.vala (+0/-5)
extensions/transfers.vala (+8/-23)
ipc/CMakeLists.txt (+47/-0)
ipc/ipc-contextaction.vala (+56/-0)
ipc/ipc-paths.vala (+132/-0)
ipc/midori-tabproxy.vala (+29/-0)
ipc/midori-webextension.vala (+40/-0)
katze/gtk3-compat.h (+0/-93)
katze/katze-cellrenderercomboboxtext.c (+0/-39)
katze/katze-http-auth.c (+0/-464)
katze/katze-http-auth.h (+0/-42)
katze/katze-preferences.c (+7/-4)
katze/katze-utils.c (+0/-80)
katze/katze-utils.h (+0/-1)
katze/katze.h (+0/-5)
katze/midori-paths.vala (+22/-111)
katze/midori-uri.vala (+0/-6)
midori/CMakeLists.txt (+10/-12)
midori/main.c (+50/-11)
midori/midori-addons.vala (+415/-0)
midori/midori-app.c (+7/-8)
midori/midori-app.h (+5/-0)
midori/midori-browser.c (+263/-702)
midori/midori-contextaction.vala (+19/-13)
midori/midori-download.vala (+4/-28)
midori/midori-extension.c (+47/-830)
midori/midori-extension.h (+2/-5)
midori/midori-findbar.c (+7/-4)
midori/midori-frontend.c (+19/-13)
midori/midori-locationaction.c (+35/-39)
midori/midori-navigationaction.vala (+237/-0)
midori/midori-notebook.vala (+0/-48)
midori/midori-oops.vala (+53/-0)
midori/midori-panel.c (+0/-10)
midori/midori-platform.h (+0/-1)
midori/midori-preferences.c (+0/-15)
midori/midori-privatedata.c (+1/-43)
midori/midori-searchaction.c (+2/-8)
midori/midori-session.c (+9/-41)
midori/midori-session.h (+0/-3)
midori/midori-settings.vala (+1/-0)
midori/midori-tab.vala (+104/-31)
midori/midori-view.c (+183/-848)
midori/midori-view.h (+3/-5)
midori/midori-websettings.c (+8/-202)
midori/midori-window.vala (+211/-0)
midori/midori.vapi (+10/-21)
midori/sokoke.c (+0/-53)
midori/sokoke.h (+0/-1)
midori/webkit2gtk-web-extension-4.0.vapi (+2801/-0)
midori/webkitgtk-3.0.deps (+0/-6)
midori/webkitgtk-3.0.vapi (+0/-841)
po/POTFILES.in (+15/-6)
tests/CMakeLists.txt (+0/-12)
tests/browser.c (+0/-33)
tests/extensions.c (+0/-52)
tests/hsts.vala (+0/-32)
tests/magic-uri.c (+0/-2)
tests/properties.c (+0/-5)
tests/tab.vala (+1/-5)
win32/makedist/makedist.midori (+12/-51)
Text conflict in CMakeLists.txt
Text conflict in extensions/CMakeLists.txt
Text conflict in extensions/adblock/extension.vala
Text conflict in extensions/external-download-manager.vala
Text conflict in extensions/history-list.vala
Text conflict in extensions/statusbar-features.c
Text conflict in extensions/transfers.vala
Contents conflict in katze/gtk3-compat.c
Text conflict in katze/katze-preferences.c
Contents conflict in katze/midori-hsts.vala
Text conflict in midori/midori-app.c
Text conflict in midori/midori-browser.c
Text conflict in midori/midori-download.vala
Text conflict in midori/midori-locationaction.c
Contents conflict in midori/midori-panedaction.vala
Text conflict in midori/midori-session.c
Text conflict in midori/midori-tab.vala
Text conflict in midori/midori-view.c
Conflict adding file midori/midori-window.vala.  Moved existing file to midori/midori-window.vala.moved.
Text conflict in midori/midori.vapi
Contents conflict in midori/webkit2gtk-4.0.vapi
Conflict adding file midori/webkit2gtk-web-extension-4.0.vapi.  Moved existing file to midori/webkit2gtk-web-extension-4.0.vapi.moved.
Text conflict in po/POTFILES.in
To merge this branch: bzr merge lp:~lemonboy/midori/loginmanager
Reviewer Review Type Date Requested Status
Cris Dywan Pending
Review via email: mp+261500@code.launchpad.net
To post a comment you must log in.
lp:~lemonboy/midori/loginmanager updated
6873. By The Lemon Man

Adjust some tiny bits

Unmerged revisions

6873. By The Lemon Man

Adjust some tiny bits

6872. By The Lemon Man

Prototype

6871. By Cris Dywan

Implement TabProxy.add_icon and low-level Midori.ContextItem

6870. By Cris Dywan

Reinstate unowned annotation of URIRequest.get_http_headers

6869. By Cris Dywan

Make Midori.Database available to web extensions

6868. By Cris Dywan

Update webkit2gtk-web-extension-4.0.vapi from vala master

https://github.com/GNOME/vala/commit/8d57dffdea43a9d663e12b52722ef567c705bf5e

6867. By Cris Dywan

Fix return_if_fail's on midori_view_get_source/find_bar

6866. By Cris Dywan

DoNotTrack needs to handle query keys being null

6865. By Cris Dywan

Make extension tests aware of web extensions with user data

6864. By Cris Dywan

Fallback to uri if error page really has no title

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-03-23 11:33:24 +0000
3+++ CMakeLists.txt 2015-06-10 13:21:27 +0000
4@@ -29,7 +29,7 @@
5 if (REVISION)
6 set(VERSION "${VERSION}~r${REVISION}")
7 # All warnings are errors in development builds
8- set(VALAFLAGS ${VALAFLAGS} --fatal-warnings)
9+ # set(VALAFLAGS ${VALAFLAGS} --fatal-warnings) # UNCOMMENT ME
10 set(CFLAGS "${CFLAGS}")
11 endif ()
12 add_definitions("-DPACKAGE_VERSION=\"${VERSION}\"")
13@@ -39,7 +39,7 @@
14 set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY 1)
15
16 find_package(Vala REQUIRED)
17-vala_require("0.16.0")
18+vala_require("0.26.0")
19 set(VALAFLAGS ${VALAFLAGS}
20 --enable-deprecated
21 --debug
22@@ -118,20 +118,31 @@
23 sqlite3>=3.6.19
24 gmodule-2.0
25 gio-2.0>=2.32.3
26+<<<<<<< TREE
27 libsoup-gnome-2.4>=2.37.1
28+=======
29+ libsoup-gnome-2.4>=2.40.0
30+>>>>>>> MERGE-SOURCE
31 )
32 add_definitions("-DHAVE_LIBXML")
33 add_definitions("-DGIO_VERSION=\"${DEPS_gio-2.0_VERSION}\"")
34 add_definitions("-DLIBSOUP_VERSION=\"${DEPS_libsoup-gnome-2.4_VERSION}\"")
35+<<<<<<< TREE
36 set(PKGS posix linux libxml-2.0 sqlite3 gmodule-2.0 gio-2.0 libsoup-2.4)
37 if (${DEPS_libsoup-gnome-2.4_VERSION} VERSION_GREATER "2.40.0")
38 # valac 0.16 didn't have the bindings yet
39 # For consistency we need to ensure C code makes the same assumptions
40 if (${VALA_VERSION} VERSION_GREATER "0.17.0")
41+=======
42+set(PACKAGES_CORE posix libsoup-2.4 sqlite3 gtk+-3.0)
43+set(PKGS ${PACKAGES_CORE} linux libxml-2.0 gmodule-2.0)
44+ add_definitions("-DHAVE_LIBSOUP_2_29_91")
45+ add_definitions("-DHAVE_LIBSOUP_2_34_0")
46+ set(VALAFLAGS ${VALAFLAGS} -D HAVE_LIBSOUP_2_34_0)
47+ add_definitions("-DHAVE_LIBSOUP_2_37_1")
48+>>>>>>> MERGE-SOURCE
49 add_definitions("-DHAVE_LIBSOUP_2_40_0")
50 set(VALAFLAGS ${VALAFLAGS} -D HAVE_LIBSOUP_2_40_0)
51- endif ()
52-endif ()
53
54 if (${DEPS_gio-2.0_VERSION} VERSION_GREATER "2.40.0" OR WIN32)
55 add_definitions("-DLIBNOTIFY_VERSION=\"No\"")
56@@ -144,19 +155,12 @@
57 set(PKGS ${PKGS} libnotify)
58 endif ()
59
60-option(USE_GTK3 "Use GTK+3" OFF)
61-option(HALF_BRO_INCOM_WEBKIT2 "Serve as a guniea pig" OFF)
62 option(USE_ZEITGEIST "Zeitgeist history integration" ON)
63 option(USE_GRANITE "Fancy notebook and pop-overs" OFF)
64 option(USE_APIDOCS "API documentation" OFF)
65 option(USE_GIR "Generate GObject Introspection bindings" OFF)
66 option(EXTRA_WARNINGS "Additional compiler warnings" OFF)
67
68-# GTK+3 is implied here, whether set or not
69-if (USE_GRANITE OR HALF_BRO_INCOM_WEBKIT2)
70- set(USE_GTK3 ON)
71-endif ()
72-
73 if (USE_GRANITE)
74 pkg_check_modules(GRANITE granite>=0.2)
75 set(OPTS_INCLUDE_DIRS "${OPTS_INCLUDE_DIRS};${GRANITE_INCLUDE_DIRS}")
76@@ -177,6 +181,7 @@
77 set(PKGS ${PKGS} zeitgeist-2.0)
78 endif()
79
80+<<<<<<< TREE
81 if (WIN32)
82 add_definitions("-DGCR_VERSION=\"No\"")
83 else ()
84@@ -190,20 +195,42 @@
85 set(OPTS_INCLUDE_DIRS ${OPTS_INCLUDE_DIRS} ${GCR_INCLUDE_DIRS})
86 set(OPTS_LIBRARIES ${OPTS_LIBRARIES} ${GCR_LIBRARIES})
87 endif ()
88+=======
89+pkg_check_modules(GCR REQUIRED gcr-3>=2.32)
90+ set(OPTS_INCLUDE_DIRS "${OPTS_INCLUDE_DIRS};${GCR_INCLUDE_DIRS}")
91+ set(OPTS_LIBRARIES "${OPTS_LIBRARIES};${GCR_LIBRARIES}")
92+ add_definitions("-DGCR_VERSION=\"${GCR_VERSION}\"")
93+ add_definitions("-DHAVE_GCR")
94+ set(VALAFLAGS ${VALAFLAGS} -D HAVE_GCR)
95+>>>>>>> MERGE-SOURCE
96
97+<<<<<<< TREE
98 if (HALF_BRO_INCOM_WEBKIT2)
99+=======
100+>>>>>>> MERGE-SOURCE
101 pkg_check_modules(DEPS_GTK REQUIRED
102+<<<<<<< TREE
103 gtk+-3.0>=3.0.0
104 webkit2gtk-4.0>=2.3.91
105+=======
106+ gtk+-3.0>=3.6.0
107+ webkit2gtk-4.0>=2.3.91
108+>>>>>>> MERGE-SOURCE
109 )
110 add_definitions("-DHAVE_WEBKIT2")
111 add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"")
112+<<<<<<< TREE
113 add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit2gtk-4.0_VERSION}\"")
114 set(PKGS ${PKGS} gtk+-3.0)
115 # set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-web-extension-4.0.vapi")
116 set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-4.0.vapi")
117+=======
118+ add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit2gtk-4.0_VERSION}\"")
119+ set(PKGS ${PKGS} webkit2gtk-4.0)
120+>>>>>>> MERGE-SOURCE
121 set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3)
122 set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2)
123+<<<<<<< TREE
124 set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2_3_91)
125 elseif (USE_GTK3)
126 pkg_check_modules(DEPS_GTK REQUIRED
127@@ -228,6 +255,9 @@
128 set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkitgtk-3.0.vapi")
129 endif ()
130 set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/katze/katze.vapi")
131+=======
132+ set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2_3_91)
133+>>>>>>> MERGE-SOURCE
134
135 # dh_translations detects this if there's no variable used
136 set (GETTEXT_PACKAGE "midori")
137@@ -260,6 +290,8 @@
138 set(VALA_CFLAGS "-w -g -fPIC")
139
140 set(LIBMIDORI "${CMAKE_PROJECT_NAME}-core")
141+set(LIBMIDORIV "${CMAKE_PROJECT_NAME}-vala")
142+set(LIBMIDORI2 "${CMAKE_PROJECT_NAME}-ipc")
143
144 # CMake provides no uninstall target by design
145 add_custom_target (uninstall
146@@ -268,8 +300,9 @@
147 install(FILES AUTHORS COPYING ChangeLog EXPAT README DESTINATION ${CMAKE_INSTALL_DOCDIR})
148
149 add_subdirectory (midori)
150+add_subdirectory (ipc)
151+enable_testing()
152 add_subdirectory (extensions)
153-enable_testing()
154 add_subdirectory (tests)
155 add_subdirectory (po)
156 add_subdirectory (icons)
157
158=== removed file 'data/error.html'
159--- data/error.html 2013-10-06 16:41:01 +0000
160+++ data/error.html 1970-01-01 00:00:00 +0000
161@@ -1,30 +0,0 @@
162-<!--
163- Error page template for Midori.
164- This file is licensed under the terms of the expat license, see the file EXPAT.
165--->
166-<html dir="{dir}">
167-<head>
168-<title>{title}</title>
169-{favicon}
170-<link rel="stylesheet" type="text/css" href="res://about.css" />
171-</head>
172-<body>
173-<img id="logo" src="res://logo-shade.png" />
174-<div id="main" style="background-image: url({error_icon});">
175- <div id="text">
176- <h1>{title}</h1>
177- <p class="message">{message}<br><i>{description}</i></p>
178- {suggestions}
179- </div>
180- <form method="GET" action="{uri}" id="button">
181- <button type="submit" onclick="location.reload(); return false;" {autofocus}>
182- <img style="{hide-button-images}" src="stock://gtk-refresh"/>
183- <span>{tryagain}</span>
184- </button>
185- </form>
186- </div>
187-
188-<br style="clear: both;"/>
189-</div>
190-</body>
191-</html>
192
193=== removed file 'data/logo-shade.svg'
194--- data/logo-shade.svg 2008-10-16 01:51:39 +0000
195+++ data/logo-shade.svg 1970-01-01 00:00:00 +0000
196@@ -1,150 +0,0 @@
197-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
198-<!-- Created with Inkscape (http://www.inkscape.org/) -->
199-<svg
200- xmlns:dc="http://purl.org/dc/elements/1.1/"
201- xmlns:cc="http://creativecommons.org/ns#"
202- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
203- xmlns:svg="http://www.w3.org/2000/svg"
204- xmlns="http://www.w3.org/2000/svg"
205- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
206- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
207- width="307.65372"
208- height="350"
209- id="svg2418"
210- sodipodi:version="0.32"
211- inkscape:version="0.46"
212- version="1.0"
213- inkscape:export-filename="/home/user/logo-shade.png"
214- inkscape:export-xdpi="90"
215- inkscape:export-ydpi="90"
216- sodipodi:docname="logo-shade.svg"
217- inkscape:output_extension="org.inkscape.output.svg.inkscape">
218- <sodipodi:namedview
219- id="base"
220- pagecolor="#ffffff"
221- bordercolor="#666666"
222- borderopacity="1.0"
223- gridtolerance="10000"
224- guidetolerance="10"
225- objecttolerance="10"
226- inkscape:pageopacity="0.0"
227- inkscape:pageshadow="2"
228- inkscape:zoom="1.03"
229- inkscape:cx="74.949357"
230- inkscape:cy="143.09941"
231- inkscape:document-units="px"
232- inkscape:current-layer="layer1"
233- showgrid="false"
234- inkscape:window-width="1253"
235- inkscape:window-height="682"
236- inkscape:window-x="0"
237- inkscape:window-y="22" />
238- <defs
239- id="defs2420">
240- <linearGradient
241- id="linearGradient3412">
242- <stop
243- id="stop3414"
244- offset="0"
245- style="stop-color:#ffffff;stop-opacity:0.59836066;" />
246- <stop
247- id="stop3416"
248- offset="1"
249- style="stop-color:#97f839;stop-opacity:0;" />
250- </linearGradient>
251- <linearGradient
252- id="linearGradient3458">
253- <stop
254- id="stop3460"
255- offset="0"
256- style="stop-color:#88fe38;stop-opacity:1;" />
257- <stop
258- id="stop3462"
259- offset="1"
260- style="stop-color:#ffffff;stop-opacity:0;" />
261- </linearGradient>
262- <inkscape:perspective
263- id="perspective2426"
264- inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
265- inkscape:vp_z="744.09448 : 526.18109 : 1"
266- inkscape:vp_y="0 : 1000 : 0"
267- inkscape:vp_x="0 : 526.18109 : 1"
268- sodipodi:type="inkscape:persp3d" />
269- <linearGradient
270- id="linearGradient3458-648">
271- <stop
272- id="stop2423"
273- offset="0"
274- style="stop-color:#bababa;stop-opacity:1;" />
275- <stop
276- id="stop2425"
277- offset="1"
278- style="stop-color:#ffffff;stop-opacity:0;" />
279- </linearGradient>
280- <linearGradient
281- id="linearGradient3412-967">
282- <stop
283- id="stop2429"
284- offset="0"
285- style="stop-color:#ffffff;stop-opacity:0.59836066;" />
286- <stop
287- id="stop2431"
288- offset="1"
289- style="stop-color:#bababa;stop-opacity:0;" />
290- </linearGradient>
291- </defs>
292- <metadata
293- id="metadata2423">
294- <rdf:RDF>
295- <cc:Work
296- rdf:about="">
297- <dc:format>image/svg+xml</dc:format>
298- <dc:type
299- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
300- <dc:creator>
301- <cc:Agent>
302- <dc:title>Nancy Runge &lt;nancy@twotoasts.de&gt;</dc:title>
303- </cc:Agent>
304- </dc:creator>
305- <cc:license
306- rdf:resource="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" />
307- </cc:Work>
308- </rdf:RDF>
309- </metadata>
310- <g
311- transform="translate(-280.66056,-644.09745)"
312- id="layer1"
313- inkscape:groupmode="layer"
314- inkscape:label="Layer 1">
315- <g
316- id="g2546"
317- style="fill:#ffffff;fill-opacity:1;stroke:#bcbcbc;stroke-opacity:1"
318- transform="matrix(2.7318355,0,0,2.7318355,-731.07518,-1421.3016)">
319- <path
320- sodipodi:nodetypes="ccsscccsc"
321- id="path3598"
322- d="M 479.0149,757.44485 C 463.33929,760.3524 390.05715,768.6009 373.75783,823.05659 C 368.99751,841.48441 371.67629,866.55457 392.88608,865.62945 C 394.38911,865.56465 394.54399,866.0597 395.07871,867.32475 C 403.8111,887.98406 426.11314,884.657 430.13518,876.12801 C 430.41248,875.53998 429.75994,876.1331 430.13518,876.12801 C 452.01909,891.1113 463.94687,870.37434 470.8404,851.89287 C 479.26032,835.85799 484.40756,769.09622 479.90163,773.41411 C 403.13312,846.97906 403.28006,782.18757 479.0149,757.44485"
323- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#bcbcbc;stroke-width:2.79349113000000004;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
324- <path
325- id="path3606"
326- d="M 394.6271,866.42646 C 389.11843,841.31269 395.51037,833.40754 398.10369,830.14819"
327- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#bcbcbc;stroke-width:2.79349113000000004;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
328- sodipodi:nodetypes="cc" />
329- <path
330- id="path3608"
331- d="M 430.04511,875.57142 C 422.884,860.41673 424.07276,847.90995 429.16085,838.58891"
332- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#bcbcbc;stroke-width:2.79349113000000004;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
333- sodipodi:nodetypes="cc" />
334- </g>
335- <g
336- id="g2551"
337- style="fill:#e8e8e8;fill-opacity:1;stroke:none"
338- transform="matrix(2.7318355,0,0,2.7318355,-731.59243,-1420.9344)">
339- <path
340- sodipodi:nodetypes="cccccccccccc"
341- id="path2553"
342- d="M 447.08573,768.31725 C 436.04919,774.1595 397.92257,781.58705 381.33359,820.27881 C 377.02863,833.88105 375.31278,851.44676 387.44516,857.54862 C 385.16801,848.06163 387.57514,834.11288 393.43272,827.57808 C 397.5473,821.96506 405.70797,826.00823 403.09775,831.29165 C 401.29067,836.46522 394.76631,843.8643 399.87669,863.28435 C 404.09154,874.85534 415.25599,879.58634 422.43347,873.92723 C 414.92666,858.12585 420.32228,825.17457 433.92305,832.69366 C 440.70334,836.82119 424.80942,848.38632 435.43821,869.81488 C 448.73626,880.75776 460.15899,863.55615 464.02222,850.63024 C 472.18961,832.82769 477.16809,790.8233 475.1786,786.29359 C 410.97397,845.50147 395.61545,794.24336 447.07098,768.23969"
343- style="fill:#e8e8e8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79349113;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
344- </g>
345- </g>
346-</svg>
347
348=== modified file 'extensions/CMakeLists.txt'
349--- extensions/CMakeLists.txt 2015-04-19 14:06:12 +0000
350+++ extensions/CMakeLists.txt 2015-06-10 13:21:27 +0000
351@@ -1,5 +1,7 @@
352-# Copyright (C) 2013 Christian Dywan <christian@twotoasts.de>
353+# Copyright (C) 2013-2014 Christian Dywan <christian@twotoasts.de>
354
355+include(ContainTest)
356+add_custom_target(check COMMAND "env" "CTEST_OUTPUT_ON_FAILURE=1" "${CMAKE_CTEST_COMMAND}")
357 set(EXTENSIONDIR "${CMAKE_INSTALL_FULL_LIBDIR}/${CMAKE_PROJECT_NAME}")
358 include_directories(
359 "${CMAKE_SOURCE_DIR}"
360@@ -11,19 +13,21 @@
361 ${OPTS_GTK_INCLUDE_DIRS}
362 ${CMAKE_BINARY_DIR}
363 "${CMAKE_BINARY_DIR}/midori"
364+ "${CMAKE_BINARY_DIR}/ipc"
365 )
366 file(GLOB EXTENSIONS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
367-if (HALF_BRO_INCOM_WEBKIT2)
368+# TODO: port to WebKit2
369 list(REMOVE_ITEM EXTENSIONS
370 "cookie-permissions"
371 "addons.c"
372 "formhistory"
373- "external-download-manager.vala"
374 "nojs"
375+<<<<<<< TREE
376 "nsplugin-manager.vala"
377 "tabs2one.c"
378+=======
379+>>>>>>> MERGE-SOURCE
380 )
381-endif ()
382
383 # FIXME: re-enable webmedia extension
384 # once we have working notifications on win
385@@ -31,6 +35,7 @@
386 list(REMOVE_ITEM EXTENSIONS "webmedia-now-playing.vala")
387 endif()
388
389+<<<<<<< TREE
390 # FIXME: not stable enough for release
391 if (NOT REVISION)
392 list(REMOVE_ITEM EXTENSIONS "tabs2one.c")
393@@ -52,83 +57,118 @@
394 )
395 endif ()
396 endforeach ()
397+=======
398+include(ParseArguments)
399+include(ValaPrecompile)
400+>>>>>>> MERGE-SOURCE
401
402-foreach(UNIT_SRC ${EXTENSIONS})
403- string(FIND ${UNIT_SRC} "." UNIT_EXTENSION)
404- if (UNIT_EXTENSION EQUAL -1)
405- file(GLOB UNIT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.c")
406- file(GLOB UNIT_FILES_VALA RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.vala")
407- if (UNIT_FILES_VALA)
408- include(ValaPrecompile)
409- vala_precompile(UNIT_SRC_C ${UNIT_SRC}
410- ${UNIT_FILES_VALA}
411+macro(build_extension name)
412+ set(source "${ARGN}")
413+ set(SOURCE_VALA "")
414+ foreach(FILE ${source})
415+ string(FIND ${FILE} ".web." WEB_EXTENSION)
416+ string(FIND ${FILE} ".vala" VALA_EXTENSION)
417+ if (WEB_EXTENSION GREATER -1)
418+ string(REPLACE ".vala" "" WEB_NAME "${name}_${FILE}")
419+ string(REPLACE "." "_" WEB_NAME "${WEB_NAME}")
420+ vala_precompile(WEB_EXTENSION_C "${WEB_NAME}"
421+ ${FILE}
422 PACKAGES
423- ${PKGS}
424+ ${PACKAGES_CORE}
425+ libsecret-1
426 OPTIONS
427 ${VALAFLAGS}
428 --use-header="${CMAKE_PROJECT_NAME}-core.h"
429 GENERATE_HEADER
430 "${UNIT_SRC}"
431 GENERATE_HEADER
432- ${UNIT}
433+ ${FILE}
434 CUSTOM_VAPIS
435+<<<<<<< TREE
436 ${EXTRA_VAPIS}
437 "${CMAKE_SOURCE_DIR}/midori/midori.vapi"
438 "${CMAKE_BINARY_DIR}/midori/${LIBMIDORI}.vapi"
439+=======
440+ "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-web-extension-4.0.vapi"
441+ "${CMAKE_BINARY_DIR}/ipc/${LIBMIDORI2}.vapi"
442+>>>>>>> MERGE-SOURCE
443 )
444- set(UNIT_FILES ${UNIT_FILES} ${UNIT_SRC_C})
445- endif ()
446- if (UNIT_FILES)
447- add_library(${UNIT_SRC} MODULE ${UNIT_FILES})
448- target_link_libraries(${UNIT_SRC}
449- ${LIBMIDORI}
450+ add_library(${WEB_NAME} MODULE ${WEB_EXTENSION_C})
451+ target_link_libraries(${WEB_NAME}
452+ ${LIBMIDORI2}
453 )
454- install(TARGETS ${UNIT_SRC}
455+ install(TARGETS ${WEB_NAME}
456 LIBRARY DESTINATION ${EXTENSIONDIR}
457 )
458- # extensions with vala code get the lenient VALA_CFLAGS
459- # others get the usual CFLAGS with -Wall and -Werror
460- if (UNIT_FILES_VALA)
461- set_target_properties(${UNIT_SRC} PROPERTIES
462- COMPILE_FLAGS ${VALA_CFLAGS}
463- )
464- else ()
465- set_target_properties(${UNIT_SRC} PROPERTIES
466- COMPILE_FLAGS ${CFLAGS}
467- )
468- endif ()
469+ # Extensions with Vala code get the lenient VALA_CFLAGS
470+ set_target_properties(${WEB_NAME} PROPERTIES
471+ COMPILE_FLAGS ${VALA_CFLAGS}
472+ )
473+ list(REMOVE_ITEM source ${FILE})
474+
475+ # Mandatory unit testing
476+ add_test(NAME "test-${WEB_NAME}" COMMAND $<TARGET_FILE:midori> -t $<TARGET_FILE:${WEB_NAME}>)
477+ contain_test("test-${WEB_NAME}" $<TARGET_FILE:midori> -t $<TARGET_FILE:${WEB_NAME}>)
478+ elseif (VALA_EXTENSION GREATER -1)
479+ list(APPEND SOURCE_VALA ${FILE})
480 endif ()
481- endif ()
482-endforeach ()
483-
484-foreach(UNIT_SRC ${EXTENSIONS})
485- string(FIND ${UNIT_SRC} ".vala" UNIT_EXTENSION)
486- if (UNIT_EXTENSION GREATER -1)
487- string(REPLACE ".vala" "" UNIT ${UNIT_SRC})
488- include(ValaPrecompile)
489- vala_precompile(UNIT_SRC_C ${UNIT}
490- ${UNIT_SRC}
491+ endforeach()
492+ if (SOURCE_VALA)
493+ vala_precompile(SOURCE_C ${name}
494+ ${SOURCE_VALA}
495 PACKAGES
496 ${PKGS}
497 OPTIONS
498 ${VALAFLAGS}
499 --use-header="${CMAKE_PROJECT_NAME}-core.h"
500 GENERATE_HEADER
501- ${UNIT}
502+ ${name}
503 CUSTOM_VAPIS
504- ${EXTRA_VAPIS}
505 "${CMAKE_SOURCE_DIR}/midori/midori.vapi"
506 "${CMAKE_BINARY_DIR}/midori/${LIBMIDORI}.vapi"
507 )
508- add_library(${UNIT} MODULE ${UNIT_SRC_C})
509- target_link_libraries(${UNIT}
510+ set(source ${SOURCE_C})
511+ endif ()
512+ if (source)
513+ add_library(${name} MODULE ${source})
514+ target_link_libraries(${name}
515 ${LIBMIDORI}
516 )
517- set_target_properties(${UNIT} PROPERTIES
518- COMPILE_FLAGS "${VALA_CFLAGS}"
519- )
520- install(TARGETS ${UNIT}
521+ install(TARGETS ${name}
522 LIBRARY DESTINATION ${EXTENSIONDIR}
523 )
524+ if (SOURCE_VALA)
525+ # Extensions with Vala code get the lenient VALA_CFLAGS
526+ set_target_properties(${name} PROPERTIES
527+ COMPILE_FLAGS ${VALA_CFLAGS}
528+ )
529+ else ()
530+ set_target_properties(${name} PROPERTIES
531+ COMPILE_FLAGS ${CFLAGS}
532+ )
533+ endif ()
534+ # Optional unit test
535+ add_test(NAME "test-${name}" COMMAND $<TARGET_FILE:midori> -t $<TARGET_FILE:${name}>)
536+ contain_test("test-${name}" $<TARGET_FILE:midori> -t $<TARGET_FILE:${name}>)
537+ endif ()
538+endmacro(build_extension)
539+
540+foreach(UNIT_SRC ${EXTENSIONS})
541+ string(FIND ${UNIT_SRC} ".c" UNIT_EXTENSION)
542+ if (UNIT_EXTENSION GREATER -1)
543+ string(REPLACE ".c" "" UNIT ${UNIT_SRC})
544+ build_extension(${UNIT} ${UNIT_SRC})
545+ endif ()
546+
547+ string(FIND ${UNIT_SRC} "." UNIT_EXTENSION)
548+ if (UNIT_EXTENSION EQUAL -1)
549+ file(GLOB UNIT_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${UNIT_SRC}/*.c" "${UNIT_SRC}/*.vala")
550+ build_extension(${UNIT_SRC} ${UNIT_FILES})
551+ endif ()
552+
553+ string(FIND ${UNIT_SRC} ".vala" UNIT_EXTENSION)
554+ if (UNIT_EXTENSION GREATER -1)
555+ string(REPLACE ".vala" "" UNIT ${UNIT_SRC})
556+ build_extension(${UNIT} ${UNIT_SRC})
557 endif ()
558 endforeach ()
559
560=== modified file 'extensions/about.vala'
561--- extensions/about.vala 2014-02-26 20:07:51 +0000
562+++ extensions/about.vala 2015-06-10 13:21:27 +0000
563@@ -15,11 +15,7 @@
564 public abstract string uri { get; set; }
565 public abstract void get_contents (Midori.View view, string uri);
566 protected void load_html (Midori.View view, string content, string uri) {
567- #if HAVE_WEBKIT2
568 view.web_view.load_html (content, uri);
569- #else
570- view.web_view.load_html_string (content, uri);
571- #endif
572 }
573 }
574
575@@ -91,6 +87,7 @@
576 private class Version : Page {
577 public override string uri { get; set; }
578 private GLib.HashTable<string, Page> about_pages;
579+ const string placeholder = "<em id=\"addons\">...</em>";
580
581 public Version (string alias, HashTable<string, Page> about_pages) {
582 this.uri = alias;
583@@ -104,13 +101,31 @@
584 return "<p>%s</p>".printf (links);
585 }
586
587+ async void add_addons (string html, Midori.View view, string uri) {
588+ GLib.StringBuilder replacement = new GLib.StringBuilder ();
589+ replacement.append ("<br><h2>Extensions:</h2>");
590+ bool debug = strcmp (Environment.get_variable ("MIDORI_DEBUG"), "addons") == 0;
591+ foreach (var addon in yield Midori.Addons.get_default ().list ()) {
592+ if (addon is Midori.ClassicExtension && (addon as Midori.ClassicExtension).intern && !debug)
593+ continue;
594+ if (addon is Midori.ClassicExtension && !((addon as Midori.ClassicExtension).is_active ()))
595+ continue;
596+ replacement.append_printf ("<tr><td><span style=\"%s\">%s</span>\t%s</td></tr>",
597+ addon.intern ? "font-style: italic" : "font-weight: bold",
598+ addon.name, addon.description);
599+ }
600+ this.load_html (view, html.replace (placeholder, replacement.str), uri);
601+ }
602+
603 public override void get_contents (Midori.View view, string uri) {
604 string contents = """<html>
605- <head><title>about:version</title></head>
606+ <head>
607+ <title>about:version</title>
608+ <meta name="theme-color" content="#00a132">
609+ </head>
610 <body>
611 <h1>a<span style="position: absolute; left: -1000px; top: -1000px">lias a=b; echo Copy carefully #</span>bout:version</h1>
612 <p>%s</p>
613- <img src="res://logo-shade.png" style="position: absolute; right: 15px; bottom: 15px; z-index: -9;">
614 <table>
615 <tr><td>Command line %s</td></tr>
616 %s
617@@ -137,44 +152,25 @@
618 GLib.StringBuilder video_formats = new GLib.StringBuilder ();
619 view.list_video_formats (video_formats, true);
620
621- GLib.StringBuilder ns_plugins = new GLib.StringBuilder ();
622- view.list_plugins (ns_plugins, true);
623-
624- /* TODO: list active extensions */
625-
626- this.load_html (view, contents.printf (
627+ string html = contents.printf (
628 _("Version numbers in brackets show the version used at runtime."),
629 Midori.Paths.get_command_line_str (true),
630 versions.str,
631 platform, sys_name, architecture != null ? architecture : "",
632 ident,
633 video_formats.str,
634- ns_plugins.str,
635- this.list_about_uris ()
636- ), uri);
637+ placeholder,
638+ this.list_about_uris ());
639+ this.load_html (view, html, uri);
640+
641+ add_addons.begin (html, view, uri);
642 }
643 }
644
645 private class Private : Page {
646 public override string uri { get; set; default = "about:private"; }
647 public override void get_contents (Midori.View view, string uri) {
648- this.load_html (view, """<html dir="ltr">
649- <head>
650- <title>%s</title>
651- <link rel="stylesheet" type="text/css" href="res://about.css">
652- </head>
653- <body>
654- <img id="logo" src="res://logo-shade.png" />
655- <div id="main" style="background-image: url(stock://dialog/gtk-dialog-info);">
656- <div id="text">
657- <h1>%s</h1>
658- <p class="message">%s</p><ul class=" suggestions"><li>%s</li><li>%s</li><li>%s</li></ul>
659- <p class="message">%s</p><ul class=" suggestions"><li>%s</li><li>%s</li><li>%s</li><li>%s</li></ul>
660- </div><br style="clear: both"></div>
661- </body>
662- </html>""".printf (
663- _("Private Browsing"), _("Private Browsing"),
664- _("Midori doesn't store any personal data:"),
665+ string suggestions = "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s".printf (
666 _("No history or web cookies are being saved."),
667 _("Extensions are disabled."),
668 _("HTML5 storage, local database and application caches are disabled."),
669@@ -183,7 +179,9 @@
670 _("DNS prefetching is disabled."),
671 _("The language and timezone are not revealed to websites."),
672 _("Flash and other Netscape plugins cannot be listed by websites.")
673- ), uri);
674+ );
675+ view.widget = new Midori.Oops (uri, "security-high", _("Private Browsing"),
676+ _("Midori doesn't store any personal data:"), "", suggestions);
677 }
678 }
679
680
681=== modified file 'extensions/adblock/extension.vala'
682--- extensions/adblock/extension.vala 2015-05-24 22:06:12 +0000
683+++ extensions/adblock/extension.vala 2015-06-10 13:21:27 +0000
684@@ -55,7 +55,6 @@
685 internal string? js_hider_function_body;
686 #endif
687
688-#if HAVE_WEBKIT2
689 #if !HAVE_WEBKIT2_3_91
690 public Extension.WebExtension (WebKit.WebExtension web_extension) {
691 init ();
692@@ -70,7 +69,6 @@
693 return request_handled (request.uri, web_page.uri);
694 }
695 #endif
696-#endif
697
698 public Extension () {
699 GLib.Object (name: _("Advertisement blocker"),
700@@ -87,7 +85,6 @@
701 }
702
703 void extension_activated (Midori.App app) {
704-#if HAVE_WEBKIT2
705 string cache_dir = Environment.get_user_cache_dir ();
706 string wk2path = Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "wk2ext");
707 Midori.Paths.mkdir_with_parents (wk2path);
708@@ -101,7 +98,6 @@
709 } catch (Error error) {
710 critical ("Failed to create WebKit2 link: %s", error.message);
711 }
712-#endif
713 init ();
714 foreach (var browser in app.get_browsers ())
715 browser_added (browser);
716@@ -123,7 +119,13 @@
717 browser.add_tab.connect (tab_added);
718 browser.remove_tab.connect (tab_removed);
719
720+<<<<<<< TREE
721 browser.add_action (status_icon);
722+=======
723+ var toggle_button = status_icon.add_button ();
724+ browser.statusbar.add (toggle_button);
725+ toggle_button.show ();
726+>>>>>>> MERGE-SOURCE
727 }
728
729 void browser_removed (Midori.Browser browser) {
730@@ -136,17 +138,11 @@
731
732 void tab_added (Midori.View view) {
733 view.navigation_requested.connect (navigation_requested);
734-#if !HAVE_WEBKIT2
735- view.web_view.resource_request_starting.connect (resource_requested);
736-#endif
737 view.notify["load-status"].connect (load_status_changed);
738 view.context_menu.connect (context_menu);
739 }
740
741 void tab_removed (Midori.View view) {
742-#if !HAVE_WEBKIT2
743- view.web_view.resource_request_starting.disconnect (resource_requested);
744-#endif
745 view.navigation_requested.disconnect (navigation_requested);
746 view.notify["load-status"].disconnect (load_status_changed);
747 view.context_menu.disconnect (context_menu);
748@@ -179,16 +175,6 @@
749 menu.add (action);
750 }
751
752-#if !HAVE_WEBKIT2
753- void resource_requested (WebKit.WebView web_view, WebKit.WebFrame frame,
754- WebKit.WebResource resource, WebKit.NetworkRequest request, WebKit.NetworkResponse? response) {
755-
756- if (request_handled (request.uri, web_view.uri)) {
757- request.set_uri ("about:blank");
758- }
759- }
760-#endif
761-
762 bool navigation_requested (Midori.Tab tab, string uri) {
763 if (uri.has_prefix ("abp:")) {
764 string parsed_uri = parse_subscription_uri (uri);
765@@ -367,12 +353,13 @@
766 }
767
768 void load_config () {
769+<<<<<<< TREE
770 #if HAVE_WEBKIT2
771 string config_dir = Path.build_filename (GLib.Environment.get_user_config_dir (), PACKAGE_NAME, "extensions", "libadblock." + GLib.Module.SUFFIX);
772+=======
773+ string config_dir = Path.build_filename (Environment.get_user_config_dir (), "midori", "extensions", "libadblock." + GLib.Module.SUFFIX);
774+>>>>>>> MERGE-SOURCE
775 Midori.Paths.mkdir_with_parents (config_dir);
776-#else
777- string config_dir = Midori.Paths.get_extension_config_dir ("adblock");
778-#endif
779 string presets = Midori.Paths.get_extension_preset_filename ("adblock", "config");
780 string filename = Path.build_filename (config_dir, "config");
781 config = new Config (filename, presets);
782@@ -473,14 +460,12 @@
783 }
784 }
785
786-#if HAVE_WEBKIT2
787 #if !HAVE_WEBKIT2_3_91
788 Adblock.Extension? filter;
789 public static void webkit_web_extension_initialize (WebKit.WebExtension web_extension) {
790 filter = new Adblock.Extension.WebExtension (web_extension);
791 }
792 #endif
793-#endif
794
795 public Midori.Extension extension_init () {
796 return new Adblock.Extension ();
797
798=== modified file 'extensions/adblock/widgets.vala'
799--- extensions/adblock/widgets.vala 2015-05-24 22:06:12 +0000
800+++ extensions/adblock/widgets.vala 2015-06-10 13:21:27 +0000
801@@ -96,15 +96,10 @@
802 public void add_subscription (string? uri) {
803 var dialog = new Gtk.Dialog.with_buttons (_("Configure Advertisement filters"),
804 null,
805-#if !HAVE_GTK3
806- Gtk.DialogFlags.NO_SEPARATOR |
807-#endif
808 Gtk.DialogFlags.DESTROY_WITH_PARENT,
809 Gtk.STOCK_HELP, Gtk.ResponseType.HELP,
810 Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE);
811-#if HAVE_GTK3
812 dialog.get_widget_for_response (Gtk.ResponseType.HELP).get_style_context ().add_class ("help_button");
813-#endif
814 dialog.set_icon_name (Gtk.STOCK_PROPERTIES);
815 dialog.set_response_sensitive (Gtk.ResponseType.HELP, false);
816
817@@ -255,9 +250,6 @@
818 public void show () {
819 this.dialog = new Gtk.Dialog.with_buttons (_("Edit rule"),
820 null,
821-#if !HAVE_GTK3
822- Gtk.DialogFlags.NO_SEPARATOR |
823-#endif
824 Gtk.DialogFlags.DESTROY_WITH_PARENT,
825 Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
826 Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT);
827
828=== modified file 'extensions/colorful-tabs.c'
829--- extensions/colorful-tabs.c 2013-10-30 00:19:27 +0000
830+++ extensions/colorful-tabs.c 2015-06-10 13:21:27 +0000
831@@ -240,11 +240,6 @@
832 void
833 extension_test (void)
834 {
835- #ifndef HAVE_WEBKIT2
836- g_object_set_data (G_OBJECT (webkit_get_default_session ()),
837- "midori-session-initialized", (void*)1);
838- #endif
839-
840 /* TODO: Add test which uses favicon codepath */
841
842 g_test_add_func ("/extensions/colorful_tabs/hostname_colour", test_colour_for_hostname);
843
844=== added file 'extensions/colorful-tabs.web.vala'
845--- extensions/colorful-tabs.web.vala 1970-01-01 00:00:00 +0000
846+++ extensions/colorful-tabs.web.vala 2015-06-10 13:21:27 +0000
847@@ -0,0 +1,69 @@
848+/*
849+ Copyright (C) 2015 Christian Dywan <christian@twotoasts.de>
850+
851+ This library is free software; you can redistribute it and/or
852+ modify it under the terms of the GNU Lesser General Public
853+ License as published by the Free Software Foundation; either
854+ version 2.1 of the License, or (at your option) any later version.
855+
856+ See the file COPYING for the full license text.
857+*/
858+
859+namespace ColorfulTabs {
860+ [DBus (name = "org.midori.ColorfulTabs")]
861+ public class Extension : Midori.WebExtension {
862+ public Extension (WebKit.WebExtension extension, Variant user_data) {
863+ Object (user_data: user_data, token: "colorfultabs");
864+ extension.page_created.connect (page_created);
865+ }
866+
867+ void page_created (WebKit.WebPage page) {
868+ page.document_loaded.connect (document_loaded);
869+ add_icon.begin (page.get_id ());
870+ }
871+
872+ async void add_icon (uint64 page_id) {
873+ var icon = new Midori.ContextItem ("click", _("Click me!"), null, _("Click me!")).to_user_data ();
874+ try {
875+ var tab = yield Midori.TabProxy.get_by_id (page_id);
876+ uint64 id = yield tab.add_action (icon);
877+ debug ("Adding icon %s with id %s", icon.print (true), id.to_string ());
878+ } catch (Error error) {
879+ critical ("Failed to set icon %s for page %s: %s\n", icon.print (true), page_id.to_string (), error.message);
880+ }
881+ }
882+
883+ void document_loaded (WebKit.WebPage page) {
884+ var nodes = page.get_dom_document ().get_elements_by_name ("theme-color");
885+ if (nodes.length == 0)
886+ return;
887+
888+ var meta = nodes.item (0) as WebKit.DOM.HTMLMetaElement;
889+ debug ("Color %s picked up from meta tag on %s", meta.content, page.uri);
890+ set_color.begin (page.get_id (), meta.content);
891+ }
892+
893+ async void set_color (uint64 page_id, string color) {
894+ try {
895+ var tab = yield Midori.TabProxy.get_by_id (page_id);
896+ tab.color = color;
897+ } catch (Error error) {
898+ critical ("Failed to propagate color %s for page %s: %s\n", color, page_id.to_string (), error.message);
899+ }
900+ }
901+ }
902+}
903+
904+ColorfulTabs.Extension? colorful_tabs;
905+public void webkit_web_extension_initialize_with_user_data (WebKit.WebExtension extension, Variant user_data) {
906+ colorful_tabs = new ColorfulTabs.Extension (extension, user_data);
907+}
908+
909+void colorful_tabs_html () {
910+ /* TODO */
911+}
912+
913+public void extension_test () {
914+ Test.add_func ("/colorful_tabs/html", colorful_tabs_html);
915+}
916+
917
918=== modified file 'extensions/cookie-manager/cookie-manager.c'
919--- extensions/cookie-manager/cookie-manager.c 2013-07-29 21:05:02 +0000
920+++ extensions/cookie-manager/cookie-manager.c 2015-06-10 13:21:27 +0000
921@@ -280,15 +280,9 @@
922 COOKIE_MANAGER_COL_NAME, GTK_SORT_ASCENDING);
923
924 /* setup soup */
925-#ifdef HAVE_WEBKIT2
926 gchar *filename = midori_paths_get_config_filename_for_writing ("cookies.db");
927 priv->jar = soup_cookie_jar_sqlite_new (filename, FALSE);
928 g_free(filename);
929-#else
930- SoupSession *session = webkit_get_default_session();
931- priv->jar = SOUP_COOKIE_JAR(soup_session_get_feature(session, soup_cookie_jar_get_type()));
932- g_object_ref(priv->jar);
933-#endif
934 g_signal_connect(priv->jar, "changed", G_CALLBACK(cookie_manager_jar_changed_cb), self);
935
936 cookie_manager_refresh_store(self);
937
938=== modified file 'extensions/cookie-permissions/cookie-permission-manager-preferences-window.c'
939--- extensions/cookie-permissions/cookie-permission-manager-preferences-window.c 2014-01-01 22:39:30 +0000
940+++ extensions/cookie-permissions/cookie-permission-manager-preferences-window.c 2015-06-10 13:21:27 +0000
941@@ -735,12 +735,8 @@
942
943 /* Get content area to add gui controls to */
944 priv->contentArea=gtk_dialog_get_content_area(GTK_DIALOG(self));
945-#ifdef HAVE_GTK3
946 vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
947 gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
948-#else
949- vbox=gtk_vbox_new(FALSE, 0);
950-#endif
951
952 /* Set up dialog */
953 dialogTitle=_("Configure cookie permission");
954@@ -786,12 +782,8 @@
955 gtk_tree_sortable_set_sort_column_id(sortableList, DOMAIN_COLUMN, GTK_SORT_ASCENDING);
956
957 /* Set up domain addition widgets */
958-#ifdef HAVE_GTK3
959 hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
960 gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
961-#else
962- hbox=gtk_hbox_new(FALSE, 0);
963-#endif
964
965 priv->addDomainEntry=gtk_entry_new();
966 gtk_entry_set_max_length(GTK_ENTRY(priv->addDomainEntry), 64);
967@@ -824,10 +816,6 @@
968 /* Set up cookie domain list */
969 priv->list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(priv->listStore));
970
971-#ifndef HAVE_GTK3
972- gtk_widget_set_size_request(priv->list, -1, 300);
973-#endif
974-
975 priv->listSelection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->list));
976 gtk_tree_selection_set_mode(priv->listSelection, GTK_SELECTION_MULTIPLE);
977 g_signal_connect_swapped(priv->listSelection, "changed", G_CALLBACK(_cookie_permission_manager_preferences_changed_selection), self);
978@@ -853,21 +841,15 @@
979 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
980
981 scrolled=gtk_scrolled_window_new(NULL, NULL);
982-#ifdef HAVE_GTK3
983 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), height*10);
984-#endif
985 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
986 gtk_container_add(GTK_CONTAINER(scrolled), priv->list);
987 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
988 gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 5);
989
990 /* Set up cookie domain list management buttons */
991-#ifdef HAVE_GTK3
992 hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
993 gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
994-#else
995- hbox=gtk_hbox_new(FALSE, 0);
996-#endif
997
998 priv->deleteButton=gtk_button_new_from_stock(GTK_STOCK_DELETE);
999 gtk_widget_set_sensitive(priv->deleteButton, FALSE);
1000@@ -883,12 +865,8 @@
1001 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5);
1002
1003 /* Add "unknown-policy" combo */
1004-#ifdef HAVE_GTK3
1005 hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1006 gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
1007-#else
1008- hbox=gtk_hbox_new(FALSE, 0);
1009-#endif
1010 widget=gtk_label_new(_("Policy for cookies from domains not in the list: "));
1011 gtk_container_add(GTK_CONTAINER(hbox), widget);
1012
1013
1014=== modified file 'extensions/cookie-permissions/cookie-permission-manager.c'
1015--- extensions/cookie-permissions/cookie-permission-manager.c 2014-06-14 03:40:37 +0000
1016+++ extensions/cookie-permissions/cookie-permission-manager.c 2015-06-10 13:21:27 +0000
1017@@ -545,10 +545,6 @@
1018
1019 /* Create list and set up columns of list */
1020 list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(listStore));
1021-#ifndef HAVE_GTK3
1022- gtk_widget_set_size_request(list, -1, 100);
1023-#endif
1024-
1025 renderer=gtk_cell_renderer_text_new();
1026 column=gtk_tree_view_column_new_with_attributes(_("Domain"),
1027 renderer,
1028@@ -589,9 +585,7 @@
1029 gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
1030
1031 scrolled=gtk_scrolled_window_new(NULL, NULL);
1032-#ifdef HAVE_GTK3
1033 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), 100);
1034-#endif
1035 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1036 gtk_container_add(GTK_CONTAINER(scrolled), list);
1037 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
1038
1039=== added file 'extensions/donottrack.web.vala'
1040--- extensions/donottrack.web.vala 1970-01-01 00:00:00 +0000
1041+++ extensions/donottrack.web.vala 2015-06-10 13:21:27 +0000
1042@@ -0,0 +1,141 @@
1043+/*
1044+ Copyright (C) 2014 Christian Dywan <christian@twotoasts.de>
1045+
1046+ This library is free software; you can redistribute it and/or
1047+ modify it under the terms of the GNU Lesser General Public
1048+ License as published by the Free Software Foundation; either
1049+ version 2.1 of the License, or (at your option) any later version.
1050+
1051+ See the file COPYING for the full license text.
1052+*/
1053+
1054+namespace DoNotTrack {
1055+ struct Stain {
1056+ string key;
1057+ string host;
1058+ }
1059+ const Stain[] stains = {
1060+ /* analytics.google.com */
1061+ { "utm_source" },
1062+ { "utm_medium" },
1063+ { "utm_term" },
1064+ { "utm_content" },
1065+ { "utm_campaign" },
1066+ { "utm_reader" },
1067+ /* metrika.yandex.ru */
1068+ { "yclid" },
1069+ /* youtube.com */
1070+ { "feature", "youtube.com" },
1071+ /* facebook.com */
1072+ { "fb_action_ids" },
1073+ { "fb_action_types" },
1074+ { "fb_ref" },
1075+ { "fb_source" },
1076+ { "action_object_map" },
1077+ { "action_type_map" },
1078+ { "action_ref_map" },
1079+ { "ref", "www.facebook.com" },
1080+ { "fref", "www.facebook.com" },
1081+ { "hc_location", "www.facebook.com" },
1082+ /* imdb.com */
1083+ { "ref_", "imdb.com" },
1084+ /* addons.mozilla.org */
1085+ { "src", "addons.mozilla.org" }
1086+ };
1087+
1088+ public class Cleanser : Object {
1089+ File config;
1090+ public bool active = false;
1091+
1092+ public Cleanser () {
1093+ config = File.new_for_path (Midori.Paths.get_config_filename_for_reading ("config"));
1094+ /* TODO: Determine if removal of dirt is enabled */
1095+ active = true;
1096+ }
1097+ bool has_stains (string host, string key) {
1098+ /*
1099+ See also https://addons.mozilla.org/en/firefox/addon/pure-url/
1100+ as well as Epiphany for a C version
1101+ */
1102+ foreach (var stain in stains) {
1103+ if (stain.host != null && host.has_suffix (stain.host))
1104+ continue;
1105+ if (stain.key == key)
1106+ return true;
1107+ }
1108+ return false;
1109+ }
1110+
1111+ public string? remove_dirt (string uri) {
1112+ string? host = uri.split ("/")[2];
1113+ string? query = uri.split ("?")[1];
1114+ if (query == null)
1115+ return null;
1116+ string[] variables = query.split("&");
1117+ string spotless = "";
1118+ foreach (string variable in variables) {
1119+ // Note: a single & may result in a null key
1120+ string? key = variable.split ("=")[0];
1121+ if (key != null && !has_stains (host, key))
1122+ spotless += variable + "&";
1123+ }
1124+ string pure = uri.replace (query, spotless);
1125+ return pure;
1126+ }
1127+ }
1128+
1129+ public class Extension : Object {
1130+ bool debug = false;
1131+ Cleanser cleanser;
1132+
1133+ public Extension (WebKit.WebExtension extension) {
1134+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "donottrack") == 0)
1135+ debug = true;
1136+ cleanser = new Cleanser ();
1137+ extension.page_created.connect (page_created);
1138+ }
1139+
1140+ void page_created (WebKit.WebPage page) {
1141+ page.send_request.connect (send_request);
1142+ }
1143+
1144+ bool send_request (WebKit.URIRequest request, WebKit.URIResponse? redirect) {
1145+ if (!cleanser.active)
1146+ return false;
1147+
1148+ Soup.MessageHeaders? headers = request.get_http_headers ();
1149+ if (headers == null)
1150+ return false;
1151+
1152+ /*
1153+ First instance: ask nicely to be left alone
1154+ See http://tools.ietf.org/id/draft-mayer-do-not-track-00.txt
1155+ */
1156+ headers.append ("DNT", "1");
1157+
1158+ /* Second instance: deal with what won't play nice */
1159+ string? pure = cleanser.remove_dirt (request.uri);
1160+ if (pure != null) {
1161+ request.uri = pure;
1162+ if (debug)
1163+ stdout.printf ("DoNotTrack: Removed dirt from %s leaving only %s\n", request.uri, pure);
1164+ }
1165+ return false;
1166+ }
1167+ }
1168+}
1169+
1170+DoNotTrack.Extension? do_not_track;
1171+public void webkit_web_extension_initialize_with_user_data (WebKit.WebExtension extension, Variant user_data) {
1172+ Midori.Paths.init_with_user_data (user_data);
1173+ do_not_track = new DoNotTrack.Extension (extension);
1174+}
1175+
1176+void do_not_track_urls () {
1177+ /* TODO */
1178+}
1179+
1180+public void extension_test () {
1181+ Test.add_func ("/donottrack/urls", do_not_track_urls);
1182+}
1183+
1184
1185=== modified file 'extensions/external-download-manager.vala'
1186--- extensions/external-download-manager.vala 2015-03-18 21:18:11 +0000
1187+++ extensions/external-download-manager.vala 2015-06-10 13:21:27 +0000
1188@@ -36,6 +36,7 @@
1189 if (download_type == Midori.DownloadType.SAVE) {
1190 var dlReq = new DownloadRequest ();
1191
1192+<<<<<<< TREE
1193 #if HAVE_WEBKIT2
1194 dlReq.uri = download.request.get_uri ();
1195 weak Soup.MessageHeaders headers = download.request.get_http_headers ();
1196@@ -45,6 +46,10 @@
1197 var message = request.get_message ();
1198 weak Soup.MessageHeaders headers = message.request_headers;
1199 #endif
1200+=======
1201+ dlReq.uri = download.get_request ().get_uri ();
1202+ weak MessageHeaders headers = download.get_request ().get_http_headers ();
1203+>>>>>>> MERGE-SOURCE
1204
1205 dlReq.auth = headers.get ("Authorization");
1206 dlReq.referer = headers.get ("Referer");
1207@@ -101,12 +106,15 @@
1208 }
1209
1210 construct {
1211- #if HAVE_WEBKIT2
1212 var session= new Session ();
1213+<<<<<<< TREE
1214 #else
1215 var session = WebKit.get_default_session ();
1216 #endif
1217 this.cookie_jar = session.get_feature (typeof (Soup.CookieJar)) as Soup.CookieJar;
1218+=======
1219+ this.cookie_jar = session.get_feature (typeof (CookieJar)) as CookieJar;
1220+>>>>>>> MERGE-SOURCE
1221 }
1222 }
1223
1224@@ -269,15 +277,9 @@
1225 this.input = new Gtk.Entry ();
1226 this.input.set_text (this.commandline.get_string ("commandline"));
1227
1228-
1229-#if HAVE_GTK3
1230 Gtk.Box vbox = get_content_area () as Gtk.Box;
1231 vbox.pack_start (text, false, false, 0);
1232 vbox.pack_start (this.input, false, true, 0);
1233-#else
1234- this.vbox.pack_start (text, false, false, 0);
1235- this.vbox.pack_start (this.input, false, true, 0);
1236-#endif
1237
1238 this.add_button (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
1239 this.add_button (Gtk.STOCK_APPLY, Gtk.ResponseType.APPLY);
1240
1241=== modified file 'extensions/feed-panel/feed-panel.c'
1242--- extensions/feed-panel/feed-panel.c 2013-10-25 21:49:56 +0000
1243+++ extensions/feed-panel/feed-panel.c 2015-06-10 13:21:27 +0000
1244@@ -800,12 +800,8 @@
1245 NULL);
1246 gtk_widget_show (treeview);
1247
1248-#if GTK_CHECK_VERSION(3,0,0)
1249 font_desc = (PangoFontDescription*)gtk_style_context_get_font (
1250 gtk_widget_get_style_context (treeview), GTK_STATE_FLAG_NORMAL);
1251-#else
1252- font_desc = treeview->style->font_desc;
1253-#endif
1254 family = pango_font_description_get_family (font_desc);
1255 size = pango_font_description_get_size (font_desc) / PANGO_SCALE;
1256 settings = midori_web_settings_new ();
1257
1258=== modified file 'extensions/feed-panel/main.c'
1259--- extensions/feed-panel/main.c 2013-08-12 19:21:06 +0000
1260+++ extensions/feed-panel/main.c 2015-06-10 13:21:27 +0000
1261@@ -348,7 +348,7 @@
1262
1263 dialog = gtk_dialog_new_with_buttons (
1264 _("New feed"), GTK_WINDOW (priv->browser),
1265- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
1266+ GTK_DIALOG_DESTROY_WITH_PARENT,
1267 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1268 GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
1269 NULL);
1270
1271=== modified file 'extensions/formhistory/formhistory.c'
1272--- extensions/formhistory/formhistory.c 2013-11-26 19:08:06 +0000
1273+++ extensions/formhistory/formhistory.c 2015-06-10 13:21:27 +0000
1274@@ -99,7 +99,7 @@
1275 alive = 1;
1276 title = _("Form history");
1277 dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
1278- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
1279+ GTK_DIALOG_DESTROY_WITH_PARENT,
1280 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1281 GTK_STOCK_OK, GTK_RESPONSE_OK,
1282 NULL);
1283
1284=== modified file 'extensions/history-list.vala'
1285--- extensions/history-list.vala 2015-03-20 16:24:07 +0000
1286+++ extensions/history-list.vala 2015-06-10 13:21:27 +0000
1287@@ -102,12 +102,13 @@
1288 Gtk.Requisition requisition;
1289 int height;
1290 int max_lines = 10;
1291+<<<<<<< TREE
1292 #if HAVE_GTK3
1293 requisition = Gtk.Requisition();
1294+=======
1295+ requisition = Requisition();
1296+>>>>>>> MERGE-SOURCE
1297 this.treeview.get_preferred_size(out requisition, null);
1298-#else
1299- this.treeview.size_request (out requisition);
1300-#endif
1301 Gtk.ListStore model = this.treeview.get_model () as Gtk.ListStore;
1302 int length = model.iter_n_children(null);
1303 if (length > max_lines) {
1304@@ -212,12 +213,6 @@
1305
1306 model.get_iter (out iter, path);
1307 model.get (iter, TabTreeCells.TREE_CELL_POINTER, out view);
1308-#if !HAVE_GTK3
1309- /* removing the selected cursor causes a segfault when using GTK2 */
1310- if (path.prev () == false)
1311- path.next ();
1312- this.treeview.set_cursor (path, column, false);
1313-#endif
1314
1315 /*
1316 FixMe: the retrun value of `Gtk.ListStore.remove` should be checked
1317@@ -314,6 +309,7 @@
1318 }
1319
1320 private void create_widgets () {
1321+<<<<<<< TREE
1322 Gtk.ListStore model;
1323 Gtk.TreeIter iter;
1324 Gtk.TreeIter? active_iter = null;
1325@@ -322,6 +318,16 @@
1326 var renderer = new Gtk.CellRendererText ();
1327
1328 var label = new Gtk.Label ( _("Tab closing behavior"));
1329+=======
1330+ Gtk.ListStore model;
1331+ TreeIter iter;
1332+ TreeIter? active_iter = null;
1333+
1334+ var table = new Table (1, 2, true);
1335+ var renderer = new CellRendererText ();
1336+
1337+ var label = new Label ( _("Tab closing behavior"));
1338+>>>>>>> MERGE-SOURCE
1339 table.attach_defaults (label, 0, 1, 0, 1);
1340
1341 var tab_closing_behavior = this.hl_manager.get_integer ("TabClosingBehavior");
1342@@ -359,11 +365,7 @@
1343 table.attach_defaults (proxy, 0, 2, 1, 2);
1344 #endif
1345
1346-#if HAVE_GTK3
1347 (get_content_area() as Gtk.Box).pack_start (table, false, true, 0);
1348-#else
1349- this.vbox.pack_start (table, false, true, 0);
1350-#endif
1351
1352 this.add_button (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
1353 this.add_button (Gtk.STOCK_APPLY, Gtk.ResponseType.APPLY);
1354
1355=== added file 'extensions/hsts.web.vala'
1356--- extensions/hsts.web.vala 1970-01-01 00:00:00 +0000
1357+++ extensions/hsts.web.vala 2015-06-10 13:21:27 +0000
1358@@ -0,0 +1,173 @@
1359+/*
1360+ Copyright (C) 2012-2014 Christian Dywan <christian@twotoasts.de>
1361+
1362+ This library is free software; you can redistribute it and/or
1363+ modify it under the terms of the GNU Lesser General Public
1364+ License as published by the Free Software Foundation; either
1365+ version 2.1 of the License, or (at your option) any later version.
1366+
1367+ See the file COPYING for the full license text.
1368+*/
1369+
1370+namespace HSTS {
1371+ public class Directive {
1372+ public Soup.Date? expires = null;
1373+ public bool sub_domains = false;
1374+
1375+ public Directive (bool include_sub_domains) {
1376+ expires = new Soup.Date.from_now (int.MAX);
1377+ sub_domains = include_sub_domains;
1378+ }
1379+
1380+ public Directive.from_header (string header) {
1381+ var param_list = Soup.header_parse_param_list (header);
1382+ if (param_list == null)
1383+ return;
1384+
1385+ string? max_age = param_list.lookup ("max-age");
1386+ if (max_age != null)
1387+ expires = new Soup.Date.from_now (max_age.to_int ());
1388+ if ("includeSubDomains" in header)
1389+ sub_domains = true;
1390+ Soup.header_free_param_list (param_list);
1391+ }
1392+
1393+ public bool is_valid () {
1394+ return expires != null && !expires.is_past ();
1395+ }
1396+ }
1397+
1398+ public class Whitelist : Object {
1399+ HashTable<string, Directive> whitelist;
1400+ string preset = "/etc/xdg/midori/hsts";
1401+ File config;
1402+
1403+ public Whitelist () {
1404+ whitelist = new HashTable<string, Directive> (str_hash, str_equal);
1405+ read_cache.begin (File.new_for_path (preset));
1406+ config = File.new_for_path (Midori.Paths.get_config_filename_for_writing ("hsts"));
1407+ read_cache.begin (config);
1408+ }
1409+
1410+ async void read_cache (File file) {
1411+ try {
1412+ var stream = new DataInputStream (yield file.read_async ());
1413+ do {
1414+ string? line = yield stream.read_line_async ();
1415+ if (line == null)
1416+ break;
1417+ string[] parts = line.split (" ", 2);
1418+ if (parts[0] == null || parts[1] == null)
1419+ break;
1420+ var directive = new Directive.from_header (parts[1]);
1421+ if (directive.is_valid ())
1422+ append_to_whitelist (parts[0], directive);
1423+ } while (true);
1424+ } catch (IOError.NOT_FOUND exist_error) {
1425+ /* It's no error if no cache file exists */
1426+ } catch (Error error) {
1427+ warning ("Failed to read cache %s: %s", file.get_path (), error.message);
1428+ }
1429+ }
1430+
1431+ public bool should_secure_host (string host) {
1432+ Directive? directive = whitelist.lookup (host);
1433+ if (directive == null)
1434+ directive = whitelist.lookup ("*." + host);
1435+ return directive != null && directive.is_valid ();
1436+ }
1437+
1438+ void append_to_whitelist (string host, Directive directive) {
1439+ whitelist.insert (host, directive);
1440+ if (directive.sub_domains)
1441+ whitelist.insert ("*." + host, directive);
1442+ }
1443+
1444+ async void append_to_cache (string host, string header) {
1445+ /* FIXME: Don't write in private browsing */
1446+
1447+ try {
1448+ var stream = yield config.append_to_async (FileCreateFlags.NONE);
1449+ yield stream.write_async ((host + " " + header + "\n").data);
1450+ yield stream.flush_async ();
1451+ }
1452+ catch (Error error) {
1453+ critical ("Failed to update %s: %s", config.get_path (), error.message);
1454+ }
1455+ }
1456+
1457+ public Directive? strict_transport_security_handled (string host, Soup.MessageHeaders headers) {
1458+ unowned string? hsts = headers.get_one ("Strict-Transport-Security");
1459+ if (hsts == null)
1460+ return null;
1461+
1462+ var directive = new Directive.from_header (hsts);
1463+ if (directive.is_valid ()) {
1464+ append_to_whitelist (host, directive);
1465+ append_to_cache.begin (host, hsts);
1466+ }
1467+ return directive;
1468+ }
1469+
1470+ }
1471+
1472+ public class Extension : Object {
1473+ Whitelist whitelist;
1474+ bool debug = false;
1475+
1476+ public Extension (WebKit.WebExtension extension) {
1477+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "hsts") == 0)
1478+ debug = true;
1479+ whitelist = new Whitelist ();
1480+ extension.page_created.connect (page_created);
1481+ }
1482+
1483+ void page_created (WebKit.WebPage page) {
1484+ page.send_request.connect (send_request);
1485+ }
1486+
1487+ bool send_request (WebKit.URIRequest request, WebKit.URIResponse? redirect) {
1488+ Soup.MessageHeaders? headers = request.get_http_headers ();
1489+ if (headers == null || !request.uri.contains ("/"))
1490+ return false;
1491+
1492+ string host = request.uri.split ("/")[2];
1493+ if (whitelist.should_secure_host (host)) {
1494+ request.uri = request.uri.replace ("http://", "https://");
1495+ if (debug)
1496+ stdout.printf ("HSTS: Enforce %s\n", host);
1497+ } else if (request.uri.has_prefix ("http://")) {
1498+ var directive = whitelist.strict_transport_security_handled (host, headers);
1499+ if (debug)
1500+ stdout.printf ("HSTS: %s valid? %s\n",
1501+ host, directive != null ? directive.is_valid ().to_string () : "/");
1502+ }
1503+ return false;
1504+ }
1505+ }
1506+}
1507+
1508+HSTS.Extension? hsts;
1509+public void webkit_web_extension_initialize_with_user_data (WebKit.WebExtension extension, Variant user_data) {
1510+ Midori.Paths.init_with_user_data (user_data);
1511+ hsts = new HSTS.Extension (extension);
1512+}
1513+
1514+void hsts_directive () {
1515+ HSTS.Directive d;
1516+ d = new HSTS.Directive.from_header ("max-age=31536000");
1517+ assert (d.is_valid () && !d.sub_domains);
1518+ d = new HSTS.Directive.from_header ("max-age=15768000 ; includeSubDomains");
1519+ assert (d.is_valid () && d.sub_domains);
1520+
1521+ /* Invalid */
1522+ d = new HSTS.Directive.from_header ("");
1523+ assert (!d.is_valid () && !d.sub_domains);
1524+ d = new HSTS.Directive.from_header ("includeSubDomains");
1525+ assert (!d.is_valid () && d.sub_domains);
1526+}
1527+
1528+public void extension_test () {
1529+ Test.add_func ("/hsts/directive", hsts_directive);
1530+}
1531+
1532
1533=== added file 'extensions/login-manager.web.vala'
1534--- extensions/login-manager.web.vala 1970-01-01 00:00:00 +0000
1535+++ extensions/login-manager.web.vala 2015-06-10 13:21:27 +0000
1536@@ -0,0 +1,456 @@
1537+namespace LoginManager {
1538+ errordomain VaultError {
1539+ INIT,
1540+ FAIL,
1541+ }
1542+
1543+ struct FormAuth {
1544+ string form_url;
1545+ string action_url;
1546+ string username_element;
1547+ string username_value;
1548+ string password_element;
1549+ // Those values aren't checked when checking whether a FormAuth corresponds to a HTML form
1550+ string password_value;
1551+ bool blacklisted;
1552+ DateTime last_update;
1553+ }
1554+
1555+ interface Vault : Object {
1556+ public abstract void initialize () throws VaultError;
1557+ public abstract void add_login (FormAuth fa) throws VaultError;
1558+ public abstract void remove_login (FormAuth fa) throws VaultError;
1559+ public abstract List<FormAuth?> get_logins (bool exclude_blacklisted) throws VaultError;
1560+ public abstract List<FormAuth?> lookup_login (FormAuth fa, bool ignore_username) throws VaultError;
1561+ }
1562+
1563+ class SecretVault : Object, Vault {
1564+ private Secret.Schema schema;
1565+ private Secret.Service service;
1566+
1567+ public List<FormAuth?> lookup_login (FormAuth fa, bool ignore_username) throws VaultError {
1568+ var list = new List <FormAuth?> ();
1569+ var attrs = new HashTable<string,string> (str_hash, str_equal);
1570+
1571+ attrs.insert ("form_url", fa.form_url);
1572+ attrs.insert ("action_url", fa.action_url);
1573+ attrs.insert ("username_element", fa.username_element);
1574+ attrs.insert ("password_element", fa.password_element);
1575+ if (ignore_username == false)
1576+ attrs.insert ("username_value", fa.username_value);
1577+
1578+ try {
1579+ var res = service.search_sync (schema, attrs, Secret.SearchFlags.ALL, null);
1580+
1581+ foreach (var item in res) {
1582+ list.append (secret_to_fa (item));
1583+ }
1584+ }
1585+ catch (Error err) {
1586+ throw new VaultError.FAIL ("Could not query the login");
1587+ }
1588+
1589+ return list;
1590+ }
1591+
1592+ FormAuth secret_to_fa (Secret.Item item) throws VaultError {
1593+ var item_attrs = item.get_attributes ();
1594+
1595+ var fa = new FormAuth ();
1596+ fa.form_url = item_attrs["form_url"];
1597+ fa.action_url = item_attrs["action_url"];
1598+ fa.username_element = item_attrs["username_element"];
1599+ fa.username_value = item_attrs["username_value"];
1600+ fa.password_element = item_attrs["password_element"];
1601+ fa.blacklisted = bool.parse(item_attrs["blacklisted"]);
1602+ fa.last_update = new DateTime.from_unix_local (item_attrs["last_update"].to_int64 ());
1603+
1604+ try {
1605+ item.load_secret_sync ();
1606+ }
1607+ catch (Error err) {
1608+ throw new VaultError.FAIL ("Could not thaw the secret");
1609+ }
1610+
1611+ var secret = item.get_secret ();
1612+ if (secret == null)
1613+ throw new VaultError.FAIL ("Could not retrieve the stored password!");
1614+ fa.password_value = secret.get_text ();
1615+
1616+ return fa;
1617+ }
1618+
1619+ public List<FormAuth?> get_logins (bool exclude_blacklisted) throws VaultError {
1620+ var list = new List <FormAuth?> ();
1621+ var attrs = new HashTable<string,string> (str_hash, str_equal);
1622+
1623+ if (exclude_blacklisted == true) {
1624+ attrs.insert ("blacklisted", false.to_string ());
1625+ }
1626+
1627+ try {
1628+ var res = service.search_sync (schema, attrs, Secret.SearchFlags.ALL | Secret.SearchFlags.LOAD_SECRETS, null);
1629+
1630+ foreach (var item in res) {
1631+ list.append (secret_to_fa (item));
1632+ }
1633+ }
1634+ catch (Error err) {
1635+ throw new VaultError.FAIL ("Could not query the logins");
1636+ }
1637+
1638+ return list;
1639+ }
1640+
1641+ public void remove_login (FormAuth fa) throws VaultError {
1642+ try {
1643+ Secret.password_clear_sync (schema, null,
1644+ "form_url", fa.form_url,
1645+ "action_url", fa.action_url,
1646+ "username_element", fa.username_element,
1647+ "username_value", fa.username_value,
1648+ "password_element", fa.password_element,
1649+ "blacklisted", fa.blacklisted.to_string ());
1650+ }
1651+ catch (Error err) {
1652+ throw new VaultError.FAIL ("Could not remove the login");
1653+ }
1654+ }
1655+
1656+ public void add_login (FormAuth fa) throws VaultError {
1657+ var now = new DateTime.now_local ();
1658+
1659+ try {
1660+ Secret.password_store_sync (schema, null,
1661+ "midori saved login for %s".printf (fa.form_url),
1662+ fa.password_value, null,
1663+ "form_url", fa.form_url,
1664+ "action_url", fa.action_url,
1665+ "username_element", fa.username_element,
1666+ "username_value", fa.username_value,
1667+ "password_element", fa.password_element,
1668+ "last_update", now.to_unix ().to_string (),
1669+ "blacklisted", fa.blacklisted.to_string ());
1670+ }
1671+ catch (Error err) {
1672+ throw new VaultError.FAIL ("Could not add the login");
1673+ }
1674+ }
1675+
1676+ public void initialize () throws VaultError {
1677+ // Setup the schema, we need to serialize all the FormAuth fields minus the
1678+ // password_value one since that's handled by libsecret separately.
1679+ schema = new Secret.Schema ("org.midori.loginmanager",
1680+ Secret.SchemaFlags.NONE,
1681+ "form_url", Secret.SchemaAttributeType.STRING,
1682+ "action_url", Secret.SchemaAttributeType.STRING,
1683+ "username_element", Secret.SchemaAttributeType.STRING,
1684+ "username_value", Secret.SchemaAttributeType.STRING,
1685+ "password_element", Secret.SchemaAttributeType.STRING,
1686+ "last_update", Secret.SchemaAttributeType.STRING,
1687+ "blacklisted", Secret.SchemaAttributeType.STRING);
1688+
1689+ // Try to check whether a supported keyring-manager is running
1690+ try {
1691+ service = Secret.Service.get_sync (Secret.ServiceFlags.OPEN_SESSION);
1692+ }
1693+ catch (Error err) {
1694+ throw new VaultError.INIT ("No supported keyring is available");
1695+ }
1696+ }
1697+ }
1698+
1699+ public class Extension : Midori.WebExtension {
1700+ Vault vault;
1701+
1702+ public Extension (WebKit.WebExtension extension, Variant user_data) {
1703+ Object (user_data: user_data, token: "loginmanager");
1704+
1705+ stderr.printf ("Oh, hello!\n");
1706+
1707+ try {
1708+ vault = new SecretVault ();
1709+
1710+ // TODO: libsecret doesn't really unlock the keyring until the first store operation
1711+ // and returns no error :(
1712+ vault.initialize ();
1713+
1714+ foreach (var login in vault.get_logins (false)) {
1715+ stderr.printf ("url : %s\nuser : \"%s\"\npass : \"%s\"\n",
1716+ login.form_url,
1717+ login.username_value,
1718+ login.password_value);
1719+ }
1720+ }
1721+ catch (Error err) {
1722+ critical (err.message);
1723+ }
1724+
1725+ extension.page_created.connect ((page) => {
1726+ page.document_loaded.connect (on_document_loaded);
1727+ });
1728+ }
1729+
1730+ bool is_password_elem (WebKit.DOM.HTMLElement elem) {
1731+ if (elem is WebKit.DOM.HTMLInputElement) {
1732+ var input_elem = (WebKit.DOM.HTMLInputElement)elem;
1733+ var input_type = input_elem.get_input_type ().down ();
1734+
1735+ return !input_elem.has_attribute ("readonly") &&
1736+ !input_elem.has_attribute ("disabled") &&
1737+ input_type == "password";
1738+ }
1739+
1740+ return false;
1741+ }
1742+
1743+ bool is_username_elem (WebKit.DOM.HTMLElement elem) {
1744+ if (elem is WebKit.DOM.HTMLInputElement) {
1745+ var input_elem = (WebKit.DOM.HTMLInputElement)elem;
1746+ var input_type = input_elem.get_input_type ().down ();
1747+
1748+ return !input_elem.has_attribute ("readonly") &&
1749+ !input_elem.has_attribute ("disabled") &&
1750+ (input_type == "text" || input_type == "email");
1751+ }
1752+
1753+ return false;
1754+ }
1755+
1756+
1757+ bool find_logins (WebKit.DOM.HTMLFormElement form,
1758+ out WebKit.DOM.HTMLInputElement username,
1759+ out WebKit.DOM.HTMLInputElement password) {
1760+ username = null;
1761+ password = null;
1762+
1763+ var form_el = form.get_elements ();
1764+
1765+ var password_idx = -1;
1766+
1767+ // Try to find the password field and save the index
1768+ for (var i = 0; i < form_el.get_length (); i++) {
1769+ var elem = form_el.item (i) as WebKit.DOM.HTMLElement;
1770+
1771+ if (is_password_elem (elem)) {
1772+ password_idx = i;
1773+ break;
1774+ }
1775+ }
1776+
1777+ if (password_idx < 0)
1778+ return false;
1779+
1780+ var username_idx = -1;
1781+
1782+ // Scan backwards the form elements starting from the password one found above;
1783+ // hopefully the username element is the first suitable one preceding it.
1784+ for (var i = password_idx - 1; i >= 0; i--) {
1785+ var elem = form_el.item (i) as WebKit.DOM.HTMLElement;
1786+
1787+ if (is_username_elem (elem)) {
1788+ username_idx = i;
1789+ break;
1790+ }
1791+ }
1792+
1793+ if (username_idx < 0)
1794+ return false;
1795+
1796+ username = form_el.item (username_idx) as WebKit.DOM.HTMLInputElement;
1797+ password = form_el.item (password_idx) as WebKit.DOM.HTMLInputElement;
1798+
1799+ return true;
1800+ }
1801+
1802+ FormAuth? webkit_form_to_fa (string url, WebKit.DOM.HTMLFormElement form) {
1803+ WebKit.DOM.HTMLInputElement username_field;
1804+ WebKit.DOM.HTMLInputElement password_field;
1805+
1806+ // Return null if we can't find a pair of username/password fields
1807+ if (!find_logins (form, out username_field, out password_field))
1808+ return null;
1809+
1810+ var fa = new FormAuth ();
1811+
1812+ fa.form_url = url;
1813+ fa.action_url = form.get_action ();
1814+
1815+ fa.username_element = username_field.get_name ();
1816+ fa.username_value = username_field.get_value ();
1817+ fa.password_element = password_field.get_name ();
1818+ fa.password_value = password_field.get_value ();
1819+ fa.blacklisted = false;
1820+
1821+ return fa;
1822+ }
1823+
1824+#if 0
1825+ bool fa_matches_webkit_form (FormAuth fa, string url, WebKit.DOM.HTMLFormElement form) {
1826+ WebKit.DOM.HTMLInputElement username_field;
1827+ WebKit.DOM.HTMLInputElement password_field;
1828+
1829+ if (fa.form_url != url)
1830+ return false;
1831+
1832+ // Blacklisted ones don't match any form
1833+ if (fa.blacklisted == true)
1834+ return false;
1835+
1836+ // Return null if we can't find a pair of username/password fields
1837+ if (!find_logins (form, out username_field, out password_field))
1838+ return false;
1839+
1840+ if (fa.username_element != username_field.get_name () ||
1841+ fa.password_element != password_field.get_name ())
1842+ return false;
1843+
1844+ if (fa.username_value != username_field.get_value ())
1845+ return false;
1846+
1847+ return true;
1848+ }
1849+#endif
1850+
1851+ void on_form_submit (string url, WebKit.DOM.HTMLFormElement form) {
1852+ WebKit.DOM.HTMLInputElement username_field;
1853+ WebKit.DOM.HTMLInputElement password_field;
1854+
1855+ if (!find_logins (form, out username_field, out password_field))
1856+ return;
1857+
1858+ stderr.printf ("Store as %s\n", url);
1859+
1860+ var username_value = username_field.get_value ();
1861+ var username_not_emtpy = (username_value._strip () != "");
1862+
1863+ var password_value = password_field.get_value ();
1864+ var password_not_emtpy = (password_value._strip () != "");
1865+
1866+ // There's no point in saving an empty form
1867+ if (!username_not_emtpy || !password_not_emtpy)
1868+ return;
1869+
1870+ var fa = webkit_form_to_fa (url, form);
1871+ if (fa == null)
1872+ return;
1873+
1874+ // TODO: Ask the user here, the response should be either yes/no or never
1875+
1876+ try {
1877+ bool should_update = true;
1878+
1879+ // Check whether there's another login for this website with the same username.
1880+ // In that case update it after asking the user if they wish to do so.
1881+ foreach (var rfa in vault.lookup_login (fa, false)) {
1882+ vault.remove_login (rfa);
1883+ }
1884+
1885+ vault.add_login (fa);
1886+ }
1887+ catch (Error err) {
1888+ critical (err.message);
1889+ }
1890+ }
1891+
1892+ void fill_form (string url, WebKit.DOM.HTMLFormElement form) {
1893+ WebKit.DOM.HTMLInputElement username_field;
1894+ WebKit.DOM.HTMLInputElement password_field;
1895+
1896+ if (!find_logins (form, out username_field, out password_field))
1897+ return;
1898+
1899+ var username_value = username_field.get_value ();
1900+ var username_not_emtpy = (username_value._strip () != "");
1901+
1902+ stderr.printf ("Username is \"%s\"\n", username_value);
1903+
1904+ var fa = webkit_form_to_fa (url, form);
1905+ if (fa == null)
1906+ return;
1907+
1908+ // Check if we have a password for the account
1909+ try {
1910+ var results = vault.lookup_login (fa, !username_not_emtpy);
1911+
1912+ // No login present for the website
1913+ if (results.length () == 0) {
1914+ stderr.printf ("No login found for the website\n");
1915+ password_field.set_attribute ("style", "background-color:red");
1916+ return;
1917+ }
1918+
1919+ // TODO : Check if the website is blacklisted
1920+
1921+ // There's at least one login saved for this website
1922+ // If the 'username' entry is filled then try to autocomplete the form
1923+ if (username_not_emtpy) {
1924+ foreach (var login in results) {
1925+ if (username_value == login.username_value) {
1926+ password_field.set_attribute ("style", "background-color:green");
1927+ password_field.set_value (login.password_value);
1928+ break;
1929+ }
1930+ }
1931+ }
1932+ else {
1933+ var first = results.nth_data (0);
1934+
1935+ // If the 'username' entry is empty then fill it with the first one available
1936+ username_field.set_value (first.username_value);
1937+ password_field.set_value (first.password_value);
1938+ password_field.set_attribute ("style", "background-color:blue");
1939+ }
1940+
1941+ // There's more than one login saved for this website, show the menu icon
1942+ if (results.length () > 1) {
1943+ stderr.printf ("[TODO] The menu icon should appear now\n");
1944+ password_field.set_attribute ("style", "background-color:yellow");
1945+ }
1946+ }
1947+ catch (Error err) {
1948+ warning (err.message);
1949+ }
1950+ }
1951+
1952+ private void on_document_loaded (WebKit.WebPage page) {
1953+ var document = page.get_dom_document ();
1954+ var forms = document.get_forms ();
1955+
1956+ for (var i = 0; i < forms.get_length (); i++) {
1957+ WebKit.DOM.HTMLInputElement username;
1958+ WebKit.DOM.HTMLInputElement password;
1959+
1960+ var form = (WebKit.DOM.HTMLFormElement)forms.item (i);
1961+ var form_uri = new Soup.URI (form.get_action ());
1962+
1963+ if (find_logins (form, out username, out password)) {
1964+ fill_form (form_uri.get_host (), form);
1965+
1966+ // Save the login on 'submit'
1967+ form.add_event_listener_with_closure ("submit",
1968+ () => {
1969+ on_form_submit (form_uri.get_host (), form);
1970+ },
1971+ false);
1972+
1973+ // Check if there's a valid login when the username field loses focus
1974+ username.add_event_listener_with_closure ("blur",
1975+ () => {
1976+ fill_form (form_uri.get_host (), form);
1977+ },
1978+ false);
1979+ }
1980+ }
1981+ }
1982+ }
1983+}
1984+
1985+LoginManager.Extension? loginmgr;
1986+public void webkit_web_extension_initialize_with_user_data (WebKit.WebExtension extension, Variant
1987+ user_data) {
1988+ loginmgr = new LoginManager.Extension (extension, user_data);
1989+}
1990+
1991+public void extension_test () {
1992+}
1993
1994=== modified file 'extensions/nojs/nojs-preferences.c'
1995--- extensions/nojs/nojs-preferences.c 2014-05-09 14:47:53 +0000
1996+++ extensions/nojs/nojs-preferences.c 2015-06-10 13:21:27 +0000
1997@@ -839,12 +839,8 @@
1998
1999 /* Get content area to add gui controls to */
2000 priv->contentArea=gtk_dialog_get_content_area(GTK_DIALOG(self));
2001-#if GTK_CHECK_VERSION (3, 0, 0)
2002 vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
2003 gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
2004-#else
2005- vbox=gtk_vbox_new(FALSE, 0);
2006-#endif
2007
2008 /* Set up dialog */
2009 dialogTitle=_("Configure NoJS");
2010@@ -887,12 +883,8 @@
2011 gtk_tree_sortable_set_sort_column_id(sortableList, DOMAIN_COLUMN, GTK_SORT_ASCENDING);
2012
2013 /* Set up domain addition widgets */
2014-#ifdef HAVE_GTK3
2015 hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2016 gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
2017-#else
2018- hbox=gtk_hbox_new(FALSE, 0);
2019-#endif
2020
2021 priv->addDomainEntry=gtk_entry_new();
2022 gtk_entry_set_max_length(GTK_ENTRY(priv->addDomainEntry), 64);
2023@@ -925,10 +917,6 @@
2024 /* Set up domain list view */
2025 priv->list=gtk_tree_view_new_with_model(GTK_TREE_MODEL(priv->listStore));
2026
2027-#if !GTK_CHECK_VERSION (3, 0, 0)
2028- gtk_widget_set_size_request(priv->list, -1, 300);
2029-#endif
2030-
2031 priv->listSelection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->list));
2032 gtk_tree_selection_set_mode(priv->listSelection, GTK_SELECTION_MULTIPLE);
2033 g_signal_connect_swapped(priv->listSelection, "changed", G_CALLBACK(_nojs_preferences_changed_selection), self);
2034@@ -954,21 +942,15 @@
2035 gtk_tree_view_append_column(GTK_TREE_VIEW(priv->list), column);
2036
2037 scrolled=gtk_scrolled_window_new(NULL, NULL);
2038-#if GTK_CHECK_VERSION (3, 0, 0)
2039 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), height*10);
2040-#endif
2041 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2042 gtk_container_add(GTK_CONTAINER(scrolled), priv->list);
2043 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
2044 gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 5);
2045
2046 /* Set up JavaScript domain list management buttons */
2047-#if GTK_CHECK_VERSION (3, 0, 0)
2048 hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2049 gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
2050-#else
2051- hbox=gtk_hbox_new(FALSE, 0);
2052-#endif
2053
2054 priv->deleteButton=gtk_button_new_from_stock(GTK_STOCK_DELETE);
2055 gtk_widget_set_sensitive(priv->deleteButton, FALSE);
2056
2057=== modified file 'extensions/nojs/nojs.c'
2058--- extensions/nojs/nojs.c 2014-05-09 14:47:53 +0000
2059+++ extensions/nojs/nojs.c 2015-06-10 13:21:27 +0000
2060@@ -508,7 +508,7 @@
2061 statusbarIcon=gtk_button_new();
2062 gtk_button_set_relief(GTK_BUTTON(statusbarIcon), GTK_RELIEF_NONE);
2063 gtk_widget_show_all(statusbarIcon);
2064- gtk_box_pack_end(GTK_BOX(statusbar), statusbarIcon, FALSE, FALSE, 0);
2065+ gtk_container_add(GTK_CONTAINER(statusbar), statusbarIcon);
2066 g_object_set_data_full(G_OBJECT(inBrowser), "nojs-statusicon", g_object_ref(statusbarIcon), (GDestroyNotify)gtk_widget_destroy);
2067
2068 /* Connect signals */
2069
2070=== removed file 'extensions/nsplugin-manager.vala'
2071--- extensions/nsplugin-manager.vala 2013-06-19 20:27:53 +0000
2072+++ extensions/nsplugin-manager.vala 1970-01-01 00:00:00 +0000
2073@@ -1,71 +0,0 @@
2074-/*
2075- Copyright (C) 2012 André Stösel <andre@stoesel.de>
2076-
2077- This library is free software; you can redistribute it and/or
2078- modify it under the terms of the GNU Lesser General Public
2079- License as published by the Free Software Foundation; either
2080- version 2.1 of the License, or (at your option) any later version.
2081-
2082- See the file COPYING for the full license text.
2083-*/
2084-
2085-namespace NSPlugins {
2086- private int active_plugins = 0;
2087-
2088- private class Extension : Midori.Extension {
2089- protected WebKit.WebPlugin plugin;
2090-
2091- void activated (Midori.App app) {
2092- active_plugins += 1;
2093- this.plugin.set_enabled (true);
2094- app.settings.enable_plugins = active_plugins > 0;
2095- }
2096-
2097- void deactivated () {
2098- Midori.App app = this.get_app ();
2099- active_plugins -= 1;
2100- this.plugin.set_enabled (false);
2101- app.settings.enable_plugins = active_plugins > 0;
2102- }
2103-
2104- internal Extension (WebKit.WebPlugin plugin) {
2105- string desc = plugin.get_description ();
2106- try {
2107- var regex = new Regex ("<a.+href.+>(.+)</a>");
2108- desc = regex.replace (desc, -1, 0, "<u>\\1</u>");
2109- desc = desc.replace ("<br>", "\n");
2110- }
2111- catch (Error error) { }
2112- GLib.Object (stock_id: Midori.Stock.PLUGINS,
2113- name: plugin.get_name (),
2114- description: desc,
2115- use_markup: true,
2116- key: GLib.Path.get_basename (plugin.get_path ()),
2117- version: "(%s)".printf ("Netscape plugins"),
2118- authors: "");
2119-
2120- this.plugin = plugin;
2121- this.plugin.set_enabled (false);
2122-
2123- this.activate.connect (activated);
2124- this.deactivate.connect (deactivated);
2125- }
2126- }
2127-}
2128-
2129-public Katze.Array? extension_init () {
2130- if (!Midori.WebSettings.has_plugin_support ())
2131- return null;
2132-
2133- var extensions = new Katze.Array( typeof (Midori.Extension));
2134- WebKit.WebPluginDatabase pdb = WebKit.get_web_plugin_database ();
2135- SList<WebKit.WebPlugin> plugins = pdb.get_plugins ();
2136-
2137- foreach (WebKit.WebPlugin plugin in plugins) {
2138- if (Midori.WebSettings.skip_plugin (plugin.get_path ()))
2139- continue;
2140- extensions.add_item (new NSPlugins.Extension (plugin));
2141- }
2142- return extensions;
2143-}
2144-
2145
2146=== modified file 'extensions/open-with.vala'
2147--- extensions/open-with.vala 2015-03-24 03:11:10 +0000
2148+++ extensions/open-with.vala 2015-06-10 13:21:27 +0000
2149@@ -157,9 +157,6 @@
2150 transient_for = browser;
2151
2152 title = _("Custom…");
2153-#if !HAVE_GTK3
2154- has_separator = false;
2155-#endif
2156 destroy_with_parent = true;
2157 set_icon_name (Gtk.STOCK_OPEN);
2158 resizable = false;
2159@@ -368,11 +365,7 @@
2160
2161 var browser = Midori.Browser.get_for_widget (widget);
2162 transient_for = browser;
2163-
2164 title = _("Choose application");
2165-#if !HAVE_GTK3
2166- has_separator = false;
2167-#endif
2168 destroy_with_parent = true;
2169 set_icon_name (Gtk.STOCK_OPEN);
2170 resizable = true;
2171@@ -557,11 +550,7 @@
2172 renderer.set ("markup",
2173 Markup.printf_escaped ("<b>%s</b>\n%s",
2174 desc, mime_type),
2175-#if HAVE_GTK3
2176 "max-width-chars", 30,
2177-#else
2178- "width-chars", 30,
2179-#endif
2180 "ellipsize", Pango.EllipsizeMode.END);
2181 }
2182
2183
2184=== modified file 'extensions/shortcuts.c'
2185--- extensions/shortcuts.c 2013-03-23 01:37:12 +0000
2186+++ extensions/shortcuts.c 2015-06-10 13:21:27 +0000
2187@@ -167,7 +167,7 @@
2188
2189 dialog_title = _("Customize Keyboard shortcuts");
2190 dialog = gtk_dialog_new_with_buttons (dialog_title, GTK_WINDOW (browser),
2191- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
2192+ GTK_DIALOG_DESTROY_WITH_PARENT,
2193 #if !HAVE_OSX
2194 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
2195 #endif
2196
2197=== modified file 'extensions/status-clock.c'
2198--- extensions/status-clock.c 2013-06-26 21:54:50 +0000
2199+++ extensions/status-clock.c 2015-06-10 13:21:27 +0000
2200@@ -105,7 +105,7 @@
2201 label = gtk_label_new (NULL);
2202
2203 statusbar = katze_object_get_object (browser, "statusbar");
2204- gtk_box_pack_end (GTK_BOX (statusbar), label, FALSE, FALSE, 0);
2205+ gtk_container_add (GTK_CONTAINER (statusbar), label);
2206
2207 g_object_set_data (G_OBJECT (browser), "clock-label", label);
2208 g_object_set_data (G_OBJECT (browser), "clock-extension", extension);
2209
2210=== modified file 'extensions/statusbar-features.c'
2211--- extensions/statusbar-features.c 2015-06-06 12:32:23 +0000
2212+++ extensions/statusbar-features.c 2015-06-10 13:21:27 +0000
2213@@ -34,33 +34,6 @@
2214 MidoriExtension* extension);
2215
2216 static void
2217-statusbar_features_toolbar_notify_toolbar_style_cb (GtkWidget* toolbar,
2218- GParamSpec* pspec,
2219- GtkWidget* button)
2220-{
2221- GtkToolbarStyle style = katze_object_get_enum (toolbar, "toolbar-style");
2222- const gchar* text = g_object_get_data (G_OBJECT (button), "feature-label");
2223- switch (style)
2224- {
2225- case GTK_TOOLBAR_BOTH:
2226- case GTK_TOOLBAR_BOTH_HORIZ:
2227- gtk_button_set_label (GTK_BUTTON (button), text);
2228- gtk_widget_show (gtk_button_get_image (GTK_BUTTON (button)));
2229- break;
2230- case GTK_TOOLBAR_TEXT:
2231- gtk_button_set_label (GTK_BUTTON (button), text);
2232- gtk_widget_hide (gtk_button_get_image (GTK_BUTTON (button)));
2233- break;
2234- case GTK_TOOLBAR_ICONS:
2235- gtk_button_set_label (GTK_BUTTON (button), "");
2236- gtk_widget_show (gtk_button_get_image (GTK_BUTTON (button)));
2237- break;
2238- default:
2239- g_assert_not_reached ();
2240- }
2241-}
2242-
2243-static void
2244 statusbar_features_browser_notify_tab_cb (MidoriBrowser* browser,
2245 GParamSpec* pspec,
2246 GtkWidget* combobox)
2247@@ -85,8 +58,6 @@
2248 GtkWidget* toolbar = katze_object_get_object (browser, "navigationbar");
2249
2250 gtk_widget_destroy (bbox);
2251- g_signal_handlers_disconnect_matched (toolbar, G_SIGNAL_MATCH_FUNC,
2252- 0, -1, NULL, statusbar_features_toolbar_notify_toolbar_style_cb, NULL);
2253 g_object_unref (toolbar);
2254 g_signal_handlers_disconnect_by_func (
2255 extension, statusbar_features_deactivate_cb, bbox);
2256@@ -149,14 +120,12 @@
2257
2258 if (!strcmp (property, "auto-load-images"))
2259 {
2260- g_object_set_data (G_OBJECT (button), "feature-label", _("Images"));
2261 image = gtk_image_new_from_stock (STOCK_IMAGE, GTK_ICON_SIZE_MENU);
2262 gtk_button_set_image (GTK_BUTTON (button), image);
2263 gtk_widget_set_tooltip_text (button, _("Load images automatically"));
2264 }
2265 else if (!strcmp (property, "enable-javascript"))
2266 {
2267- g_object_set_data (G_OBJECT (button), "feature-label", _("Scripts"));
2268 image = gtk_image_new_from_stock (STOCK_SCRIPT, GTK_ICON_SIZE_MENU);
2269 gtk_button_set_image (GTK_BUTTON (button), image);
2270 gtk_widget_set_tooltip_text (button, _("Enable scripts"));
2271@@ -165,16 +134,18 @@
2272 {
2273 if (!midori_web_settings_has_plugin_support ())
2274 gtk_widget_hide (button);
2275- g_object_set_data (G_OBJECT (button), "feature-label", _("Netscape plugins"));
2276 image = gtk_image_new_from_stock (MIDORI_STOCK_PLUGINS, GTK_ICON_SIZE_MENU);
2277 gtk_button_set_image (GTK_BUTTON (button), image);
2278 gtk_widget_set_tooltip_text (button, _("Enable Netscape plugins"));
2279+<<<<<<< TREE
2280 }
2281 if (GTK_IS_TOOLBAR (toolbar) && GTK_IS_BUTTON (button))
2282 {
2283 statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
2284 g_signal_connect (toolbar, "notify::toolbar-style",
2285 G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
2286+=======
2287+>>>>>>> MERGE-SOURCE
2288 }
2289 return button;
2290 }
2291@@ -225,7 +196,7 @@
2292 gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
2293 }
2294 gtk_widget_show_all (bbox);
2295- gtk_box_pack_end (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
2296+ gtk_container_add (GTK_CONTAINER (statusbar), bbox);
2297 g_object_unref (statusbar);
2298 g_object_unref (toolbar);
2299
2300
2301=== modified file 'extensions/tabby.vala'
2302--- extensions/tabby.vala 2015-04-19 14:42:11 +0000
2303+++ extensions/tabby.vala 2015-06-10 13:21:27 +0000
2304@@ -236,12 +236,7 @@
2305 }
2306 }
2307
2308-#if HAVE_GTK3
2309 protected bool delete_event (Gtk.Widget widget, Gdk.EventAny event) {
2310-#else
2311- protected bool delete_event (Gtk.Widget widget, Gdk.Event event) {
2312-#endif
2313-
2314 this.close ();
2315 return false;
2316
2317
2318=== modified file 'extensions/transfers.vala'
2319--- extensions/transfers.vala 2014-04-23 05:40:37 +0000
2320+++ extensions/transfers.vala 2015-06-10 13:21:27 +0000
2321@@ -36,23 +36,11 @@
2322 internal double progress { get {
2323 return Midori.Download.get_progress (download);
2324 } }
2325-#if HAVE_WEBKIT2
2326 public bool succeeded { get; protected set; default = false; }
2327 public bool finished { get; protected set; default = false; }
2328 internal string destination { get {
2329 return download.destination;
2330 } }
2331-#else
2332- internal bool succeeded { get {
2333- return download.status == WebKit.DownloadStatus.FINISHED;
2334- } }
2335- internal bool finished { get {
2336- return Midori.Download.is_finished (download);
2337- } }
2338- internal string destination { get {
2339- return download.destination_uri;
2340- } }
2341-#endif
2342
2343 internal Transfer (WebKit.Download download) {
2344 poll_source = Timeout.add(1000/10, () => {
2345@@ -60,7 +48,11 @@
2346 return true;
2347 });
2348 this.download = download;
2349+<<<<<<< TREE
2350 #if HAVE_WEBKIT2
2351+=======
2352+ download.notify["estimated-progress"].connect (transfer_changed);
2353+>>>>>>> MERGE-SOURCE
2354 download.finished.connect (() => {
2355 succeeded = finished = true;
2356 changed ();
2357@@ -74,6 +66,7 @@
2358 Source.remove (poll_source);
2359 poll_source = 0;
2360 });
2361+<<<<<<< TREE
2362 #else
2363 download.notify["status"].connect (() => {
2364 changed ();
2365@@ -83,6 +76,8 @@
2366 }
2367 });
2368 #endif
2369+=======
2370+>>>>>>> MERGE-SOURCE
2371 }
2372 }
2373
2374@@ -328,9 +323,7 @@
2375
2376 var box = new Gtk.HBox (false, 0);
2377 progress = new Gtk.ProgressBar ();
2378-#if HAVE_GTK3
2379 progress.show_text = true;
2380-#endif
2381 progress.ellipsize = Pango.EllipsizeMode.MIDDLE;
2382 string filename = Midori.Download.get_basename_for_display (transfer.destination);
2383 progress.text = filename;
2384@@ -501,11 +494,7 @@
2385 transfer.removed ();
2386 }
2387
2388-#if HAVE_GTK3
2389 bool browser_closed (Gtk.Widget widget, Gdk.EventAny event) {
2390-#else
2391- bool browser_closed (Gtk.Widget widget, Gdk.Event event) {
2392-#endif
2393 var browser = widget as Midori.Browser;
2394 if (pending_transfers (array)) {
2395 var dialog = new Gtk.MessageDialog (browser,
2396@@ -530,11 +519,7 @@
2397 browser.panel.append_page (viewable);
2398 widgets.append (viewable);
2399 var toolbar = new Toolbar (array);
2400-#if HAVE_GTK3
2401- browser.statusbar.pack_end (toolbar, false, false);
2402-#else
2403- browser.statusbar.pack_start (toolbar, false, false);
2404-#endif
2405+ browser.add_toolbar (toolbar);
2406 widgets.append (toolbar);
2407 // TODO: popover
2408 // TODO: progress in dock item
2409
2410=== added directory 'ipc'
2411=== added file 'ipc/CMakeLists.txt'
2412--- ipc/CMakeLists.txt 1970-01-01 00:00:00 +0000
2413+++ ipc/CMakeLists.txt 2015-06-10 13:21:27 +0000
2414@@ -0,0 +1,47 @@
2415+include(ValaPrecompile)
2416+
2417+set(LIBMIDORI2_VERSION 0.6.0)
2418+set(LIBMIDORI2_SOVERSION 0)
2419+file(GLOB LIBMIDORI2_SOURCE *.vala)
2420+
2421+vala_precompile(LIBMIDORI2_SOURCE_C ${LIBMIDORI2}
2422+ ${LIBMIDORI2_SOURCE}
2423+PACKAGES
2424+ ${PACKAGES_CORE}
2425+OPTIONS
2426+ ${VALAFLAGS}
2427+GENERATE_VAPI
2428+ "${LIBMIDORI2}"
2429+GENERATE_HEADER
2430+ "${LIBMIDORI2}"
2431+)
2432+
2433+add_library("${LIBMIDORI2}" SHARED ${LIBMIDORI2_SOURCE_C})
2434+target_link_libraries("${LIBMIDORI2}"
2435+ ${DEPS_LIBRARIES}
2436+ )
2437+set_target_properties("${LIBMIDORI2}" PROPERTIES
2438+ COMPILE_FLAGS "${VALA_CFLAGS}"
2439+ POSITION_INDEPENDENT_CODE ON
2440+ VERSION ${LIBMIDORI2_VERSION}
2441+ SOVERSION ${LIBMIDORI2_SOVERSION}
2442+ )
2443+
2444+include_directories(
2445+ ${CMAKE_SOURCE_DIR}
2446+ ${CMAKE_CURRENT_SOURCE_DIR}
2447+ ${CMAKE_BINARY_DIR}
2448+ ${DEPS_INCLUDE_DIRS}
2449+ ${OPTS_INCLUDE_DIRS}
2450+ ${DEPS_GTK_INCLUDE_DIRS}
2451+ )
2452+if (WIN32)
2453+ install(TARGETS ${LIBMIDORI2}
2454+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR}
2455+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
2456+ )
2457+else ()
2458+ install(TARGETS ${LIBMIDORI2}
2459+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
2460+ )
2461+endif ()
2462
2463=== added file 'ipc/ipc-contextaction.vala'
2464--- ipc/ipc-contextaction.vala 1970-01-01 00:00:00 +0000
2465+++ ipc/ipc-contextaction.vala 2015-06-10 13:21:27 +0000
2466@@ -0,0 +1,56 @@
2467+/*
2468+ Copyright (C) 2013-2015 Christian Dywan <christian@twotoasts.de>
2469+
2470+ This library is free software; you can redistribute it and/or
2471+ modify it under the terms of the GNU Lesser General Public
2472+ License as published by the Free Software Foundation; either
2473+ version 2.1 of the License, or (at your option) any later version.
2474+
2475+ See the file COPYING for the full license text.
2476+*/
2477+
2478+namespace Midori {
2479+ /* A context item that make a menu, toolbar or button.
2480+ Since: 0.6.0 */
2481+ public class ContextItem : Gtk.Action {
2482+ List<Gtk.Action> children;
2483+ public ContextItem (string name, string? label, string? tooltip, string? stock_id) {
2484+ GLib.Object (name: name, label: label, tooltip: tooltip, stock_id: stock_id);
2485+ children = new List<ContextItem> ();
2486+ }
2487+
2488+ public Variant to_user_data () {
2489+ var user_data = new HashTable<string, string> (str_hash, str_equal);
2490+ user_data.insert ("name", name);
2491+ user_data.insert ("label", label ?? "");
2492+ user_data.insert ("tooltip", tooltip ?? "");
2493+ user_data.insert ("stock_id", stock_id ?? "");
2494+ return user_data;
2495+ }
2496+
2497+ /*
2498+ The action label will be escaped for mnemonics so for example
2499+ "a_fairy_tale" will not get accel keys on "f" or "t".
2500+ */
2501+ public ContextItem.escaped (string name, string label, string? tooltip, string? stock_id) {
2502+ string? escaped_label = label.replace ("_", "__");
2503+ GLib.Object (name: name, label: escaped_label, tooltip: tooltip, stock_id: stock_id);
2504+ children = new List<ContextItem> ();
2505+ }
2506+
2507+ public void add (Gtk.Action? action) {
2508+ if (action == null) {
2509+ add (new SeparatorContextItem ());
2510+ return;
2511+ }
2512+
2513+ children.append (action);
2514+ }
2515+ }
2516+
2517+ public class SeparatorContextItem : ContextItem {
2518+ public SeparatorContextItem () {
2519+ GLib.Object (name: "SeparatorContextAction", label: null, tooltip: null, stock_id: null);
2520+ }
2521+ }
2522+}
2523
2524=== added file 'ipc/ipc-paths.vala'
2525--- ipc/ipc-paths.vala 1970-01-01 00:00:00 +0000
2526+++ ipc/ipc-paths.vala 2015-06-10 13:21:27 +0000
2527@@ -0,0 +1,132 @@
2528+/*
2529+ Copyright (C) 2012-2015 Christian Dywan <christian@twotoasts.de>
2530+
2531+ This library is free software; you can redistribute it and/or
2532+ modify it under the terms of the GNU Lesser General Public
2533+ License as published by the Free Software Foundation; either
2534+ version 2.1 of the License, or (at your option) any later version.
2535+
2536+ See the file COPYING for the full license text.
2537+*/
2538+
2539+extern const string MDATADIR;
2540+extern const string PACKAGE_NAME;
2541+
2542+namespace Midori {
2543+ public enum RuntimeMode {
2544+ UNDEFINED,
2545+ NORMAL,
2546+ APP,
2547+ PRIVATE,
2548+ PORTABLE
2549+ }
2550+
2551+ namespace Paths {
2552+ static RuntimeMode mode = RuntimeMode.UNDEFINED;
2553+ static string? exec_path = null;
2554+ static string? config_dir = null;
2555+ static string? readonly_dir = null;
2556+ static string? app_name = null;
2557+
2558+ public static void mkdir_with_parents (string path, int mode = 0700) {
2559+ /* Use g_access instead of g_file_test for better performance */
2560+ if (Posix.access (path, Posix.F_OK) == 0)
2561+ return;
2562+ int i = path.index_of_char (Path.DIR_SEPARATOR, 0);
2563+ do {
2564+ string fn = path.substring (i, -1);
2565+ if (Posix.access (fn, Posix.F_OK) != 0) {
2566+ if (DirUtils.create (fn, mode) == -1) {
2567+ /* Slow fallback; if this fails we fail */
2568+ DirUtils.create_with_parents (path, mode);
2569+ return;
2570+ }
2571+ }
2572+ else if (!FileUtils.test (fn, FileTest.IS_SYMLINK))
2573+ return; /* Failed */
2574+
2575+ i = path.index_of_char (Path.DIR_SEPARATOR, i);
2576+ }
2577+ while (i != -1);
2578+ }
2579+
2580+ public static void init_with_user_data (Variant user_data) {
2581+ /* Web extensions may run in the same process */
2582+ if (mode != RuntimeMode.UNDEFINED)
2583+ return;
2584+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "addons") == 0)
2585+ stdout.printf ("Addons: Serialized config %s\n", user_data.print (true));
2586+ var config = user_data as HashTable<string, string>;
2587+ mode = (RuntimeMode)config["mode"];
2588+ assert (mode != RuntimeMode.UNDEFINED);
2589+ readonly_dir = config["readonly_dir"];
2590+ config_dir = config["config_dir"];
2591+ assert (readonly_dir != null || config_dir != null);
2592+ exec_path = config["exec_path"];
2593+ assert (exec_path != null);
2594+ app_name = config["app_name"];
2595+ assert (app_name != null);
2596+ }
2597+
2598+ public static string get_config_dir_for_reading () {
2599+ assert (mode != RuntimeMode.UNDEFINED);
2600+ return readonly_dir ?? config_dir;
2601+ }
2602+
2603+ /* returns the path to a user configuration file whose contents should not be modified.
2604+ to get the path to save settings, use get_config_filename() */
2605+ public static string get_config_filename_for_reading (string filename) {
2606+ assert (mode != RuntimeMode.UNDEFINED);
2607+ return Path.build_path (Path.DIR_SEPARATOR_S,
2608+ readonly_dir ?? config_dir, filename);
2609+ }
2610+
2611+ /* returns the path to a user configuration file to which it is permitted to write.
2612+ this is also necessary for files whose state is synchronized to disk by a manager,
2613+ e.g. cookies. */
2614+ public static string get_config_filename_for_writing (string filename) {
2615+ assert (mode != RuntimeMode.UNDEFINED);
2616+ assert (config_dir != null);
2617+ mkdir_with_parents (config_dir);
2618+ return Path.build_path (Path.DIR_SEPARATOR_S, config_dir, filename);
2619+ }
2620+
2621+ #if !HAVE_WIN32
2622+ string? build_folder (string folder, string? middle, string filename) {
2623+ /* Fallback to build folder */
2624+ File? parent = File.new_for_path (exec_path);
2625+ while (parent != null) {
2626+ var data = parent.get_child (folder);
2627+ if (middle != null)
2628+ data = data.get_child (middle);
2629+ var child = data.get_child (filename);
2630+ if (child.query_exists ())
2631+ return child.get_path ();
2632+ parent = parent.get_parent ();
2633+ }
2634+ return null;
2635+ }
2636+ #endif
2637+
2638+ public static string get_res_filename (string filename) {
2639+ assert (exec_path != null);
2640+ assert (filename != "");
2641+ #if HAVE_WIN32
2642+ return Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
2643+ #else
2644+ string path = Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
2645+ if (Posix.access (path, Posix.F_OK) == 0)
2646+ return path;
2647+
2648+ return build_folder ("data", null, filename) ??
2649+ Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename);
2650+ #endif
2651+ }
2652+
2653+ public static string get_app_name () {
2654+ assert (mode != RuntimeMode.UNDEFINED);
2655+ assert (app_name != null);
2656+ return app_name;
2657+ }
2658+ }
2659+}
2660
2661=== renamed file 'midori/midori-database.vala' => 'ipc/midori-database.vala'
2662=== added file 'ipc/midori-tabproxy.vala'
2663--- ipc/midori-tabproxy.vala 1970-01-01 00:00:00 +0000
2664+++ ipc/midori-tabproxy.vala 2015-06-10 13:21:27 +0000
2665@@ -0,0 +1,29 @@
2666+/*
2667+ Copyright (C) 2015 Christian Dywan <christian@twotoasts.de>
2668+
2669+ This library is free software; you can redistribute it and/or
2670+ modify it under the terms of the GNU Lesser General Public
2671+ License as published by the Free Software Foundation; either
2672+ version 2.1 of the License, or (at your option) any later version.
2673+
2674+ See the file COPYING for the full license text.
2675+*/
2676+
2677+namespace Midori {
2678+ [DBus (name = "org.midori.Remote.tab")]
2679+ public interface TabProxy : Object {
2680+ public abstract uint64 id { get; }
2681+ public abstract string color { owned get; set; }
2682+ public async abstract uint64 add_action (Variant user_data) throws IOError;
2683+ public signal void action_added (uint64 id, Variant user_data);
2684+ public signal void action_activated (uint64 id, string name);
2685+ public async static TabProxy? get_by_id (uint64 page_id, Cancellable? cancellable=null) throws Error {
2686+ var app = new Application (Midori.Paths.get_app_name (), ApplicationFlags.IS_LAUNCHER);
2687+ app.register (cancellable);
2688+ var connection = app.get_dbus_connection ();
2689+ return yield connection.get_proxy<TabProxy> (app.get_application_id (),
2690+ "/org/midori/Remote/tab/" + page_id.to_string (), DBusProxyFlags.NONE, cancellable);
2691+ }
2692+ }
2693+}
2694+
2695
2696=== added file 'ipc/midori-webextension.vala'
2697--- ipc/midori-webextension.vala 1970-01-01 00:00:00 +0000
2698+++ ipc/midori-webextension.vala 2015-06-10 13:21:27 +0000
2699@@ -0,0 +1,40 @@
2700+/*
2701+ Copyright (C) 2015 Christian Dywan <christian@twotoats.de>
2702+
2703+ This library is free software; you can redistribute it and/or
2704+ modify it under the terms of the GNU Lesser General Public
2705+ License as published by the Free Software Foundation; either
2706+ version 2.1 of the License, or (at your option) any later version.
2707+
2708+ See the file COPYING for the full license text.
2709+*/
2710+
2711+namespace Midori {
2712+ /*
2713+ * The WebExtension is a base class for out-of-process extensions.
2714+ *
2715+ * Since: 0.6.0
2716+ */
2717+ public class WebExtension : Object {
2718+ protected string? token { get; set; default = null; }
2719+
2720+ /*
2721+ * The user data is used to initialize Midori.Paths.
2722+ */
2723+ public Variant user_data { set {
2724+ Midori.Paths.init_with_user_data (value);
2725+ } }
2726+
2727+ /*
2728+ * Debug messages will be printed if MIDORI_DEBUG contains @token.
2729+ */
2730+ protected void debug (string format, ...) {
2731+ return_if_fail (token != null);
2732+ if (!(token in (Environment.get_variable ("MIDORI_DEBUG") ?? "")))
2733+ return;
2734+
2735+ var args = va_list ();
2736+ stdout.vprintf (token + ": " + format + "\n", args);
2737+ }
2738+ }
2739+}
2740
2741=== renamed file 'katze/gtk3-compat.c' => 'katze/gtk3-compat.c.THIS'
2742=== removed file 'katze/gtk3-compat.h'
2743--- katze/gtk3-compat.h 2013-06-26 21:54:50 +0000
2744+++ katze/gtk3-compat.h 1970-01-01 00:00:00 +0000
2745@@ -1,93 +0,0 @@
2746-/*
2747- Copyright (C) 2011-2012 Christian Dywan <christian@twotoasts.de>
2748-
2749- This library is free software; you can redistribute it and/or
2750- modify it under the terms of the GNU Lesser General Public
2751- License as published by the Free Software Foundation; either
2752- version 2.1 of the License, or (at your option) any later version.
2753-
2754- See the file COPYING for the full license text.
2755-*/
2756-
2757-#include <gtk/gtk.h>
2758-#include <gdk/gdkkeysyms.h>
2759-
2760-#ifndef H_GTK3_COMPAT_20110110
2761-#define H_GTK3_COMPAT_20110110
2762-
2763-G_BEGIN_DECLS
2764-
2765-#if GTK_CHECK_VERSION (3, 2, 0) && defined (GTK_DISABLE_DEPRECATED)
2766- #define GTK_TYPE_VBOX GTK_TYPE_BOX
2767- #define GtkVBox GtkBox
2768- #define GtkVBoxClass GtkBoxClass
2769- #define gtk_vbox_new(hmg,spc) g_object_new (GTK_TYPE_BOX, \
2770- "homogeneous", hmg, "spacing", spc, \
2771- "orientation", GTK_ORIENTATION_VERTICAL, NULL)
2772- #define GTK_TYPE_HBOX GTK_TYPE_BOX
2773- #define GtkHBox GtkBox
2774- #define GtkHBoxClass GtkBoxClass
2775- #define gtk_hbox_new(hmg,spc) g_object_new (GTK_TYPE_BOX, \
2776- "homogeneous", hmg, "spacing", spc, \
2777- "orientation", GTK_ORIENTATION_HORIZONTAL, NULL)
2778- #define gtk_hseparator_new() g_object_new (GTK_TYPE_SEPARATOR, NULL)
2779- #define gtk_hpaned_new() g_object_new (GTK_TYPE_PANED, NULL)
2780- #define gtk_vpaned_new() g_object_new (GTK_TYPE_PANED, \
2781- "orientation", GTK_ORIENTATION_VERTICAL, NULL)
2782- /* FIXME */
2783- #define gtk_widget_render_icon(wdgt, stk, sz, dtl) \
2784- gtk_widget_render_icon_pixbuf(wdgt, stk, sz)
2785- #define gtk_widget_size_request(wdgt, req) \
2786- gtk_widget_get_preferred_size(wdgt, req, NULL)
2787-#endif
2788-
2789-#if GTK_CHECK_VERSION (3, 0, 0)
2790- #define GTK_DIALOG_NO_SEPARATOR 0
2791-#endif
2792-
2793-#if !GTK_CHECK_VERSION (3, 2, 0)
2794- void gtk_entry_set_placeholder_text (GtkEntry* entry, const gchar* text);
2795- const gchar* gtk_entry_get_placeholder_text (GtkEntry* entry);
2796-#endif
2797-
2798-#ifndef GDK_KEY_Return
2799- #define GDK_KEY_0 GDK_0
2800- #define GDK_KEY_BackSpace GDK_BackSpace
2801- #define GDK_KEY_space GDK_space
2802- #define GDK_KEY_F5 GDK_F5
2803- #define GDK_KEY_KP_Equal GDK_KP_Equal
2804- #define GDK_KEY_KP_Enter GDK_KP_Enter
2805- #define GDK_KEY_KP_Left GDK_KP_Left
2806- #define GDK_KEY_KP_Right GDK_KP_Right
2807- #define GDK_KEY_KP_Delete GDK_KP_Delete
2808- #define GDK_KEY_KP_Down GDK_KP_Down
2809- #define GDK_KEY_KP_Up GDK_KP_Up
2810- #define GDK_KEY_KP_Divide GDK_KP_Divide
2811- #define GDK_KEY_Tab GDK_Tab
2812- #define GDK_KEY_ISO_Left_Tab GDK_ISO_Left_Tab
2813- #define GDK_KEY_equal GDK_equal
2814- #define GDK_KEY_ISO_Enter GDK_ISO_Enter
2815- #define GDK_KEY_Left GDK_Left
2816- #define GDK_KEY_Right GDK_Right
2817- #define GDK_KEY_Escape GDK_Escape
2818- #define GDK_KEY_Page_Up GDK_Page_Up
2819- #define GDK_KEY_Page_Down GDK_Page_Down
2820- #define GDK_KEY_Delete GDK_Delete
2821- #define GDK_KEY_Down GDK_Down
2822- #define GDK_KEY_Up GDK_Up
2823- #define GDK_KEY_B GDK_B
2824- #define GDK_KEY_H GDK_H
2825- #define GDK_KEY_J GDK_J
2826- #define GDK_KEY_Return GDK_Return
2827-#endif
2828-
2829-#ifdef GDK_WINDOWING_X11
2830- #include <gdk/gdkx.h>
2831- #ifndef GDK_IS_X11_DISPLAY
2832- #define GDK_IS_X11_DISPLAY(display) TRUE
2833- #endif
2834-#endif
2835-
2836-G_END_DECLS
2837-
2838-#endif
2839
2840=== modified file 'katze/katze-cellrenderercomboboxtext.c'
2841--- katze/katze-cellrenderercomboboxtext.c 2014-05-20 02:15:05 +0000
2842+++ katze/katze-cellrenderercomboboxtext.c 2015-06-10 13:21:27 +0000
2843@@ -39,16 +39,11 @@
2844 static void
2845 katze_cell_renderer_combobox_text_get_size (GtkCellRenderer* cell,
2846 GtkWidget* widget,
2847-#if GTK_CHECK_VERSION(3,0,0)
2848 const GdkRectangle* cell_area,
2849-#else
2850- GdkRectangle* cell_area,
2851-#endif
2852 gint* x_offset,
2853 gint* y_offset,
2854 gint* width,
2855 gint* height);
2856-#if GTK_CHECK_VERSION(3,0,0)
2857 static void
2858 katze_cell_renderer_combobox_text_render (GtkCellRenderer *cell,
2859 cairo_t* cr,
2860@@ -56,16 +51,6 @@
2861 const GdkRectangle *background_area,
2862 const GdkRectangle *cell_area,
2863 GtkCellRendererState flags);
2864-#else
2865-static void
2866-katze_cell_renderer_combobox_text_render (GtkCellRenderer *cell,
2867- GdkDrawable *window,
2868- GtkWidget *widget,
2869- GdkRectangle *background_area,
2870- GdkRectangle *cell_area,
2871- GdkRectangle *expose_area,
2872- GtkCellRendererState flags);
2873-#endif
2874
2875 enum {
2876 PROP_0,
2877@@ -425,11 +410,7 @@
2878 static void
2879 katze_cell_renderer_combobox_text_get_size (GtkCellRenderer *cell,
2880 GtkWidget *widget,
2881-#if GTK_CHECK_VERSION(3,0,0)
2882 const GdkRectangle* cell_area,
2883-#else
2884- GdkRectangle* cell_area,
2885-#endif
2886 gint *x_offset,
2887 gint *y_offset,
2888 gint *width,
2889@@ -450,22 +431,12 @@
2890 }
2891
2892 static void
2893-#if GTK_CHECK_VERSION(3,0,0)
2894 katze_cell_renderer_combobox_text_render (GtkCellRenderer *cell,
2895 cairo_t* cr,
2896 GtkWidget *widget,
2897 const GdkRectangle *background_area,
2898 const GdkRectangle *cell_area,
2899 GtkCellRendererState flags)
2900-#else
2901-katze_cell_renderer_combobox_text_render (GtkCellRenderer *cell,
2902- GdkDrawable *window,
2903- GtkWidget *widget,
2904- GdkRectangle *background_area,
2905- GdkRectangle *cell_area,
2906- GdkRectangle *expose_area,
2907- GtkCellRendererState flags)
2908-#endif
2909 {
2910 const gchar *text = NULL;
2911
2912@@ -473,22 +444,12 @@
2913
2914 set_text (KATZE_CELL_RENDERER_COMBOBOX_TEXT (cell), widget, text);
2915
2916-#if GTK_CHECK_VERSION(3,0,0)
2917 GTK_CELL_RENDERER_CLASS (katze_cell_renderer_combobox_text_parent_class)->render (cell,
2918 cr,
2919 widget,
2920 background_area,
2921 cell_area,
2922 flags);
2923-#else
2924- GTK_CELL_RENDERER_CLASS (katze_cell_renderer_combobox_text_parent_class)->render (cell,
2925- window,
2926- widget,
2927- background_area,
2928- cell_area,
2929- expose_area,
2930- flags);
2931-#endif
2932
2933 g_object_set (G_OBJECT (cell), "text", text, NULL);
2934 g_free ((gpointer)text);
2935
2936=== removed file 'katze/katze-http-auth.c'
2937--- katze/katze-http-auth.c 2013-08-12 19:21:06 +0000
2938+++ katze/katze-http-auth.c 1970-01-01 00:00:00 +0000
2939@@ -1,464 +0,0 @@
2940-/*
2941- Copyright (C) 2008-2009 Christian Dywan <christian@twotoasts.de>
2942-
2943- This library is free software; you can redistribute it and/or
2944- modify it under the terms of the GNU Lesser General Public
2945- License as published by the Free Software Foundation; either
2946- version 2.1 of the License, or (at your option) any later version.
2947-
2948- See the file COPYING for the full license text.
2949-*/
2950-
2951-#if HAVE_CONFIG_H
2952- #include <config.h>
2953-#endif
2954-
2955-#include "katze-http-auth.h"
2956-#include "gtk3-compat.h"
2957-
2958-#include <libsoup/soup.h>
2959-#include <gtk/gtk.h>
2960-#include <glib/gi18n.h>
2961-#include <glib/gstdio.h>
2962-
2963-struct _KatzeHttpAuth
2964-{
2965- GObject parent_instance;
2966- gchar* filename;
2967- GHashTable* logins;
2968-};
2969-
2970-struct _KatzeHttpAuthClass
2971-{
2972- GObjectClass parent_class;
2973-};
2974-
2975-typedef struct
2976-{
2977- KatzeHttpAuth* http_auth;
2978- SoupAuth* auth;
2979- gchar* username;
2980- gchar* password;
2981-} KatzeHttpAuthSave;
2982-
2983-typedef struct
2984-{
2985- gchar* username;
2986- gchar* password;
2987-} KatzeHttpAuthLogin;
2988-
2989-static void
2990-katze_http_auth_session_feature_iface_init (SoupSessionFeatureInterface *iface,
2991- gpointer data);
2992-
2993-G_DEFINE_TYPE_WITH_CODE (KatzeHttpAuth, katze_http_auth, G_TYPE_OBJECT,
2994- G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE,
2995- katze_http_auth_session_feature_iface_init));
2996-
2997-enum
2998-{
2999- PROP_0,
3000-
3001- PROP_FILENAME
3002-};
3003-
3004-static void
3005-katze_http_auth_set_property (GObject* object,
3006- guint prop_id,
3007- const GValue* value,
3008- GParamSpec* pspec);
3009-
3010-static void
3011-katze_http_auth_get_property (GObject* object,
3012- guint prop_id,
3013- GValue* value,
3014- GParamSpec* pspec);
3015-
3016-static void
3017-katze_http_auth_finalize (GObject* object);
3018-
3019-static gchar*
3020-katze_http_auth_soup_auth_get_hash (SoupAuth* auth)
3021-{
3022- return g_strdup_printf ("%s:%s:%s",
3023- soup_auth_get_host (auth),
3024- soup_auth_get_scheme_name (auth),
3025- soup_auth_get_realm (auth));
3026-}
3027-
3028-static void
3029-authentication_message_got_headers_cb (SoupMessage* msg,
3030- KatzeHttpAuthSave* save)
3031-{
3032- /* Anything but 401 and 5xx means the password was accepted */
3033- if (msg->status_code != 401 && msg->status_code < 500)
3034- {
3035- gchar* opaque_info;
3036- FILE* file;
3037-
3038- opaque_info = katze_http_auth_soup_auth_get_hash (save->auth);
3039-
3040- if (!g_hash_table_lookup (save->http_auth->logins, opaque_info))
3041- {
3042- KatzeHttpAuthLogin* login = g_slice_new (KatzeHttpAuthLogin);
3043- login->username = save->username;
3044- login->password = save->password;
3045- g_hash_table_insert (save->http_auth->logins, opaque_info, login);
3046-
3047- if ((file = g_fopen (save->http_auth->filename, "a")))
3048- {
3049- fprintf (file, "%s\t%s\t%s\n", opaque_info,
3050- login->username, login->password);
3051- fclose (file);
3052- g_chmod (save->http_auth->filename, 0600);
3053- }
3054- }
3055- else
3056- {
3057- /* FIXME g_free (save->username);
3058- g_free (save->password); */
3059- }
3060- }
3061- else
3062- {
3063- /* FIXME g_free (save->username);
3064- g_free (save->password); */
3065- }
3066-
3067- /* FIXME g_object_unref (save->auth); */
3068- /* FIXME g_slice_free (KatzeHttpAuthSave, save); */
3069- g_signal_handlers_disconnect_by_func (msg,
3070- authentication_message_got_headers_cb, save);
3071-}
3072-
3073-static void
3074-authentication_dialog_response_cb (GtkWidget* dialog,
3075- gint response,
3076- KatzeHttpAuthSave* save)
3077-{
3078- SoupSession* session;
3079- SoupMessage* msg;
3080-
3081- msg = g_object_get_data (G_OBJECT (dialog), "msg");
3082-
3083- if (response == GTK_RESPONSE_OK)
3084- {
3085- GtkEntry* username = g_object_get_data (G_OBJECT (dialog), "username");
3086- GtkEntry* password = g_object_get_data (G_OBJECT (dialog), "password");
3087- GtkToggleButton* remember = g_object_get_data (G_OBJECT (dialog), "remember");
3088-
3089- soup_auth_authenticate (save->auth,
3090- gtk_entry_get_text (username), gtk_entry_get_text (password));
3091-
3092- if (gtk_toggle_button_get_active (remember) && save->http_auth->filename)
3093- {
3094- save->username = g_strdup (gtk_entry_get_text (username));
3095- save->password = g_strdup (gtk_entry_get_text (password));
3096- g_signal_connect (msg, "got-headers",
3097- G_CALLBACK (authentication_message_got_headers_cb), save);
3098- }
3099- else
3100- {
3101- g_object_unref (save->auth);
3102- g_slice_free (KatzeHttpAuthSave, save);
3103- }
3104- }
3105-
3106- session = g_object_get_data (G_OBJECT (dialog), "session");
3107- if (g_object_get_data (G_OBJECT (msg), "paused"))
3108- soup_session_unpause_message (session, msg);
3109- gtk_widget_destroy (dialog);
3110- g_object_unref (msg);
3111-}
3112-
3113-static void
3114-katze_http_auth_session_authenticate_cb (SoupSession* session,
3115- SoupMessage* msg,
3116- SoupAuth* auth,
3117- gboolean retrying,
3118- KatzeHttpAuth* http_auth)
3119-{
3120- gchar* opaque_info;
3121- KatzeHttpAuthLogin* login;
3122- GtkWidget* dialog;
3123- GtkSizeGroup* sizegroup;
3124- GtkWidget* hbox;
3125- GtkWidget* image;
3126- GtkWidget* label;
3127- GtkWidget* align;
3128- GtkWidget* entry;
3129- KatzeHttpAuthSave* save;
3130-
3131- /* We want to ask for authentication exactly once, so we
3132- enforce this with a tag. There might be a better way. */
3133- if (!retrying && g_object_get_data (G_OBJECT (msg), "katze-session-tag"))
3134- return;
3135-
3136- if (1)
3137- {
3138- /* We use another tag to indicate whether a message is paused.
3139- There doesn't seem to be API in libSoup to find that out. */
3140- soup_session_pause_message (session, g_object_ref (msg));
3141- g_object_set_data (G_OBJECT (msg), "paused", (void*)1);
3142- }
3143- g_object_set_data (G_OBJECT (msg), "katze-session-tag", (void*)1);
3144-
3145- opaque_info = katze_http_auth_soup_auth_get_hash (auth);
3146- login = g_hash_table_lookup (http_auth->logins, opaque_info);
3147- g_free (opaque_info);
3148-
3149- dialog = gtk_dialog_new_with_buttons (_("Authentication Required"),
3150- NULL,
3151- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
3152- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3153- GTK_STOCK_OK, GTK_RESPONSE_OK,
3154- NULL);
3155- gtk_window_set_icon_name (GTK_WINDOW (dialog),
3156- GTK_STOCK_DIALOG_AUTHENTICATION);
3157- gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
3158- gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 5);
3159-
3160- gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 5);
3161- hbox = gtk_hbox_new (FALSE, 6);
3162- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
3163- GTK_ICON_SIZE_DIALOG);
3164- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
3165- label = gtk_label_new (_("A username and a password are required\n"
3166- "to open this location:"));
3167- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
3168- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, FALSE, TRUE, 0);
3169- label = gtk_label_new (soup_auth_get_host (auth));
3170- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label, FALSE, TRUE, 0);
3171- /* If the realm is merely the host, omit the realm label */
3172- if (g_strcmp0 (soup_auth_get_host (auth), soup_auth_get_realm (auth)))
3173- {
3174- label = gtk_label_new (soup_auth_get_realm (auth));
3175- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label, FALSE, TRUE, 0);
3176- }
3177- sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
3178- hbox = gtk_hbox_new (FALSE, 6);
3179- label = gtk_label_new (_("Username"));
3180- align = gtk_alignment_new (0, 0.5, 0, 0);
3181- gtk_container_add (GTK_CONTAINER (align), label);
3182- gtk_size_group_add_widget (sizegroup, align);
3183- gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
3184- entry = gtk_entry_new ();
3185- if (login)
3186- gtk_entry_set_text (GTK_ENTRY (entry), login->username);
3187- gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3188- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
3189- g_object_set_data (G_OBJECT (dialog), "username", entry);
3190- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, FALSE, TRUE, 0);
3191- hbox = gtk_hbox_new (FALSE, 6);
3192- label = gtk_label_new (_("Password"));
3193- align = gtk_alignment_new (0, 0.5, 0, 0);
3194- gtk_container_add (GTK_CONTAINER (align), label);
3195- gtk_size_group_add_widget (sizegroup, align);
3196- gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
3197- entry = gtk_entry_new ();
3198- if (login)
3199- gtk_entry_set_text (GTK_ENTRY (entry), login->password);
3200- gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
3201- gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3202- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
3203- g_object_set_data (G_OBJECT (dialog), "password", entry);
3204- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, FALSE, TRUE, 0);
3205- hbox = gtk_hbox_new (FALSE, 6);
3206- label = gtk_check_button_new_with_mnemonic (_("_Remember password"));
3207- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
3208- g_object_set_data (G_OBJECT (dialog), "remember", label);
3209- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (label), (login != NULL));
3210- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, FALSE, TRUE, 0);
3211- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
3212- gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
3213-
3214- g_object_set_data (G_OBJECT (dialog), "session", session);
3215- g_object_set_data (G_OBJECT (dialog), "msg", msg);
3216-
3217- save = g_slice_new0 (KatzeHttpAuthSave);
3218- save->http_auth = http_auth;
3219- save->auth = g_object_ref (auth);
3220- g_signal_connect (dialog, "response",
3221- G_CALLBACK (authentication_dialog_response_cb), save);
3222- gtk_widget_show (dialog);
3223-}
3224-
3225-static void
3226-katze_http_auth_session_request_queued_cb (SoupSession* session,
3227- SoupMessage* msg,
3228- KatzeHttpAuth* http_auth)
3229-{
3230- /* WebKit has its own authentication dialog in recent versions.
3231- We want only one, and we choose our own to have localization. */
3232- GType type = g_type_from_name ("WebKitSoupAuthDialog");
3233- if (type)
3234- soup_session_remove_feature_by_type (session, type);
3235-
3236- g_signal_connect (session, "authenticate",
3237- G_CALLBACK (katze_http_auth_session_authenticate_cb), http_auth);
3238- g_signal_handlers_disconnect_by_func (session,
3239- katze_http_auth_session_request_queued_cb, http_auth);
3240-}
3241-
3242-static void
3243-katze_http_auth_attach (SoupSessionFeature* feature,
3244- SoupSession* session)
3245-{
3246- g_signal_connect (session, "request-queued",
3247- G_CALLBACK (katze_http_auth_session_request_queued_cb), feature);
3248-}
3249-
3250-static void
3251-katze_http_auth_detach (SoupSessionFeature* feature,
3252- SoupSession* session)
3253-{
3254- g_signal_handlers_disconnect_by_func (session,
3255- katze_http_auth_session_authenticate_cb, NULL);
3256- g_signal_handlers_disconnect_by_func (session,
3257- katze_http_auth_session_request_queued_cb, NULL);
3258-}
3259-
3260-static void
3261-katze_http_auth_session_feature_iface_init (SoupSessionFeatureInterface *iface,
3262- gpointer data)
3263-{
3264- iface->attach = katze_http_auth_attach;
3265- iface->detach = katze_http_auth_detach;
3266-}
3267-
3268-static void
3269-katze_http_auth_class_init (KatzeHttpAuthClass* class)
3270-{
3271- GObjectClass* gobject_class;
3272- GParamFlags flags;
3273-
3274- gobject_class = G_OBJECT_CLASS (class);
3275- gobject_class->finalize = katze_http_auth_finalize;
3276- gobject_class->set_property = katze_http_auth_set_property;
3277- gobject_class->get_property = katze_http_auth_get_property;
3278-
3279- flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
3280-
3281- /**
3282- * KatzeHttpAuth:filename:
3283- *
3284- * An absolute path and name of a file for storing logins.
3285- *
3286- * Since: 0.1.10
3287- */
3288- g_object_class_install_property (gobject_class,
3289- PROP_FILENAME,
3290- g_param_spec_string (
3291- "filename",
3292- "Filename",
3293- "An absolute path and name of a file for storing logins",
3294- NULL,
3295- flags));
3296-}
3297-
3298-static void
3299-katze_http_auth_login_free (KatzeHttpAuthLogin* login)
3300-{
3301- g_free (login->username);
3302- g_free (login->password);
3303- g_slice_free (KatzeHttpAuthLogin, login);
3304-}
3305-
3306-static void
3307-katze_http_auth_set_filename (KatzeHttpAuth* http_auth,
3308- const gchar* filename)
3309-{
3310- FILE* file;
3311-
3312- katze_assign (http_auth->filename, g_strdup (filename));
3313-
3314- g_hash_table_remove_all (http_auth->logins);
3315-
3316- if ((file = g_fopen (filename, "r")))
3317- {
3318- gchar line[255];
3319- guint number = 0;
3320-
3321- while (fgets (line, 255, file))
3322- {
3323- gchar** parts = g_strsplit (line, "\t", 3);
3324- if (parts && parts[0] && parts[1] && parts[2])
3325- {
3326- gint length = strlen (parts[2]);
3327- KatzeHttpAuthLogin* login = g_slice_new (KatzeHttpAuthLogin);
3328- login->username = parts[1];
3329- if (parts[2][length - 1] == '\n')
3330- length--;
3331- login->password = g_strndup (parts[2], length);
3332- g_hash_table_insert (http_auth->logins, parts[0], login);
3333- g_free (parts);
3334- }
3335- else
3336- {
3337- g_strfreev (parts);
3338- g_warning ("Error in line %d in HTTP Auth file", number);
3339- }
3340- number++;
3341- }
3342- fclose (file);
3343- }
3344-}
3345-
3346-static void
3347-katze_http_auth_init (KatzeHttpAuth* http_auth)
3348-{
3349- http_auth->filename = NULL;
3350-
3351- http_auth->logins = g_hash_table_new_full (g_str_hash, g_str_equal,
3352- (GDestroyNotify)g_free, (GDestroyNotify)katze_http_auth_login_free);
3353-}
3354-
3355-static void
3356-katze_http_auth_finalize (GObject* object)
3357-{
3358- KatzeHttpAuth* http_auth = KATZE_HTTP_AUTH (object);
3359-
3360- g_free (http_auth->filename);
3361-
3362- g_hash_table_unref (http_auth->logins);
3363-
3364- G_OBJECT_CLASS (katze_http_auth_parent_class)->finalize (object);
3365-}
3366-
3367-static void
3368-katze_http_auth_set_property (GObject* object,
3369- guint prop_id,
3370- const GValue* value,
3371- GParamSpec* pspec)
3372-{
3373- KatzeHttpAuth* http_auth = KATZE_HTTP_AUTH (object);
3374-
3375- switch (prop_id)
3376- {
3377- case PROP_FILENAME:
3378- katze_http_auth_set_filename (http_auth, g_value_get_string (value));
3379- break;
3380- default:
3381- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3382- break;
3383- }
3384-}
3385-
3386-static void
3387-katze_http_auth_get_property (GObject* object,
3388- guint prop_id,
3389- GValue* value,
3390- GParamSpec* pspec)
3391-{
3392- KatzeHttpAuth* http_auth = KATZE_HTTP_AUTH (object);
3393-
3394- switch (prop_id)
3395- {
3396- case PROP_FILENAME:
3397- g_value_set_string (value, http_auth->filename);
3398- break;
3399- default:
3400- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3401- break;
3402- }
3403-}
3404
3405=== removed file 'katze/katze-http-auth.h'
3406--- katze/katze-http-auth.h 2010-01-17 17:14:48 +0000
3407+++ katze/katze-http-auth.h 1970-01-01 00:00:00 +0000
3408@@ -1,42 +0,0 @@
3409-/*
3410- Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
3411-
3412- This library is free software; you can redistribute it and/or
3413- modify it under the terms of the GNU Lesser General Public
3414- License as published by the Free Software Foundation; either
3415- version 2.1 of the License, or (at your option) any later version.
3416-
3417- See the file COPYING for the full license text.
3418-*/
3419-
3420-#ifndef __KATZE_HTTP_AUTH_H__
3421-#define __KATZE_HTTP_AUTH_H__
3422-
3423-#include "katze-utils.h"
3424-
3425-#include <glib-object.h>
3426-
3427-G_BEGIN_DECLS
3428-
3429-#define KATZE_TYPE_HTTP_AUTH \
3430- (katze_http_auth_get_type ())
3431-#define KATZE_HTTP_AUTH(obj) \
3432- (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_HTTP_AUTH, KatzeHttpAuth))
3433-#define KATZE_HTTP_AUTH_CLASS(klass) \
3434- (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_HTTP_AUTH, KatzeHttpAuthClass))
3435-#define KATZE_IS_HTTP_AUTH(obj) \
3436- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_HTTP_AUTH))
3437-#define KATZE_IS_HTTP_AUTH_CLASS(klass) \
3438- (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_HTTP_AUTH))
3439-#define KATZE_HTTP_AUTH_GET_CLASS(obj) \
3440- (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_HTTP_AUTH, KatzeHttpAuthClass))
3441-
3442-typedef struct _KatzeHttpAuth KatzeHttpAuth;
3443-typedef struct _KatzeHttpAuthClass KatzeHttpAuthClass;
3444-
3445-GType
3446-katze_http_auth_get_type (void) G_GNUC_CONST;
3447-
3448-G_END_DECLS
3449-
3450-#endif /* __KATZE_HTTP_AUTH_H__ */
3451
3452=== modified file 'katze/katze-preferences.c'
3453--- katze/katze-preferences.c 2015-04-19 14:40:59 +0000
3454+++ katze/katze-preferences.c 2015-06-10 13:21:27 +0000
3455@@ -67,9 +67,12 @@
3456 g_object_set (preferences,
3457 "icon-name", GTK_STOCK_PREFERENCES,
3458 "title", dialog_title,
3459+<<<<<<< TREE
3460 #if !GTK_CHECK_VERSION (2, 22, 0)
3461 "has-separator", FALSE,
3462 #endif
3463+=======
3464+>>>>>>> MERGE-SOURCE
3465 NULL);
3466 g_free (dialog_title);
3467
3468@@ -144,7 +147,7 @@
3469 {
3470 KatzePreferencesPrivate* priv = preferences->priv;
3471
3472- #if GTK_CHECK_VERSION (3, 10, 0) && !HAVE_OSX
3473+ #if !HAVE_OSX
3474 priv->notebook = gtk_stack_new ();
3475 #else
3476 priv->notebook = gtk_notebook_new ();
3477@@ -160,7 +163,7 @@
3478 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
3479 priv->toolbar, FALSE, FALSE, 0);
3480 #else
3481- #if GTK_CHECK_VERSION (3, 10, 0) && !HAVE_OSX
3482+ #if !HAVE_OSX
3483 priv->toolbar = gtk_stack_switcher_new ();
3484 gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (priv->toolbar), GTK_STACK (priv->notebook));
3485 gtk_widget_set_halign (priv->toolbar, GTK_ALIGN_CENTER);
3486@@ -200,7 +203,7 @@
3487 gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (preferences)));
3488 }
3489
3490-#if GTK_CHECK_VERSION (3, 10, 0) & !HAVE_OSX
3491+#if !HAVE_OSX
3492 /* these functions are used to clear the 100-px width set in GTK3's
3493 update_button function in gtk/gtkstackswitcher.c */
3494
3495@@ -252,7 +255,7 @@
3496 priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
3497 gtk_widget_show (priv->page);
3498 gtk_container_set_border_width (GTK_CONTAINER (priv->page), 4);
3499- #if GTK_CHECK_VERSION (3, 10, 0) & !HAVE_OSX
3500+ #if !HAVE_OSX
3501 gtk_stack_add_titled (GTK_STACK (priv->notebook),
3502 priv->page, label, label);
3503 workaround_stack_switcher_sizing (GTK_STACK_SWITCHER (priv->toolbar));
3504
3505=== modified file 'katze/katze-utils.c'
3506--- katze/katze-utils.c 2014-05-20 02:15:05 +0000
3507+++ katze/katze-utils.c 2015-06-10 13:21:27 +0000
3508@@ -9,8 +9,6 @@
3509 See the file COPYING for the full license text.
3510 */
3511
3512-#include "gtk3-compat.h"
3513-
3514 #include "katze-utils.h"
3515 #include "katze-array.h"
3516 #include "midori-core.h"
3517@@ -70,7 +68,6 @@
3518 g_object_set (object, property, file, NULL);
3519 }
3520
3521-#if GTK_CHECK_VERSION (3, 2, 0)
3522 static void
3523 proxy_font_chooser_font_activated_cb (GtkFontChooser* chooser,
3524 GObject* object)
3525@@ -89,17 +86,6 @@
3526 gboolean monospace = GPOINTER_TO_INT (data);
3527 return monospace == pango_font_family_is_monospace (family);
3528 }
3529-#else
3530-static void
3531-proxy_combo_box_text_changed_cb (GtkComboBoxText* button,
3532- GObject* object)
3533-{
3534- gchar* text = gtk_combo_box_text_get_active_text (button);
3535- const gchar* property = g_object_get_data (G_OBJECT (button), "property");
3536- g_object_set (object, property, text, NULL);
3537- g_free (text);
3538-}
3539-#endif
3540
3541 static gboolean
3542 proxy_entry_focus_out_event_cb (GtkEntry* entry,
3543@@ -423,7 +409,6 @@
3544 katze_assign (string, g_strdup ("sans"));
3545 gboolean monospace = _hint == I_("font-monospace");
3546
3547- #if GTK_CHECK_VERSION (3, 2, 0)
3548 widget = gtk_font_button_new ();
3549 gtk_font_button_set_show_size (GTK_FONT_BUTTON (widget), FALSE);
3550 gtk_font_chooser_set_font (GTK_FONT_CHOOSER (widget), string);
3551@@ -432,36 +417,6 @@
3552 G_CALLBACK (proxy_font_chooser_font_activated_cb), object);
3553 gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (widget),
3554 (GtkFontFilterFunc)proxy_font_chooser_filter_monospace_cb, GINT_TO_POINTER (monospace), NULL);
3555- #else
3556- GtkComboBox* combo;
3557- gint n_families, i;
3558- PangoContext* context;
3559- PangoFontFamily** families;
3560-
3561- widget = gtk_combo_box_text_new ();
3562- combo = GTK_COMBO_BOX (widget);
3563- context = gtk_widget_get_pango_context (widget);
3564- pango_context_list_families (context, &families, &n_families);
3565- if (string)
3566- {
3567- gint j = 0;
3568- for (i = 0; i < n_families; i++)
3569- {
3570- if (monospace != pango_font_family_is_monospace (families[i]))
3571- continue;
3572- const gchar* font = pango_font_family_get_name (families[i]);
3573- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), font);
3574- if (!g_ascii_strcasecmp (font, string))
3575- gtk_combo_box_set_active (combo, j);
3576- j++;
3577- }
3578- }
3579- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (
3580- gtk_combo_box_get_model (combo)), 0, GTK_SORT_ASCENDING);
3581- g_signal_connect (widget, "changed",
3582- G_CALLBACK (proxy_combo_box_text_changed_cb), object);
3583- g_free (families);
3584- #endif
3585 }
3586 else if (type == G_TYPE_PARAM_STRING)
3587 {
3588@@ -656,23 +611,13 @@
3589 if (!window)
3590 return;
3591
3592- #if !GTK_CHECK_VERSION (3, 0, 0)
3593- if (GTK_IS_ENTRY (widget))
3594- window = gdk_window_get_parent (window);
3595- #endif
3596-
3597 /* Retrieve size and position of both widget and menu */
3598 gtk_widget_get_allocation (widget, &allocation);
3599 gdk_window_get_origin (window, &wx, &wy);
3600 wx += allocation.x;
3601 wy += allocation.y;
3602- #if GTK_CHECK_VERSION (3, 0, 0)
3603 gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
3604 gtk_widget_get_preferred_size (widget, &widget_req, NULL);
3605- #else
3606- gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
3607- gtk_widget_size_request (widget, &widget_req);
3608- #endif
3609 menu_width = menu_req.width;
3610 widget_height = widget_req.height; /* Better than allocation.height */
3611
3612@@ -1037,31 +982,13 @@
3613 if (!valid)
3614 valid = midori_uri_is_ip_address (uri);
3615
3616- #if GTK_CHECK_VERSION (3, 2, 0)
3617 g_object_set_data (G_OBJECT (entry), "invalid", GINT_TO_POINTER (uri && *uri && !valid));
3618 gtk_widget_queue_draw (entry);
3619- #else
3620- if (uri && *uri && !valid)
3621- {
3622- GdkColor bg_color = { 0 };
3623- GdkColor fg_color = { 0 };
3624- gdk_color_parse ("#ef7070", &bg_color);
3625- gdk_color_parse ("#000", &fg_color);
3626- gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &bg_color);
3627- gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &fg_color);
3628- }
3629- else
3630- {
3631- gtk_widget_modify_base (entry, GTK_STATE_NORMAL, NULL);
3632- gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL);
3633- }
3634- #endif
3635
3636 if (other_widget != NULL)
3637 gtk_widget_set_sensitive (other_widget, valid);
3638 }
3639
3640-#if GTK_CHECK_VERSION (3, 2, 0)
3641 static gboolean
3642 katze_uri_entry_draw_cb (GtkWidget* entry,
3643 cairo_t* cr,
3644@@ -1081,7 +1008,6 @@
3645 width * 0.75, height / 1.9 / 2);
3646 return TRUE;
3647 }
3648-#endif
3649
3650 /**
3651 * katze_uri_entry_new:
3652@@ -1100,18 +1026,14 @@
3653 katze_uri_entry_new (GtkWidget* other_widget)
3654 {
3655 GtkWidget* entry = gtk_entry_new ();
3656- #if GTK_CHECK_VERSION (3, 6, 0)
3657 gtk_entry_set_input_purpose (GTK_ENTRY (entry), GTK_INPUT_PURPOSE_URL);
3658- #endif
3659
3660 gtk_entry_set_icon_from_gicon (GTK_ENTRY (entry), GTK_ENTRY_ICON_PRIMARY,
3661 g_themed_icon_new_with_default_fallbacks ("text-html-symbolic"));
3662 g_signal_connect (entry, "changed",
3663 G_CALLBACK (katze_uri_entry_changed_cb), other_widget);
3664- #if GTK_CHECK_VERSION (3, 2, 0)
3665 g_signal_connect_after (entry, "draw",
3666 G_CALLBACK (katze_uri_entry_draw_cb), other_widget);
3667- #endif
3668 return entry;
3669 }
3670
3671@@ -1119,10 +1041,8 @@
3672 katze_widget_add_class (GtkWidget* widget,
3673 const gchar* class_name)
3674 {
3675- #if GTK_CHECK_VERSION (3,0,0)
3676 GtkStyleContext* context = gtk_widget_get_style_context (widget);
3677 gtk_style_context_add_class (context, class_name);
3678- #endif
3679 }
3680
3681 /**
3682
3683=== modified file 'katze/katze-utils.h'
3684--- katze/katze-utils.h 2013-04-16 22:10:56 +0000
3685+++ katze/katze-utils.h 2015-06-10 13:21:27 +0000
3686@@ -15,7 +15,6 @@
3687
3688 #include <gtk/gtk.h>
3689 #include "katze-array.h"
3690-#include "gtk3-compat.h"
3691
3692 G_BEGIN_DECLS
3693
3694
3695=== modified file 'katze/katze.h'
3696--- katze/katze.h 2013-10-22 22:38:26 +0000
3697+++ katze/katze.h 2015-06-10 13:21:27 +0000
3698@@ -12,17 +12,12 @@
3699 #ifndef __KATZE_H__
3700 #define __KATZE_H__
3701
3702-#include "katze-http-auth.h"
3703 #include "katze-utils.h"
3704 #include "katze-item.h"
3705 #include "katze-array.h"
3706 #include "katze-arrayaction.h"
3707 #include "katze-preferences.h"
3708
3709-#ifndef HAVE_WEBKIT2
3710- #include <webkit/webkit.h>
3711-#else
3712 #include <webkit2/webkit2.h>
3713-#endif
3714
3715 #endif /* __KATZE_H__ */
3716
3717=== renamed file 'katze/midori-hsts.vala' => 'katze/midori-hsts.vala.THIS'
3718=== modified file 'katze/midori-paths.vala'
3719--- katze/midori-paths.vala 2015-04-18 21:38:47 +0000
3720+++ katze/midori-paths.vala 2015-06-10 13:21:27 +0000
3721@@ -16,30 +16,16 @@
3722 }
3723
3724 extern const string LIBDIR;
3725-extern const string MDATADIR;
3726-extern const string PACKAGE_NAME;
3727 extern const string SYSCONFDIR;
3728 extern const string MIDORI_VERSION_SUFFIX;
3729 const string MODULE_PREFIX = "lib";
3730 const string MODULE_SUFFIX = "." + GLib.Module.SUFFIX;
3731
3732 namespace Midori {
3733- public enum RuntimeMode {
3734- UNDEFINED,
3735- NORMAL,
3736- APP,
3737- PRIVATE,
3738- PORTABLE
3739- }
3740-
3741 namespace Paths {
3742- static string? exec_path = null;
3743 static string[] command_line = null;
3744 static string? runtime_dir = null;
3745- static RuntimeMode mode = RuntimeMode.UNDEFINED;
3746
3747- static string? config_dir = null;
3748- static string? readonly_dir = null;
3749 static string? cache_dir = null;
3750 static string? cache_dir_for_reading = null;
3751 static string? user_data_dir = null;
3752@@ -52,19 +38,6 @@
3753 }
3754 }
3755
3756- public static string get_config_dir_for_reading () {
3757- assert (mode != RuntimeMode.UNDEFINED);
3758- return readonly_dir ?? config_dir;
3759- }
3760-
3761- /* returns the path to a user configuration file whose contents should not be modified.
3762- to get the path to save settings, use get_config_filename() */
3763- public static string get_config_filename_for_reading (string filename) {
3764- assert (mode != RuntimeMode.UNDEFINED);
3765- return Path.build_path (Path.DIR_SEPARATOR_S,
3766- readonly_dir ?? config_dir, filename);
3767- }
3768-
3769 public bool is_readonly () {
3770 assert (mode != RuntimeMode.UNDEFINED);
3771 return readonly_dir != null;
3772@@ -99,6 +72,7 @@
3773
3774 public static void init (RuntimeMode new_mode, string? config) {
3775 assert (mode == RuntimeMode.UNDEFINED);
3776+ assert (exec_path != null);
3777 assert (new_mode != RuntimeMode.UNDEFINED);
3778 mode = new_mode;
3779 if (mode == RuntimeMode.PORTABLE || mode == RuntimeMode.PRIVATE)
3780@@ -133,11 +107,9 @@
3781 tmp_dir = get_runtime_dir ();
3782 }
3783 else {
3784-#if HAVE_WEBKIT2_3_91
3785 /* Allow WebKit to spawn more than one rendering process */
3786 if (!("wk2:no-multi-render-process" in (Environment.get_variable ("MIDORI_DEBUG") ?? "")))
3787 WebKit.WebContext.get_default ().set_process_model (WebKit.ProcessModel.MULTIPLE_SECONDARY_PROCESSES);
3788-#endif
3789 string? real_config = config != null && !Path.is_absolute (config)
3790 ? Path.build_filename (Environment.get_current_dir (), config) : config;
3791 config_dir = real_config ?? Path.build_path (Path.DIR_SEPARATOR_S,
3792@@ -147,11 +119,15 @@
3793 user_data_dir = Environment.get_user_data_dir ();
3794 tmp_dir = get_runtime_dir ();
3795 }
3796-#if HAVE_WEBKIT2
3797+
3798+ /* Cache and extension dir MUST be set no later than here to work */
3799+ WebKit.WebContext.get_default ().set_web_extensions_directory (
3800+ get_lib_path (PACKAGE_NAME));
3801+ WebKit.WebContext.get_default ().initialize_web_extensions.connect (() => {
3802+ app_name = Application.get_default ().get_application_id ();
3803+ WebKit.WebContext.get_default ().set_web_extensions_initialization_user_data (user_data_for_config ());
3804+ });
3805 if (cache_dir != null) {
3806- /* Cache and extension dir MUST be set no later than here to work */
3807- WebKit.WebContext.get_default ().set_web_extensions_directory (
3808- Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "wk2ext"));
3809 WebKit.WebContext.get_default ().set_disk_cache_directory (
3810 Path.build_path (Path.DIR_SEPARATOR_S, cache_dir, "web"));
3811 }
3812@@ -161,27 +137,19 @@
3813 cookie_manager.set_persistent_storage (Path.build_filename (config_dir, "cookies.db"),
3814 WebKit.CookiePersistentStorage.SQLITE);
3815 }
3816-#endif
3817 if (user_data_dir != null) {
3818 string folder = Path.build_filename (user_data_dir, "webkit", "icondatabase");
3819-#if HAVE_WEBKIT2
3820 WebKit.WebContext.get_default ().set_favicon_database_directory (folder);
3821-#else
3822- WebKit.get_favicon_database ().set_path (folder);
3823-#endif
3824 }
3825 else
3826 {
3827-#if HAVE_WEBKIT2
3828 /* with wk2 set_favicon_database_directory can only be called once and actually
3829 initializes and enables the favicon database, so we do not call it in this case */
3830-#else
3831- /* wk1 documentation claims that the favicon database is not enabled unless
3832- a call to favicon_database.set_path is made, but in fact it must be explicitly
3833- disabled by setting to null (verified as of webkitgtk 2.3.1) */
3834- WebKit.get_favicon_database ().set_path (null);
3835-#endif
3836 }
3837+ if (("wk2:ignore-tls" in (Environment.get_variable ("MIDORI_DEBUG") ?? "")))
3838+ WebKit.WebContext.get_default ().set_tls_errors_policy (WebKit.TLSErrorsPolicy.IGNORE);
3839+ else
3840+ WebKit.WebContext.get_default ().set_tls_errors_policy (WebKit.TLSErrorsPolicy.FAIL);
3841
3842 if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
3843 stdout.printf ("config: %s\ncache: %s\nuser_data: %s\ntmp: %s\n",
3844@@ -189,26 +157,15 @@
3845 }
3846 }
3847
3848- public static void mkdir_with_parents (string path, int mode = 0700) {
3849- /* Use g_access instead of g_file_test for better performance */
3850- if (Posix.access (path, Posix.F_OK) == 0)
3851- return;
3852- int i = path.index_of_char (Path.DIR_SEPARATOR, 0);
3853- do {
3854- string fn = path.substring (i, -1);
3855- if (Posix.access (fn, Posix.F_OK) != 0) {
3856- if (DirUtils.create (fn, mode) == -1) {
3857- /* Slow fallback; if this fails we fail */
3858- DirUtils.create_with_parents (path, mode);
3859- return;
3860- }
3861- }
3862- else if (!FileUtils.test (fn, FileTest.IS_SYMLINK))
3863- return; /* Failed */
3864-
3865- i = path.index_of_char (Path.DIR_SEPARATOR, i);
3866- }
3867- while (i != -1);
3868+ static Variant user_data_for_config () {
3869+ assert (mode != RuntimeMode.UNDEFINED);
3870+ HashTable<string, string?> config = new HashTable<string, string> (str_hash, str_equal);
3871+ config.insert ("mode", "%d".printf ((int)mode));
3872+ config.insert ("readonly_dir", get_config_dir_for_reading ());
3873+ config.insert ("config_dir", get_config_dir_for_reading ());
3874+ config.insert ("exec_path", exec_path);
3875+ config.insert ("app_name", get_app_name ());
3876+ return config;
3877 }
3878
3879 public static void remove_path (string path) {
3880@@ -255,16 +212,6 @@
3881 return get_preset_filename (Path.build_filename ("extensions", preset_filename), filename);
3882 }
3883
3884- /* returns the path to a user configuration file to which it is permitted to write.
3885- this is also necessary for files whose state is synchronized to disk by a manager,
3886- e.g. cookies. */
3887- public static string get_config_filename_for_writing (string filename) {
3888- assert (mode != RuntimeMode.UNDEFINED);
3889- assert (config_dir != null);
3890- mkdir_with_parents (config_dir);
3891- return Path.build_path (Path.DIR_SEPARATOR_S, config_dir, filename);
3892- }
3893-
3894 public static unowned string get_cache_dir () {
3895 assert (cache_dir != null);
3896 return cache_dir;
3897@@ -370,38 +317,6 @@
3898 #endif
3899 }
3900
3901- public static string get_res_filename (string filename) {
3902- assert (command_line != null);
3903- assert (filename != "");
3904- #if HAVE_WIN32
3905- return Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
3906- #else
3907- string path = Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
3908- if (Posix.access (path, Posix.F_OK) == 0)
3909- return path;
3910-
3911- return build_folder ("data", null, filename) ??
3912- Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename);
3913- #endif
3914- }
3915-
3916- #if !HAVE_WIN32
3917- string? build_folder (string folder, string? middle, string filename) {
3918- /* Fallback to build folder */
3919- File? parent = File.new_for_path (exec_path);
3920- while (parent != null) {
3921- var data = parent.get_child (folder);
3922- if (middle != null)
3923- data = data.get_child (middle);
3924- var child = data.get_child (filename);
3925- if (child.query_exists ())
3926- return child.get_path ();
3927- parent = parent.get_parent ();
3928- }
3929- return null;
3930- }
3931- #endif
3932-
3933 /* returns the path to a file containing read-only data installed with the application
3934 if @res is true, looks in the midori resource folder specifically */
3935 public static string get_data_filename (string filename, bool res) {
3936@@ -447,11 +362,7 @@
3937 public static void clear_icons () {
3938 assert (cache_dir != null);
3939 assert (user_data_dir != null);
3940-#if HAVE_WEBKIT2
3941 WebKit.WebContext.get_default ().get_favicon_database ().clear ();
3942-#else
3943- WebKit.get_favicon_database ().clear ();
3944-#endif
3945 /* FIXME: Exclude search engine icons */
3946 remove_path (Path.build_filename (user_data_dir, "webkit", "icondatabase"));
3947 }
3948
3949=== modified file 'katze/midori-uri.vala'
3950--- katze/midori-uri.vala 2015-04-12 13:30:03 +0000
3951+++ katze/midori-uri.vala 2015-06-10 13:21:27 +0000
3952@@ -248,16 +248,10 @@
3953 * Since: 0.5.8
3954 **/
3955 public static async GLib.Icon? get_icon (string uri, Cancellable? cancellable=null) throws Error {
3956-#if HAVE_WEBKIT2
3957 var database = WebKit.WebContext.get_default ().get_favicon_database ();
3958 var surface = yield database.get_favicon (uri, cancellable);
3959 var image = (Cairo.ImageSurface)surface;
3960 var pixbuf = Gdk.pixbuf_get_from_surface (image, 0, 0, image.get_width (), image.get_height ());
3961-#else
3962- var database = WebKit.get_favicon_database ();
3963- // We must not pass a Cancellable due to a crasher bug
3964- var pixbuf = yield database.get_favicon_pixbuf (uri, 0, 0, null);
3965-#endif
3966 return pixbuf as GLib.Icon;
3967 }
3968
3969
3970=== modified file 'midori/CMakeLists.txt'
3971--- midori/CMakeLists.txt 2013-09-08 21:38:36 +0000
3972+++ midori/CMakeLists.txt 2015-06-10 13:21:27 +0000
3973@@ -1,15 +1,13 @@
3974 # Copyright (C) 2013 Christian Dywan <christian@twotoasts.de>
3975
3976-set(LIBMIDORI_VERSION 0.5.5)
3977+set(LIBMIDORI_VERSION 0.6.0)
3978 set(LIBMIDORI_SOVERSION 0)
3979
3980-file(GLOB MIDORI_VALA_SOURCE ../katze/*.vala *.vala ../panels/*.vala)
3981-file(GLOB LIBMIDORI_SOURCE ../katze/*.c ../panels/*.c ../toolbars/*.c midori-*.vala midori-*.c sokoke.c)
3982+# FIXME: Eventually core should link against ipc
3983+file(GLOB MIDORI_VALA_SOURCE ../katze/*.vala *.vala ../panels/*.vala ../ipc/*.vala)
3984+file(GLOB LIBMIDORI_SOURCE ../katze/*.c ../panels/*.c ../toolbars/*.c midori-*.c sokoke.c)
3985 include(GLibHelpers)
3986 add_glib_marshal(LIBMIDORI_SOURCE marshal ${CMAKE_PROJECT_NAME}_cclosure_marshal "midori.h")
3987-set(MIDORI_SOURCE
3988- main.c
3989- )
3990
3991 include(ValaPrecompile)
3992 vala_precompile(LIBMIDORI_SOURCE_C ${CMAKE_PROJECT_NAME}
3993@@ -21,18 +19,18 @@
3994 CUSTOM_VAPIS
3995 ${EXTRA_VAPIS}
3996 GENERATE_VAPI
3997- "${CMAKE_PROJECT_NAME}-core"
3998+ "${LIBMIDORI}"
3999 GENERATE_HEADER
4000- "${CMAKE_PROJECT_NAME}-core"
4001+ "${LIBMIDORI}"
4002 )
4003
4004-add_library("${LIBMIDORI}-vala" STATIC ${LIBMIDORI_SOURCE_C})
4005-target_link_libraries("${LIBMIDORI}-vala"
4006+add_library("${LIBMIDORIV}" STATIC ${LIBMIDORI_SOURCE_C})
4007+target_link_libraries("${LIBMIDORIV}"
4008 ${DEPS_LIBRARIES}
4009 ${OPTS_LIBRARIES}
4010 ${DEPS_GTK_LIBRARIES}
4011 )
4012-set_target_properties("${LIBMIDORI}-vala" PROPERTIES
4013+set_target_properties("${LIBMIDORIV}" PROPERTIES
4014 COMPILE_FLAGS "${VALA_CFLAGS}"
4015 POSITION_INDEPENDENT_CODE ON
4016 )
4017@@ -49,7 +47,7 @@
4018 ${DEPS_GTK_INCLUDE_DIRS}
4019 )
4020 target_link_libraries(${LIBMIDORI}
4021- "${LIBMIDORI}-vala"
4022+ ${LIBMIDORIV}
4023 ${DEPS_LIBRARIES}
4024 ${OPTS_LIBRARIES}
4025 ${DEPS_GTK_LIBRARIES}
4026
4027=== modified file 'midori/main.c'
4028--- midori/main.c 2014-04-23 03:34:23 +0000
4029+++ midori/main.c 2015-06-10 13:21:27 +0000
4030@@ -62,6 +62,7 @@
4031 gchar* config;
4032 gboolean private;
4033 gboolean portable;
4034+ gchar* test;
4035 gboolean plain;
4036 gboolean diagnostic_dialog = FALSE;
4037 gboolean debug = FALSE;
4038@@ -85,6 +86,8 @@
4039 { "portable", 'P', 0, G_OPTION_ARG_NONE, &portable,
4040 N_("Portable mode, all runtime files are stored in one place"), NULL },
4041 #endif
4042+ { "test", 't', 0, G_OPTION_ARG_STRING, &test,
4043+ N_("Run unit tests for the specified extension"), NULL },
4044 { "plain", '\0', 0, G_OPTION_ARG_NONE, &plain,
4045 N_("Plain GTK+ window with WebKit, akin to GtkLauncher"), NULL },
4046 { "diagnostic-dialog", 'd', 0, G_OPTION_ARG_NONE, &diagnostic_dialog,
4047@@ -118,6 +121,7 @@
4048 config = NULL;
4049 private = FALSE;
4050 portable = FALSE;
4051+ test = NULL;
4052 plain = FALSE;
4053 run = FALSE;
4054 snapshot = NULL;
4055@@ -287,24 +291,62 @@
4056 return 0;
4057 }
4058
4059+ if (test != NULL)
4060+ {
4061+ g_assert (g_module_supported ());
4062+
4063+ GModule* module = g_module_open (test, G_MODULE_BIND_LOCAL);
4064+ if (module == NULL)
4065+ g_error (_("Failed to load %s."), test);
4066+
4067+ midori_test_init (&argc, &argv);
4068+
4069+ typedef void (*extension_test_func)(void);
4070+ extension_test_func extension_test;
4071+ /* Midori.Extension */
4072+ typedef GObject* (*extension_init_func)(void);
4073+ extension_init_func extension_init;
4074+ /* WebKit.WebExtension */
4075+ typedef void (*webkit_web_extension_initialize_func)(GObject* extension);
4076+ webkit_web_extension_initialize_func web_extension_init;
4077+
4078+ if (g_module_symbol (module, "extension_init",
4079+ (gpointer) &extension_init))
4080+ {
4081+ /* It's fine to conditionally return no extension */
4082+ if (!(extension_init ()))
4083+ return 0;
4084+ midori_paths_init (MIDORI_RUNTIME_MODE_NORMAL, NULL);
4085+
4086+ /* Not all extensions have unit tests :-( */
4087+ if (!g_module_symbol (module, "extension_test", (gpointer) &extension_test))
4088+ return 0;
4089+ }
4090+ else if (g_module_symbol (module, "webkit_web_extension_initialize",
4091+ (gpointer) &web_extension_init)
4092+ || g_module_symbol (module, "webkit_web_extension_initialize_with_user_data",
4093+ (gpointer) &web_extension_init))
4094+ {
4095+ if (!g_module_symbol (module, "extension_test", (gpointer) &extension_test))
4096+ g_error (_("%s doesn't provide unit tests."), test);
4097+ }
4098+ else
4099+ g_error (_("%s doesn't look like a Midori extension."), test);
4100+
4101+ extension_test ();
4102+ return g_test_run ();
4103+ }
4104+
4105 if (plain)
4106 {
4107 GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4108 GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
4109 GtkWidget* entry = gtk_entry_new ();
4110-#ifndef HAVE_WEBKIT2
4111- GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
4112-#endif
4113 GtkWidget* web_view = webkit_web_view_new ();
4114 katze_window_set_sensible_default_size (GTK_WINDOW (window));
4115
4116 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
4117-#ifndef HAVE_WEBKIT2
4118- gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
4119- gtk_container_add (GTK_CONTAINER (scrolled), web_view);
4120-#else
4121 gtk_box_pack_start (GTK_BOX (vbox), web_view, TRUE, TRUE, 0);
4122-#endif
4123 gtk_container_add (GTK_CONTAINER (window), vbox);
4124 gtk_entry_set_text (GTK_ENTRY (entry), uris && *uris ? *uris : "http://www.example.com");
4125 plain_entry_activate_cb (entry, web_view);
4126@@ -330,9 +372,6 @@
4127
4128 MidoriBrowser* browser = midori_browser_new ();
4129 MidoriWebSettings* settings = midori_browser_get_settings (browser);
4130-#ifndef HAVE_WEBKIT2
4131- g_object_set_data (G_OBJECT (webkit_get_default_session ()), "pass-through-console", (void*)1);
4132-#endif
4133 midori_load_soup_session (settings);
4134
4135 gchar* msg = NULL;
4136
4137=== added file 'midori/midori-addons.vala'
4138--- midori/midori-addons.vala 1970-01-01 00:00:00 +0000
4139+++ midori/midori-addons.vala 2015-06-10 13:21:27 +0000
4140@@ -0,0 +1,415 @@
4141+/*
4142+ Copyright (C) 2014 Christian Dywan <christian@twotoats.de>
4143+
4144+ This library is free software; you can redistribute it and/or
4145+ modify it under the terms of the GNU Lesser General Public
4146+ License as published by the Free Software Foundation; either
4147+ version 2.1 of the License, or (at your option) any later version.
4148+
4149+ See the file COPYING for the full license text.
4150+*/
4151+
4152+namespace Midori {
4153+ public class Addon : Object {
4154+ public string name { get; set; }
4155+ public string description { get; set; }
4156+ public bool intern { get; internal set; }
4157+ public Addon (string name, string description) {
4158+ Object (name: name, description: description);
4159+ }
4160+ }
4161+
4162+ public class UserContent : Addon {
4163+ internal UserContent (string name, string description) {
4164+ Object (name: name, description: description);
4165+ }
4166+ }
4167+
4168+ public class ClassicExtension : Addon {
4169+ string? _version = null;
4170+ public string? version { get {
4171+ return _version;
4172+ } set {
4173+ /* Don't show version suffix if it matches the running Midori */
4174+ if (value != null && value.has_suffix (MIDORI_VERSION_SUFFIX))
4175+ _version = value.replace (MIDORI_VERSION_SUFFIX, "");
4176+ /* No version suffix at all, must be 0.4.1 or 0.4.1 git */
4177+ else if (value != null && !("-" in value) && !("(" in value))
4178+ _version = value + " (0.4.1)";
4179+ else
4180+ _version = value;
4181+ } }
4182+ public string? authors { get; set; default = null; }
4183+ public string? website { get; set; default = null; }
4184+ public string? stock_id { get; set; default = null; }
4185+ public bool use_markup { get; set; }
4186+ /* If there's more than one extension in an array.
4187+ Since: 0.4.5 */
4188+ public string? key { get; set; default = null; }
4189+
4190+ public string? config_dir { get; /* FIXME: internal */ set; default = null; }
4191+ KeyFile? keyfile = null;
4192+ /* Since: 0.1.3 */
4193+ public void install_boolean (string name, bool default) {
4194+ keyfile.set_boolean ("settings", name, default);
4195+ }
4196+ /* Since: 0.1.3 */
4197+ public bool get_boolean (string name) {
4198+ try {
4199+ return keyfile.get_boolean ("settings", name);
4200+ } catch (Error error) {
4201+ return false;
4202+ }
4203+ }
4204+ /* Since: 0.1.3 */
4205+ public void set_boolean (string name, bool value) {
4206+ keyfile.set_boolean ("settings", name, value);
4207+ save ();
4208+ }
4209+ /* Since: 0.1.3 */
4210+ public void install_integer (string name, int default) {
4211+ keyfile.set_integer ("settings", name, default);
4212+ }
4213+ public int get_integer (string name) {
4214+ try {
4215+ return keyfile.get_integer ("settings", name);
4216+ } catch (Error error) {
4217+ return 0;
4218+ }
4219+ }
4220+ public void set_integer (string name, int value) {
4221+ keyfile.set_integer ("settings", name, value);
4222+ save ();
4223+ }
4224+ /* Since: 0.1.3 */
4225+ public void install_string (string name, string default) {
4226+ keyfile.set_string ("settings", name, default);
4227+ }
4228+ public string? get_string (string name) {
4229+ try {
4230+ return keyfile.get_string ("settings", name);
4231+ } catch (Error error) {
4232+ return null;
4233+ }
4234+ }
4235+ public void set_string (string name, string value) {
4236+ keyfile.set_string ("settings", name, value);
4237+ save ();
4238+ }
4239+ /* Since: 0.1.7 */
4240+ public void install_string_list (string name, string[]? default) {
4241+ if (default != null)
4242+ keyfile.set_string_list ("settings", name, default);
4243+ }
4244+ /* Since: 0.1.7 */
4245+ public string[]? get_string_list (string name) {
4246+ try {
4247+ return keyfile.get_string_list ("settings", name);
4248+ } catch (Error error) {
4249+ return null;
4250+ }
4251+ }
4252+ /* Since: 0.1.7 */
4253+ public void set_string_list (string name, string[]? value) {
4254+ keyfile.set_string_list ("settings", name, value);
4255+ save ();
4256+ }
4257+ void save () {
4258+ Katze.mkdir_with_parents (config_dir, 0700);
4259+ string config = Path.build_filename (config_dir, "config");
4260+ try {
4261+ keyfile.save_to_file (config);
4262+ } catch (Error error) {
4263+ warning (_("The configuration of the extension '%s' couldn't be saved: %s\n"), name, error.message);
4264+ }
4265+ }
4266+
4267+ public bool is_prepared () {
4268+ // FIXME: has 'activate' handler pending?
4269+ return name != null && description != null && version != null && authors != null;
4270+ }
4271+ /* Since: 0.1.6 */
4272+ public Object? app { get; protected set; default = null; }
4273+ /* Since: 0.1.2 */
4274+ public bool is_active () { return app != null; }
4275+
4276+ public signal void activate (Object? app);
4277+ public signal void deactivate ();
4278+ /* Since: 0.4.0 */
4279+ public signal void open_preferences ();
4280+ public bool has_preferences () {
4281+ // FIXME: has 'open-preferences' handler pending?
4282+ return false;
4283+ }
4284+
4285+ protected ClassicExtension (string name, string description) {
4286+ Object (name: name, description: description);
4287+ }
4288+ void activated (Object? app) {
4289+ assert (is_prepared ());
4290+ this.app = app != null ? app : this.app;
4291+ string? filename = get_data<string?>("filename");
4292+ if (!Midori.Paths.is_readonly ()) {
4293+ this.config_dir = Paths.get_extension_config_dir (filename);
4294+ string preset = Paths.get_extension_preset_filename (filename, "config");
4295+ try {
4296+ keyfile.load_from_file (preset, KeyFileFlags.KEEP_COMMENTS);
4297+ } catch (FileError.NOENT exist_error) {
4298+ /* It's no error if no config file exists */
4299+ } catch (Error error) {
4300+ warning ("Failed to load config for %s from %s: %s", name, preset, error.message);
4301+ }
4302+ string config = Path.build_filename (config_dir, "config");
4303+ try {
4304+ keyfile.load_from_file (config, KeyFileFlags.KEEP_COMMENTS);
4305+ } catch (FileError.NOENT exist_error) {
4306+ /* It's no error if no config file exists */
4307+ } catch (Error error) {
4308+ warning ("Failed to load config for %s from %s: %s", name, config, error.message);
4309+ }
4310+ }
4311+ }
4312+ void deactivated () {
4313+ this.app = null;
4314+ }
4315+
4316+ construct {
4317+ keyfile = new KeyFile ();
4318+ activate.connect (activated);
4319+ deactivate.connect (deactivated);
4320+ }
4321+ }
4322+
4323+ delegate Object? ExtensionInitFunction ();
4324+ delegate void WebExtensionInitializeFunction (Object extension);
4325+
4326+ public class Addons : Object {
4327+ bool debug = false;
4328+ public WebKit.UserContentManager content_manager;
4329+
4330+ Addons () {
4331+ addons = new List<Addon> ();
4332+ modules = new HashTable<string, Object> (str_hash, str_equal);
4333+ content_manager = new WebKit.UserContentManager ();
4334+ if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "addons") == 0)
4335+ debug = true;
4336+ }
4337+
4338+ static Addons? _instance = null;
4339+ public static unowned Addons get_default () {
4340+ if (_instance == null)
4341+ _instance = new Addons ();
4342+ return _instance;
4343+ }
4344+
4345+ public Object? app { private get; set; default = null; }
4346+ string? _interns = null;
4347+ /* A comma separated list of extension names that are always loaded and
4348+ acctive but won't show up in GUI. Can only be set once. */
4349+ public string? interns { get {
4350+ return _interns;
4351+ } set {
4352+ assert (_interns == null);
4353+ _interns = value;
4354+ if (debug)
4355+ stdout.printf ("Addons: internal extensions '%s'\n", _interns);
4356+ foreach (string name in _interns.split (" ")) {
4357+ if (name == "")
4358+ continue;
4359+ var extension = load_by_name (name);
4360+ assert (extension != null);
4361+ assert (extension is ClassicExtension);
4362+ (extension as ClassicExtension).activate (app);
4363+ }
4364+ } }
4365+ /* GModule detects repeated loading but exposes no API zo check it */
4366+ HashTable<string, Object> modules;
4367+
4368+ public Object? load_by_name (string name) {
4369+ return load_by_filename ("lib" + name + "." + Module.SUFFIX);
4370+ }
4371+
4372+ public Object? load_by_filename (string filename) {
4373+ var libs = File.new_for_path (Midori.Paths.get_lib_path (PACKAGE_NAME));
4374+ string fullname = "/" in filename ? filename.split ("/")[0] : filename;
4375+ return load_from_file (libs.get_child (fullname));
4376+ }
4377+
4378+ public Object? load_from_file (File file) {
4379+ /* Not a module of any sort */
4380+ if (!(file.get_basename ().has_suffix (Module.SUFFIX)))
4381+ return null;
4382+ if (debug)
4383+ stdout.printf ("Addons: Module %s\n", file.get_basename ());
4384+
4385+ var addon = modules.lookup (file.get_basename ());
4386+ if (addon != null)
4387+ return addon;
4388+
4389+ Module? module = Module.open (file.get_path (), ModuleFlags.BIND_LOCAL);
4390+ void* extension_init;
4391+ void* web_extension_init;
4392+ if (module == null)
4393+ warning ("'%s' failed to open: %s", file.get_basename (), Module.error ());
4394+ else if (module.symbol ("extension_init", out extension_init)) {
4395+ if (debug)
4396+ stdout.printf ("^^ Midori.Extension\n");
4397+ var extension_or_array = ((ExtensionInitFunction)extension_init) ();
4398+ modules.insert (file.get_basename (), extension_or_array);
4399+ module.make_resident ();
4400+ if (extension_or_array is Addon) {
4401+ var extension = extension_or_array as Addon;
4402+ string bare_name = file.get_basename ().replace ("lib", "").replace ("." + Module.SUFFIX, "");
4403+ extension.intern = (bare_name in interns);
4404+ extension.set_data<string> ("filename", file.get_basename ());
4405+ if (debug)
4406+ stdout.printf ("^^ internal\n");
4407+ addons.append (extension);
4408+ return extension;
4409+ } else if (extension_or_array != null) {
4410+ if (debug)
4411+ stdout.printf ("^^ Katze.Array\n");
4412+ foreach (var extension in Katze.array_peek_items (extension_or_array))
4413+ addons.append (extension as Addon);
4414+ return extension_or_array;
4415+ }
4416+ } else if (module.symbol ("webkit_web_extension_initialize", out web_extension_init)
4417+ || module.symbol ("webkit_web_extension_initialize_with_user_data", out web_extension_init)) {
4418+ if (debug)
4419+ stdout.printf ("^^ WebKit.WebExtension\n");
4420+ var web_extension = new Addon (file.get_basename (), "WebExtension");
4421+ web_extension.intern = true;
4422+ addons.append (web_extension);
4423+ return web_extension;
4424+ } else
4425+ warning ("'%s' is not a known type of extension", file.get_basename ());
4426+ return null;
4427+ }
4428+
4429+ async UserContent parse_user_content (File file) {
4430+ string name = file.get_basename ();
4431+ string description = "";
4432+
4433+ if (file.get_basename ().has_suffix (".js")) {
4434+ try {
4435+ var stream = new DataInputStream (yield file.read_async ());
4436+ var source = new StringBuilder ();
4437+ do {
4438+ string? line = yield stream.read_line_async ();
4439+ if (line == null)
4440+ break;
4441+ // TODO: Parse metadata
4442+ source.append (line);
4443+ } while (true);
4444+
4445+ // TODO: whitelist, blacklist
4446+ var script = new WebKit.UserScript (source.str,
4447+ WebKit.UserContentInjectedFrames.ALL_FRAMES,
4448+ WebKit.UserScriptInjectionTime.END, null, null);
4449+ content_manager.add_script (script);
4450+ } catch (Error error) {
4451+ description = error.message;
4452+ warning ("Failed to read user script %s: %s", file.get_path (), error.message);
4453+ }
4454+ } else if (file.get_basename ().has_suffix (".css")) {
4455+ try {
4456+ var stream = new DataInputStream (yield file.read_async ());
4457+ var source = new StringBuilder ();
4458+ do {
4459+ string? line = yield stream.read_line_async ();
4460+ if (line == null)
4461+ break;
4462+ // TODO: Parse @-moz-document
4463+ source.append (line);
4464+ } while (true);
4465+
4466+ // TODO: whitelist, blacklist
4467+ var script = new WebKit.UserStyleSheet (source.str,
4468+ WebKit.UserContentInjectedFrames.ALL_FRAMES,
4469+ WebKit.UserStyleLevel.USER, null, null);
4470+ content_manager.add_style_sheet (script);
4471+ } catch (Error error) {
4472+ description = error.message;
4473+ warning ("Failed to read user style sheet %s: %s", file.get_path (), error.message);
4474+ }
4475+ } else {
4476+ assert_not_reached ();
4477+ }
4478+
4479+ // TODO: Handle activation
4480+ return new UserContent (name, description);
4481+ }
4482+
4483+ async void scan_user_content_folder (string folder, string extension) {
4484+ var scripts = File.new_for_path (Midori.Paths.get_user_data_dir ())
4485+ .get_child (PACKAGE_NAME).get_child (folder);
4486+ if (debug)
4487+ stdout.printf ("Addons: Scanning %s for user content\n", scripts.get_path ());
4488+ try {
4489+ var enumerator = yield scripts.enumerate_children_async ("standard::name", 0);
4490+ while (true) {
4491+ var files = yield enumerator.next_files_async (10);
4492+ if (files == null)
4493+ break;
4494+ foreach (var info in files) {
4495+ var file = scripts.get_child (info.get_name ());
4496+ /* Not a user script/ style? */
4497+ if (!(file.get_basename ().has_suffix (extension)))
4498+ continue;
4499+ if (debug)
4500+ stdout.printf ("Addons: User content %s\n", file.get_basename ());
4501+ var script = yield parse_user_content (file);
4502+ addons.append (script);
4503+ }
4504+ }
4505+ } catch (Error error) {
4506+ critical ("Failed to list user content: %s", error.message);
4507+ }
4508+ }
4509+
4510+ List<Addon>? addons;
4511+ public async unowned List<unowned Addon> list (Cancellable? cancellable=null) {
4512+ var libs = File.new_for_path (Midori.Paths.get_lib_path (PACKAGE_NAME));
4513+ if (debug)
4514+ stdout.printf ("Addons: Scanning %s for modules\n", libs.get_path ());
4515+ try {
4516+ var enumerator = yield libs.enumerate_children_async ("standard::name", 0);
4517+ while (true) {
4518+ var files = yield enumerator.next_files_async (10);
4519+ if (files == null)
4520+ break;
4521+ foreach (var info in files) {
4522+ var file = libs.get_child (info.get_name ());
4523+ var addon = load_from_file (file);
4524+ if (addon == null)
4525+ continue;
4526+ }
4527+ }
4528+ } catch (Error error) {
4529+ critical ("Failed to list (web) extensions: %s", error.message);
4530+ }
4531+
4532+ if (debug)
4533+ stdout.printf ("Addons: Reading WebKit.Plugin's\n");
4534+ try {
4535+ List<WebKit.Plugin> plugins = yield WebKit.WebContext.get_default ().get_plugins (cancellable);
4536+ foreach (WebKit.Plugin plugin in plugins) {
4537+ if (debug)
4538+ stdout.printf ("Addons: WebKit.Plugin %s\n", plugin.get_path ());
4539+ // FIXME: Skip plugin?
4540+ var regex = new Regex ("<a.+href.+>(.+)</a>");
4541+ string desc = regex.replace (
4542+ plugin.get_description (), -1, 0, "<u>\\1</u>").replace ("<br>", "\n");
4543+ addons.append (new Addon (plugin.get_name (), desc));
4544+ }
4545+ } catch (Error error) {
4546+ critical ("Failed to list plugins: %s", error.message);
4547+ }
4548+
4549+ yield scan_user_content_folder ("scripts", ".js");
4550+ yield scan_user_content_folder ("styles", ".css");
4551+
4552+ return addons;
4553+ }
4554+ }
4555+}
4556
4557=== modified file 'midori/midori-app.c'
4558--- midori/midori-app.c 2015-04-14 19:13:57 +0000
4559+++ midori/midori-app.c 2015-06-10 13:21:27 +0000
4560@@ -202,7 +202,6 @@
4561 G_CALLBACK (midori_app_send_notification), app);
4562 katze_array_add_item (app->browsers, browser);
4563
4564- #if GTK_CHECK_VERSION (3, 0, 0)
4565 if (app->browser == NULL)
4566 {
4567 gchar* filename;
4568@@ -226,7 +225,6 @@
4569 g_free (filename);
4570 }
4571 }
4572- #endif
4573
4574 app->browser = browser;
4575 }
4576@@ -1240,14 +1238,8 @@
4577 textdomain (GETTEXT_PACKAGE);
4578 #endif
4579
4580- #if GTK_CHECK_VERSION (3, 0, 0)
4581 success = gtk_init_with_args (argc, argument_vector, _("[Addresses]"),
4582 entries, GETTEXT_PACKAGE, &error);
4583- #else
4584- success = gtk_init_with_args (argc, argument_vector, _("[Addresses]"),
4585- (GOptionEntry*)entries, GETTEXT_PACKAGE, &error);
4586- #endif
4587-
4588 factory = gtk_icon_factory_new ();
4589 for (i = 0; i < G_N_ELEMENTS (items); i++)
4590 {
4591@@ -1284,7 +1276,14 @@
4592 midori_debug (const gchar* token)
4593 {
4594 static const gchar* debug_token = NULL;
4595+<<<<<<< TREE
4596 const gchar* debug_tokens = "wk2:no-multi-render-process adblock:match adblock:parse adblock:time adblock:element adblock:css startup headers body referer cookies paths hsts unarmed db:bookmarks db:history db:tabby mouse app database addons:match ";
4597+=======
4598+ const gchar* debug_tokens = "wk2:no-multi-render-process \
4599+ adblock:match adblock:parse adblock:time adblock:element adblock:css \
4600+ startup headers body referer cookies paths addons hsts unarmed \
4601+ db:bookmarks db:history db:tabby mouse app database dnt ";
4602+>>>>>>> MERGE-SOURCE
4603 if (debug_token == NULL)
4604 {
4605 gchar* found_token;
4606
4607=== modified file 'midori/midori-app.h'
4608--- midori/midori-app.h 2013-03-28 17:27:56 +0000
4609+++ midori/midori-app.h 2015-06-10 13:21:27 +0000
4610@@ -103,6 +103,11 @@
4611 midori_error (const gchar* format,
4612 ...);
4613
4614+void
4615+midori_app_set_browsers (MidoriApp* app,
4616+ KatzeArray* browsers,
4617+ MidoriBrowser* browser);
4618+
4619 G_END_DECLS
4620
4621 #endif /* __MIDORI_APP_H__ */
4622
4623=== modified file 'midori/midori-browser.c'
4624--- midori/midori-browser.c 2015-06-03 02:05:28 +0000
4625+++ midori/midori-browser.c 2015-06-10 13:21:27 +0000
4626@@ -1,5 +1,5 @@
4627 /*
4628- Copyright (C) 2007-2013 Christian Dywan <christian@twotoasts.de>
4629+ Copyright (C) 2007-2014 Christian Dywan <christian@twotoasts.de>
4630 Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
4631 Copyright (C) 2009 Jérôme Geulfucci <jeromeg@xfce.org>
4632
4633@@ -70,16 +70,8 @@
4634
4635 GtkWidget* panel;
4636 GtkWidget* notebook;
4637-
4638- GtkWidget* inspector;
4639- GtkWidget* inspector_view;
4640-
4641 GtkWidget* find;
4642
4643- GtkWidget* statusbar;
4644- GtkWidget* statusbar_contents;
4645- gchar* statusbar_text;
4646-
4647 gint last_window_width, last_window_height;
4648 guint alloc_timeout;
4649 guint panel_timeout;
4650@@ -95,7 +87,6 @@
4651 gboolean show_tabs;
4652
4653 gboolean show_navigationbar;
4654- gboolean show_statusbar;
4655 guint maximum_history_age;
4656 guint last_web_search;
4657
4658@@ -153,11 +144,9 @@
4659 static void
4660 midori_browser_finalize (GObject* object);
4661
4662-#ifdef HAVE_WEBKIT2
4663 void download_created_destination_cb (WebKitDownload *download,
4664 gchar *destination,
4665 gpointer user_data);
4666-#endif
4667
4668 static void
4669 midori_browser_set_property (GObject* object,
4670@@ -243,7 +232,8 @@
4671 gboolean show_tabs = !midori_browser_is_fullscreen (browser) || ignore_fullscreen;
4672 if (!browser->show_tabs)
4673 show_tabs = FALSE;
4674- midori_notebook_set_labels_visible (MIDORI_NOTEBOOK (browser->notebook), show_tabs);
4675+ if (browser->notebook)
4676+ midori_notebook_set_labels_visible (MIDORI_NOTEBOOK (browser->notebook), show_tabs);
4677 return has_tabs;
4678 }
4679
4680@@ -292,13 +282,6 @@
4681 {
4682 GtkAction* action;
4683
4684- _action_set_sensitive (browser, "Back", midori_view_can_go_back (view));
4685- _action_set_sensitive (browser, "Forward", midori_tab_can_go_forward (MIDORI_TAB (view)));
4686- _action_set_sensitive (browser, "Previous",
4687- midori_view_get_previous_page (view) != NULL);
4688- _action_set_sensitive (browser, "Next",
4689- midori_view_get_next_page (view) != NULL);
4690-
4691 _action_set_sensitive (browser, "AddSpeedDial", !midori_view_is_blank (view));
4692 _action_set_sensitive (browser, "BookmarkAdd", !midori_view_is_blank (view));
4693 _action_set_sensitive (browser, "MailTo", !midori_view_is_blank (view));
4694@@ -311,24 +294,6 @@
4695 midori_tab_can_view_source (MIDORI_TAB (view)));
4696 _action_set_sensitive (browser, "SourceView",
4697 midori_tab_can_view_source (MIDORI_TAB (view)));
4698- _action_set_sensitive (browser, "SourceViewDom",
4699- midori_tab_can_view_source (MIDORI_TAB (view)));
4700-
4701- action = _action_by_name (browser, "NextForward");
4702- if (midori_tab_can_go_forward (MIDORI_TAB (view)))
4703- {
4704- g_object_set (action,
4705- "stock-id", GTK_STOCK_GO_FORWARD,
4706- "tooltip", _("Go forward to the next page"),
4707- "sensitive", TRUE, NULL);
4708- }
4709- else
4710- {
4711- g_object_set (action,
4712- "stock-id", GTK_STOCK_MEDIA_NEXT,
4713- "tooltip", _("Go to the next sub-page"),
4714- "sensitive", midori_view_get_next_page (view) != NULL, NULL);
4715- }
4716
4717 action = _action_by_name (browser, "Location");
4718 if (midori_tab_is_blank (MIDORI_TAB (view)))
4719@@ -345,55 +310,6 @@
4720 midori_browser_update_secondary_icon (browser, view, action);
4721 }
4722
4723-static void
4724-_midori_browser_set_statusbar_text (MidoriBrowser* browser,
4725- MidoriView* view,
4726- const gchar* text)
4727-{
4728- #if GTK_CHECK_VERSION (3, 2, 0)
4729- gboolean is_location = FALSE;
4730- #else
4731- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
4732- gboolean is_location = widget && GTK_IS_ENTRY (widget)
4733- && GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget));
4734- #endif
4735-
4736- katze_assign (browser->statusbar_text, midori_uri_format_for_display (text));
4737- if (view == NULL)
4738- return;
4739-
4740- if (!gtk_widget_get_visible (browser->statusbar) && !is_location
4741- && text && *text)
4742- {
4743- #if GTK_CHECK_VERSION (3, 2, 0)
4744- midori_view_set_overlay_text (view, browser->statusbar_text);
4745- #else
4746- GtkAction* action = _action_by_name (browser, "Location");
4747- MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action);
4748- midori_location_action_set_text (location_action, browser->statusbar_text);
4749- midori_location_action_set_secondary_icon (location_action, NULL);
4750- #endif
4751- }
4752- else if (!gtk_widget_get_visible (browser->statusbar) && !is_location)
4753- {
4754- #if GTK_CHECK_VERSION (3, 2, 0)
4755- midori_view_set_overlay_text (view, NULL);
4756- #else
4757- GtkAction* action = _action_by_name (browser, "Location");
4758- MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action);
4759- midori_browser_update_secondary_icon (browser, view, action);
4760- midori_location_action_set_text (location_action,
4761- midori_view_get_display_uri (view));
4762- #endif
4763- }
4764- else
4765- {
4766- gtk_statusbar_pop (GTK_STATUSBAR (browser->statusbar), 1);
4767- gtk_statusbar_push (GTK_STATUSBAR (browser->statusbar), 1,
4768- katze_str_non_null (browser->statusbar_text));
4769- }
4770-}
4771-
4772 void
4773 midori_browser_set_current_page_smartly (MidoriBrowser* browser,
4774 gint n)
4775@@ -596,11 +512,6 @@
4776 }
4777 }
4778
4779-void
4780-midori_app_set_browsers (MidoriApp* app,
4781- KatzeArray* browsers,
4782- MidoriBrowser* browser);
4783-
4784 static void
4785 _midori_browser_activate_action (MidoriBrowser* browser,
4786 const gchar* name)
4787@@ -639,17 +550,9 @@
4788 }
4789 else
4790 {
4791- gchar* extension_path = midori_paths_get_lib_path (PACKAGE_NAME);
4792+ gchar* extension_path = NULL;
4793 GObject* extension = midori_extension_load_from_file (extension_path, parts[0], TRUE, FALSE);
4794- MidoriApp* app = midori_app_new_proxy (NULL);
4795- g_object_set (app,
4796- "settings", browser->settings,
4797- NULL);
4798- /* FIXME: tabs of multiple windows */
4799- KatzeArray* browsers = katze_array_new (MIDORI_TYPE_BROWSER);
4800- katze_array_add_item (browsers, browser);
4801- midori_app_set_browsers (app, browsers, browser);
4802- g_free (extension_path);
4803+ MidoriApp* app = NULL;
4804 if (extension && !strcmp (parts[1], "true"))
4805 midori_extension_activate (extension, parts[0], TRUE, app);
4806 else if (extension && !strcmp (parts[1], "false"))
4807@@ -670,6 +573,16 @@
4808 }
4809
4810 static void
4811+midori_view_action_added_cb (MidoriView* view,
4812+ guint64 id,
4813+ GVariant* user_data,
4814+ MidoriBrowser* browser)
4815+{
4816+ MidoriContextAction* action = midori_context_action_new_from_user_data (user_data);
4817+ midori_window_add_action (MIDORI_WINDOW (browser), GTK_ACTION (action));
4818+}
4819+
4820+static void
4821 midori_view_notify_icon_cb (MidoriView* view,
4822 GParamSpec* pspec,
4823 MidoriBrowser* browser)
4824@@ -704,7 +617,6 @@
4825 }
4826
4827 _midori_browser_update_interface (browser, view);
4828- _midori_browser_set_statusbar_text (browser, view, NULL);
4829 }
4830
4831 if (load_status == MIDORI_LOAD_FINISHED)
4832@@ -734,8 +646,6 @@
4833 const gchar* uri = midori_view_get_display_uri (view);
4834 GtkAction* action = _action_by_name (browser, "Location");
4835 midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
4836- _action_set_sensitive (browser, "Back", midori_view_can_go_back (view));
4837- _action_set_sensitive (browser, "Forward", midori_tab_can_go_forward (MIDORI_TAB (view)));
4838 g_object_notify (G_OBJECT (browser), "uri");
4839 }
4840 }
4841@@ -834,21 +744,6 @@
4842 midori_view_get_zoom_level (MIDORI_VIEW (view)) != 1.0f);
4843 }
4844
4845-static void
4846-midori_view_notify_statusbar_text_cb (GtkWidget* view,
4847- GParamSpec* pspec,
4848- MidoriBrowser* browser)
4849-{
4850- gchar* text;
4851-
4852- if (view == midori_browser_get_current_tab (browser))
4853- {
4854- g_object_get (view, "statusbar-text", &text, NULL);
4855- _midori_browser_set_statusbar_text (browser, MIDORI_VIEW (view), text);
4856- g_free (text);
4857- }
4858-}
4859-
4860 static gboolean
4861 midori_bookmark_folder_button_reach_parent (GtkTreeModel* model, GtkTreeIter *iter, gint64 parentid)
4862 {
4863@@ -1205,6 +1100,7 @@
4864 #endif
4865 {
4866 dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (browser),
4867+<<<<<<< TREE
4868 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, NULL, NULL);
4869 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
4870 actions = gtk_hbox_new (FALSE, 0);
4871@@ -1217,6 +1113,9 @@
4872 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
4873 g_signal_connect (dialog, "response", G_CALLBACK (midori_browser_edit_bookmark_response_cb), browser);
4874 accept = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
4875+=======
4876+ GTK_DIALOG_DESTROY_WITH_PARENT, NULL, NULL);
4877+>>>>>>> MERGE-SOURCE
4878 }
4879 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4880
4881@@ -1319,54 +1218,11 @@
4882 if (!midori_download_has_enough_space (download, uri, FALSE))
4883 return FALSE;
4884
4885-#ifdef HAVE_WEBKIT2
4886 webkit_download_set_destination (download, uri);
4887-#else
4888- webkit_download_set_destination_uri (download, uri);
4889-#endif
4890 g_signal_emit (browser, signals[ADD_DOWNLOAD], 0, download);
4891 return TRUE;
4892 }
4893
4894-#ifndef HAVE_WEBKIT2
4895-static void
4896-midori_browser_save_resources (GList* resources,
4897- const gchar* folder)
4898-{
4899- GList* list;
4900- katze_mkdir_with_parents (folder, 0700);
4901-
4902- for (list = resources; list; list = g_list_next (list))
4903- {
4904- WebKitWebResource* resource = WEBKIT_WEB_RESOURCE (list->data);
4905- GString* data = webkit_web_resource_get_data (resource);
4906-
4907- /* Resource could be adblocked, skip it in that case */
4908- if (!g_strcmp0 (webkit_web_resource_get_uri (resource), "about:blank"))
4909- continue;
4910-
4911- gchar* sub_filename = midori_download_get_filename_suggestion_for_uri (
4912- webkit_web_resource_get_mime_type (resource),
4913- webkit_web_resource_get_uri (resource));
4914- gchar* sub_path = g_build_filename (folder, sub_filename, NULL);
4915- sub_path = midori_download_get_unique_filename (sub_path);
4916- if (data)
4917- {
4918- GError* error = NULL;
4919- if (!g_file_set_contents (sub_path, data->str, data->len, &error))
4920- {
4921- g_warning ("Failed to save %s: %s", sub_filename, error->message);
4922- g_error_free (error);
4923- }
4924- }
4925- else
4926- g_warning ("Skipping empty resource %s", sub_filename);
4927- g_free (sub_filename);
4928- g_free (sub_path);
4929- }
4930-}
4931-#endif
4932-
4933 void
4934 midori_browser_save_uri (MidoriBrowser* browser,
4935 MidoriView* view,
4936@@ -1395,50 +1251,6 @@
4937 g_free (dirname);
4938 }
4939
4940-#ifndef HAVE_WEBKIT2
4941- GList* resources = midori_view_get_resources (view);
4942- gboolean file_only = TRUE;
4943- GtkWidget* checkbox = NULL;
4944-
4945- if (resources != NULL && g_list_nth_data (resources, 1) != NULL)
4946- {
4947- file_only = FALSE;
4948- checkbox = gtk_check_button_new_with_mnemonic (_("Save associated _resources"));
4949- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), TRUE);
4950- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), checkbox);
4951- }
4952-
4953- if (!file_only && !g_str_equal (title, uri))
4954- filename = midori_download_clean_filename (title);
4955- else
4956- {
4957- gchar* mime_type = katze_object_get_object (view, "mime-type");
4958- filename = midori_download_get_filename_suggestion_for_uri (mime_type, uri);
4959- g_free (mime_type);
4960- }
4961- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
4962- g_free (filename);
4963-
4964- if (midori_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
4965- {
4966- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
4967- if (checkbox != NULL)
4968- file_only = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
4969- if (!file_only)
4970- {
4971- gchar* fullname = g_strconcat (filename, ".html", NULL);
4972- midori_view_save_source (view, uri, fullname, FALSE);
4973- g_free (fullname);
4974- midori_browser_save_resources (resources, filename);
4975- }
4976- else
4977- midori_view_save_source (view, uri, filename, FALSE);
4978- katze_assign (last_dir,
4979- gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)));
4980- }
4981- g_list_foreach (resources, (GFunc)g_object_unref, NULL);
4982- g_list_free (resources);
4983-#else
4984 filename = midori_download_clean_filename (title);
4985 gchar* suggested_filename = g_strconcat (filename, ".mht", NULL);
4986 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested_filename);
4987@@ -1456,7 +1268,6 @@
4988 katze_assign (last_dir,
4989 gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)));
4990 }
4991-#endif
4992 gtk_widget_destroy (dialog);
4993 }
4994
4995@@ -1480,15 +1291,6 @@
4996 midori_view_get_display_title (MIDORI_VIEW (view)), NULL);
4997 }
4998
4999-static gboolean
5000-midori_browser_tab_leave_notify_event_cb (GtkWidget* widget,
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: