Merge branch 'upstream-unstable'
This commit is contained in:
commit
bf2d83aba2
78 changed files with 25888 additions and 20487 deletions
26
ChangeLog
26
ChangeLog
|
@ -1,5 +1,31 @@
|
||||||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||||
|
|
||||||
|
v0.4.4:
|
||||||
|
+ Disable page cache with < 352 MB RAM
|
||||||
|
+ Display filename in download dialog
|
||||||
|
+ Fix box packing in GTK+3 (in most cases)
|
||||||
|
+ Enable experimental HTML5 fullscreen API
|
||||||
|
+ Harden IPv6 address recognition in location
|
||||||
|
+ Experimental site data policy support (see FAQ)
|
||||||
|
+ Close tabs by middle clicking close button
|
||||||
|
+ Merge cookies and other data in Clear Private Data
|
||||||
|
+ Improve KatzeArrayAction for Unity menuproxy compatibility
|
||||||
|
+ Use GDateTime for history to avoid broken C runtimes
|
||||||
|
+ Add Midori tag to DuckDuckGo default URI
|
||||||
|
+ Rewrite completion popup resizing
|
||||||
|
+ Streamline page icon loading stages and fallbacks
|
||||||
|
+ Disable clipboard work-around for WebKit >= 1.4.3
|
||||||
|
+ Re-word .desktop entry as an action
|
||||||
|
+ Display informative text in private browsing
|
||||||
|
+ Consistent clear icons in entries
|
||||||
|
+ Revised download filename generation
|
||||||
|
+ Add 'Open in Image Viewer' menu item
|
||||||
|
+ Formhistory 2.0 with GDOM support
|
||||||
|
+ Handle javascript: and mailto: links better
|
||||||
|
+ Handle = key in Ukrainian layout better
|
||||||
|
+ Fix bookmark export and deletion of bookmark folders
|
||||||
|
+ Speed dial shortcut re-reordering by DND
|
||||||
|
|
||||||
v0.4.3:
|
v0.4.3:
|
||||||
+ Implement about:widgets to test rendering
|
+ Implement about:widgets to test rendering
|
||||||
+ Fix resizing of inspector by applying a minimum size
|
+ Fix resizing of inspector by applying a minimum size
|
||||||
|
|
2
INSTALL
2
INSTALL
|
@ -67,6 +67,8 @@ If you want to "dry run" without WebKitGTK+ rendering, try this:
|
||||||
|
|
||||||
'MIDORI_UNARMED=1 _build_/default/midori/midori'
|
'MIDORI_UNARMED=1 _build_/default/midori/midori'
|
||||||
|
|
||||||
|
To disable Netscape plugins, use MOZ_PLUGIN_PATH=/.
|
||||||
|
|
||||||
To debug extensions you can specify the path:
|
To debug extensions you can specify the path:
|
||||||
|
|
||||||
'export MIDORI_EXTENSION_PATH=_build_/default/extensions'
|
'export MIDORI_EXTENSION_PATH=_build_/default/extensions'
|
||||||
|
|
57
data/about.css
Normal file
57
data/about.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
about: page style template for Midori.
|
||||||
|
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
background-color: #eee;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
background: #f6fff3;
|
||||||
|
min-width: 70%;
|
||||||
|
max-width: 70%;
|
||||||
|
margin: 2em auto 1em;
|
||||||
|
padding: 1em;
|
||||||
|
border: 0.2em solid #9acb7f;
|
||||||
|
-webkit-border-radius: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon {
|
||||||
|
float: left;
|
||||||
|
padding-left: 1%;
|
||||||
|
padding-top: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
float: right;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.4em;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
position: absolute; right: 15px; bottom: 15px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button span,
|
||||||
|
button img {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 2px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
message {
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
description {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
|
@ -2,67 +2,11 @@
|
||||||
Error page template for Midori.
|
Error page template for Midori.
|
||||||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<link rel="shortcut icon" href="{icon}" />
|
<link rel="shortcut icon" href="{icon}" />
|
||||||
<style type="text/css">
|
<link rel="stylesheet" type="text/css" href="res://about.css" />
|
||||||
body {
|
|
||||||
background-color: #eee;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#container {
|
|
||||||
background: #f6fff3;
|
|
||||||
min-width: 70%;
|
|
||||||
max-width: 70%;
|
|
||||||
margin: 2em auto 1em;
|
|
||||||
padding: 1em;
|
|
||||||
border: 0.2em solid #9acb7f;
|
|
||||||
-webkit-border-radius: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
icon {
|
|
||||||
float: left;
|
|
||||||
padding-left: 1%;
|
|
||||||
padding-top: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main {
|
|
||||||
float: right;
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 1.4em;
|
|
||||||
font-weight: bold;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo {
|
|
||||||
position: absolute; right: 15px; bottom: 15px;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
button span,
|
|
||||||
button img {
|
|
||||||
vertical-align: middle;
|
|
||||||
padding: 2px 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
message {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
description {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
|
|
|
@ -3,7 +3,7 @@ Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
_Name=Midori
|
_Name=Midori
|
||||||
_GenericName=Web Browser
|
_GenericName=Web Browser
|
||||||
_Comment=Lightweight web browser
|
_Comment=Browse the Web
|
||||||
_X-GNOME-Keywords=Internet;WWW;Explorer
|
_X-GNOME-Keywords=Internet;WWW;Explorer
|
||||||
_X-AppInstall-Keywords=Internet;WWW;Explorer
|
_X-AppInstall-Keywords=Internet;WWW;Explorer
|
||||||
Categories=GTK;Network;WebBrowser;
|
Categories=GTK;Network;WebBrowser;
|
||||||
|
|
|
@ -55,10 +55,7 @@
|
||||||
width: 85%;
|
width: 85%;
|
||||||
height: 75%;
|
height: 75%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
-webkit-box-shadow: 0 4px 18px rgba(0,0,0,.3), 0 0 2px #fff inset;
|
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,.3), 0 0 0px #fff inset;
|
||||||
background-image: -webkit-gradient(
|
|
||||||
linear, center top, center bottom,
|
|
||||||
from(#f6f6f6), to(#e3e3e3));
|
|
||||||
border: 1px solid #bcbcbc;
|
border: 1px solid #bcbcbc;
|
||||||
border-bottom-color: #a0a0a0;
|
border-bottom-color: #a0a0a0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -75,9 +72,15 @@
|
||||||
div.shortcut .preview.new .add {
|
div.shortcut .preview.new .add {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 50%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,.3), 0 0 0px #fff inset;
|
||||||
|
background-image: -webkit-gradient(
|
||||||
|
linear, center top, center bottom,
|
||||||
|
from(#f6f6f6), to(#e3e3e3));
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -126,6 +129,11 @@
|
||||||
-webkit-border-bottom-left-radius: 10px;
|
-webkit-border-bottom-left-radius: 10px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
outline: 1px dotted black;
|
||||||
|
background-color: #eef;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -196,6 +204,72 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var firstNode, secondNode;
|
||||||
|
var cursor;
|
||||||
|
var dial = document.getElementsByClassName("shortcut");
|
||||||
|
|
||||||
|
var get_dial_div = function (ele) {
|
||||||
|
var dial_div;
|
||||||
|
if (ele.nodeName == 'IMG')
|
||||||
|
dial_div = ele.parentNode.parentNode.parentNode;
|
||||||
|
if (ele.className == 'title')
|
||||||
|
dial_div = ele.parentNode;
|
||||||
|
if (ele.className.indexOf ('shortcut') != -1)
|
||||||
|
dial_dir = ele;
|
||||||
|
return dial_div;
|
||||||
|
}
|
||||||
|
var click = function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
var ele = ev.target;
|
||||||
|
cursor = ele.style.cursor;
|
||||||
|
ele.style.cursor = 'move';
|
||||||
|
|
||||||
|
var eparent = get_dial_div (ele);
|
||||||
|
if (eparent != undefined) {
|
||||||
|
eparent.className = 'shortcut selected';
|
||||||
|
firstNode = eparent.id;
|
||||||
|
}
|
||||||
|
document.RemoveEventListener('click', click, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
var up = function (ev) {
|
||||||
|
ele = ev.target;
|
||||||
|
var eparent = get_dial_div (ele);
|
||||||
|
|
||||||
|
ele.style.cursor = cursor;
|
||||||
|
secondNode = eparent.id;
|
||||||
|
|
||||||
|
/* ommit just mere clicking the dial */
|
||||||
|
if (firstNode != secondNode && firstNode != undefined)
|
||||||
|
swap();
|
||||||
|
};
|
||||||
|
|
||||||
|
var over = function (ev) {
|
||||||
|
if (ev == undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ele = ev.target;
|
||||||
|
var eparent = get_dial_div (ele);
|
||||||
|
|
||||||
|
if (firstNode != undefined)
|
||||||
|
{
|
||||||
|
eparent.className = 'shortcut selected';
|
||||||
|
for (var i = 0; i <= dial.length; i++) {
|
||||||
|
if (eparent.id != firstNode.id && dial[i].id != eparent.id) {
|
||||||
|
dial[i].className = 'shortcut';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ele.style.cursor = cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function swap () {
|
||||||
|
console.log ("speed_dial-save-swap " + firstNode + " " + secondNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', click, false);
|
||||||
|
document.addEventListener('mouseup', up, false);
|
||||||
|
document.addEventListener('mouseover', over, false);
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2009-2010 Christian Dywan <christian@twotoasts.de>
|
Copyright (C) 2009-2012 Christian Dywan <christian@twotoasts.de>
|
||||||
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
See the file COPYING for the full license text.
|
See the file COPYING for the full license text.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <midori/midori.h>
|
#include <midori/midori.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
@ -35,13 +34,12 @@
|
||||||
#define adblock_debug(dmsg, darg1, darg2) /* nothing */
|
#define adblock_debug(dmsg, darg1, darg2) /* nothing */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static GHashTable* pattern;
|
static GHashTable* pattern = NULL;
|
||||||
static GHashTable* keys;
|
static GHashTable* keys = NULL;
|
||||||
static GHashTable* optslist;
|
static GHashTable* optslist = NULL;
|
||||||
static GHashTable* urlcache;
|
static GHashTable* urlcache = NULL;
|
||||||
static GString* blockcss;
|
static GHashTable* blockcssprivate = NULL;
|
||||||
static GString* blockcssprivate;
|
static GString* blockcss = NULL;
|
||||||
static gchar* blockscript = NULL;
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
static guint debug;
|
static guint debug;
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,43 +52,83 @@ adblock_reload_rules (MidoriExtension* extension,
|
||||||
gboolean custom_only);
|
gboolean custom_only);
|
||||||
|
|
||||||
static gchar*
|
static gchar*
|
||||||
adblock_build_js (const gchar* private)
|
adblock_build_js (const gchar* uri)
|
||||||
{
|
{
|
||||||
return g_strdup_printf (
|
gchar* domain;
|
||||||
|
const gchar* style;
|
||||||
|
GString* subdomain;
|
||||||
|
GString* code;
|
||||||
|
int cnt = 0, blockscnt = 0;
|
||||||
|
gchar** subdomains;
|
||||||
|
|
||||||
|
domain = midori_uri_parse_hostname (uri, NULL);
|
||||||
|
subdomains = g_strsplit (domain, ".", -1);
|
||||||
|
g_free (domain);
|
||||||
|
if (!subdomains)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
code = g_string_new (
|
||||||
"window.addEventListener ('DOMContentLoaded',"
|
"window.addEventListener ('DOMContentLoaded',"
|
||||||
"function () {"
|
"function () {"
|
||||||
" if (document.getElementById('madblock'))"
|
" if (document.getElementById('madblock'))"
|
||||||
" return;"
|
" return;"
|
||||||
// Get just domain name from URL
|
" public = '");
|
||||||
" var URL = location.href.match(/:\\/\\/(.[^/]+)/)[1];"
|
|
||||||
" var sites = new Array(); %s;"
|
cnt = g_strv_length (subdomains) - 1;
|
||||||
" var public = '.madblockplaceholder ';"
|
subdomain = g_string_new (subdomains [cnt]);
|
||||||
// Split domain into subdomain parts
|
g_string_prepend_c (subdomain, '.');
|
||||||
" var subdomains = URL.split ('.');"
|
cnt--;
|
||||||
" var hostname = subdomains [subdomains.length - 1];"
|
while (cnt >= 0)
|
||||||
" var i = subdomains.length - 2;"
|
{
|
||||||
// Check if any of subdomains do have blocking rules
|
g_string_prepend (subdomain, subdomains[cnt]);
|
||||||
" while (i >= 0) {"
|
if ((style = g_hash_table_lookup (blockcssprivate, subdomain->str)))
|
||||||
" hostname = subdomains [i] + '.' + hostname;"
|
{
|
||||||
" if (sites [hostname])"
|
g_string_append (code, style);
|
||||||
" public += ', ' + sites [hostname];"
|
g_string_append_c (code, ',');
|
||||||
" i--;"
|
blockscnt++;
|
||||||
" }"
|
}
|
||||||
" public += ' {display: none !important}';"
|
g_string_prepend_c (subdomain, '.');
|
||||||
|
cnt--;
|
||||||
|
}
|
||||||
|
g_string_free (subdomain, TRUE);
|
||||||
|
g_strfreev (subdomains);
|
||||||
|
|
||||||
|
if (blockscnt == 0)
|
||||||
|
return g_string_free (code, TRUE);
|
||||||
|
|
||||||
|
g_string_append (code,
|
||||||
|
" zz-non-existent {display: none !important}';"
|
||||||
" var mystyle = document.createElement('style');"
|
" var mystyle = document.createElement('style');"
|
||||||
" mystyle.setAttribute('type', 'text/css');"
|
" mystyle.setAttribute('type', 'text/css');"
|
||||||
" mystyle.setAttribute('id', 'madblock');"
|
" mystyle.setAttribute('id', 'madblock');"
|
||||||
" mystyle.appendChild(document.createTextNode(public));"
|
" mystyle.appendChild(document.createTextNode(public));"
|
||||||
" var head = document.getElementsByTagName('head')[0];"
|
" var head = document.getElementsByTagName('head')[0];"
|
||||||
" if (head) head.appendChild(mystyle);"
|
" if (head) head.appendChild(mystyle);"
|
||||||
"}, true);",
|
"}, true);");
|
||||||
private);
|
return g_string_free (code, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GString*
|
static GString*
|
||||||
adblock_fixup_regexp (const gchar* prefix,
|
adblock_fixup_regexp (const gchar* prefix,
|
||||||
gchar* src);
|
gchar* src);
|
||||||
|
|
||||||
|
static void
|
||||||
|
adblock_destroy_db ()
|
||||||
|
{
|
||||||
|
if (blockcss)
|
||||||
|
g_string_free (blockcss, TRUE);
|
||||||
|
blockcss = NULL;
|
||||||
|
|
||||||
|
g_hash_table_destroy (pattern);
|
||||||
|
pattern = NULL;
|
||||||
|
g_hash_table_destroy (optslist);
|
||||||
|
optslist = NULL;
|
||||||
|
g_hash_table_destroy (urlcache);
|
||||||
|
urlcache = NULL;
|
||||||
|
g_hash_table_destroy (blockcssprivate);
|
||||||
|
blockcssprivate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adblock_init_db ()
|
adblock_init_db ()
|
||||||
{
|
{
|
||||||
|
@ -106,12 +144,13 @@ adblock_init_db ()
|
||||||
urlcache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
urlcache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
(GDestroyNotify)g_free,
|
(GDestroyNotify)g_free,
|
||||||
(GDestroyNotify)g_free);
|
(GDestroyNotify)g_free);
|
||||||
|
blockcssprivate = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
(GDestroyNotify)g_free,
|
||||||
|
(GDestroyNotify)g_free);
|
||||||
|
|
||||||
if (blockcss && blockcss->len > 0)
|
if (blockcss && blockcss->len > 0)
|
||||||
g_string_free (blockcss, TRUE);
|
g_string_free (blockcss, TRUE);
|
||||||
if (blockcssprivate && blockcssprivate->len > 0)
|
|
||||||
g_string_free (blockcssprivate, TRUE);
|
|
||||||
blockcss = g_string_new ("z-non-exist");
|
blockcss = g_string_new ("z-non-exist");
|
||||||
blockcssprivate = g_string_new ("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -119,23 +158,9 @@ adblock_download_notify_status_cb (WebKitDownload* download,
|
||||||
GParamSpec* pspec,
|
GParamSpec* pspec,
|
||||||
MidoriExtension* extension)
|
MidoriExtension* extension)
|
||||||
{
|
{
|
||||||
gchar* path;
|
|
||||||
MidoriApp* app;
|
|
||||||
MidoriWebSettings* settings;
|
|
||||||
|
|
||||||
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_FINISHED)
|
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_FINISHED)
|
||||||
return;
|
return;
|
||||||
|
adblock_reload_rules (extension, FALSE);
|
||||||
path = g_filename_from_uri (webkit_download_get_destination_uri (download), NULL, NULL);
|
|
||||||
adblock_parse_file (path);
|
|
||||||
g_free (path);
|
|
||||||
|
|
||||||
app = midori_extension_get_app (extension);
|
|
||||||
settings = katze_object_get_object (app, "settings");
|
|
||||||
g_string_append (blockcss, " {display: none !important}\n");
|
|
||||||
midori_web_settings_add_style (settings, "adblock-blockcss", blockcss->str);
|
|
||||||
katze_assign (blockscript, adblock_build_js (blockcssprivate->str));
|
|
||||||
g_object_unref (settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
static gchar*
|
||||||
|
@ -174,6 +199,8 @@ adblock_reload_rules (MidoriExtension* extension,
|
||||||
MidoriApp* app = midori_extension_get_app (extension);
|
MidoriApp* app = midori_extension_get_app (extension);
|
||||||
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
|
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
|
||||||
|
|
||||||
|
if (pattern)
|
||||||
|
adblock_destroy_db ();
|
||||||
adblock_init_db ();
|
adblock_init_db ();
|
||||||
|
|
||||||
custom_list = g_build_filename (midori_extension_get_config_dir (extension),
|
custom_list = g_build_filename (midori_extension_get_config_dir (extension),
|
||||||
|
@ -215,7 +242,6 @@ adblock_reload_rules (MidoriExtension* extension,
|
||||||
g_strfreev (filters);
|
g_strfreev (filters);
|
||||||
g_string_append (blockcss, " {display: none !important}\n");
|
g_string_append (blockcss, " {display: none !important}\n");
|
||||||
|
|
||||||
katze_assign (blockscript, adblock_build_js (blockcssprivate->str));
|
|
||||||
midori_web_settings_add_style (settings, "adblock-blockcss", blockcss->str);
|
midori_web_settings_add_style (settings, "adblock-blockcss", blockcss->str);
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
}
|
}
|
||||||
|
@ -622,7 +648,9 @@ adblock_check_rule (GRegex* regex,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* TODO: Domain opt check */
|
/* TODO: Domain opt check */
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
adblock_debug ("blocked by pattern regexp=%s -- %s", g_regex_get_pattern (regex), req_uri);
|
adblock_debug ("blocked by pattern regexp=%s -- %s", g_regex_get_pattern (regex), req_uri);
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,11 +797,6 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
|
||||||
if (midori_uri_is_blank (page_uri))
|
if (midori_uri_is_blank (page_uri))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Never filter the main page itself */
|
|
||||||
if (web_frame == webkit_web_view_get_main_frame (web_view)
|
|
||||||
&& webkit_web_frame_get_load_status (web_frame) == WEBKIT_LOAD_PROVISIONAL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
req_uri = webkit_network_request_get_uri (request);
|
req_uri = webkit_network_request_get_uri (request);
|
||||||
if (!midori_uri_is_http (req_uri)
|
if (!midori_uri_is_http (req_uri)
|
||||||
|| g_str_has_suffix (req_uri, "favicon.ico"))
|
|| g_str_has_suffix (req_uri, "favicon.ico"))
|
||||||
|
@ -932,13 +955,19 @@ adblock_window_object_cleared_cb (WebKitWebView* web_view,
|
||||||
JSObjectRef js_window)
|
JSObjectRef js_window)
|
||||||
{
|
{
|
||||||
const char *page_uri;
|
const char *page_uri;
|
||||||
|
gchar* script;
|
||||||
|
|
||||||
page_uri = webkit_web_frame_get_uri (web_frame);
|
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||||
/* Don't add adblock css into speeddial and about: pages */
|
/* Don't add adblock css into speeddial and about: pages */
|
||||||
if (!midori_uri_is_http (page_uri))
|
if (!midori_uri_is_http (page_uri))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_free (sokoke_js_script_eval (js_context, blockscript, NULL));
|
script = adblock_build_js (page_uri);
|
||||||
|
if (!script)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free (sokoke_js_script_eval (js_context, script, NULL));
|
||||||
|
g_free (script);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1089,7 +1118,9 @@ adblock_compile_regexp (GString* gpatt,
|
||||||
if (!g_regex_match_simple ("[\\*]", sig, G_REGEX_UNGREEDY, G_REGEX_MATCH_NOTEMPTY) &&
|
if (!g_regex_match_simple ("[\\*]", sig, G_REGEX_UNGREEDY, G_REGEX_MATCH_NOTEMPTY) &&
|
||||||
!g_hash_table_lookup (keys, sig))
|
!g_hash_table_lookup (keys, sig))
|
||||||
{
|
{
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
adblock_debug ("sig: %s %s", sig, patt);
|
adblock_debug ("sig: %s %s", sig, patt);
|
||||||
|
#endif
|
||||||
g_hash_table_insert (keys, sig, regex);
|
g_hash_table_insert (keys, sig, regex);
|
||||||
g_hash_table_insert (optslist, sig, g_strdup (opts));
|
g_hash_table_insert (optslist, sig, g_strdup (opts));
|
||||||
signature_count++;
|
signature_count++;
|
||||||
|
@ -1099,7 +1130,9 @@ adblock_compile_regexp (GString* gpatt,
|
||||||
if (g_regex_match_simple ("^\\*", sig, G_REGEX_UNGREEDY, G_REGEX_MATCH_NOTEMPTY) &&
|
if (g_regex_match_simple ("^\\*", sig, G_REGEX_UNGREEDY, G_REGEX_MATCH_NOTEMPTY) &&
|
||||||
!g_hash_table_lookup (pattern, patt))
|
!g_hash_table_lookup (pattern, patt))
|
||||||
{
|
{
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
adblock_debug ("patt2: %s %s", sig, patt);
|
adblock_debug ("patt2: %s %s", sig, patt);
|
||||||
|
#endif
|
||||||
g_hash_table_insert (pattern, patt, regex);
|
g_hash_table_insert (pattern, patt, regex);
|
||||||
g_hash_table_insert (optslist, patt, g_strdup (opts));
|
g_hash_table_insert (optslist, patt, g_strdup (opts));
|
||||||
}
|
}
|
||||||
|
@ -1115,7 +1148,9 @@ adblock_compile_regexp (GString* gpatt,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
adblock_debug ("patt: %s%s", patt, "");
|
adblock_debug ("patt: %s%s", patt, "");
|
||||||
|
#endif
|
||||||
/* Pattern is a regexp chars */
|
/* Pattern is a regexp chars */
|
||||||
g_hash_table_insert (pattern, patt, regex);
|
g_hash_table_insert (pattern, patt, regex);
|
||||||
g_hash_table_insert (optslist, patt, g_strdup (opts));
|
g_hash_table_insert (optslist, patt, g_strdup (opts));
|
||||||
|
@ -1170,7 +1205,9 @@ adblock_add_url_pattern (gchar* prefix,
|
||||||
|
|
||||||
format_patt = adblock_fixup_regexp (prefix, patt);
|
format_patt = adblock_fixup_regexp (prefix, patt);
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
adblock_debug ("got: %s opts %s", format_patt->str, opts);
|
adblock_debug ("got: %s opts %s", format_patt->str, opts);
|
||||||
|
#endif
|
||||||
should_free = adblock_compile_regexp (format_patt, opts);
|
should_free = adblock_compile_regexp (format_patt, opts);
|
||||||
|
|
||||||
if (data[1] && data[2])
|
if (data[1] && data[2])
|
||||||
|
@ -1200,6 +1237,22 @@ adblock_frame_add (gchar* line)
|
||||||
g_string_append (blockcss, line);
|
g_string_append (blockcss, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
adblock_update_css_hash (gchar* domain,
|
||||||
|
gchar* value)
|
||||||
|
{
|
||||||
|
const gchar* olddata;
|
||||||
|
gchar* newdata;
|
||||||
|
|
||||||
|
if ((olddata = g_hash_table_lookup (blockcssprivate, domain)))
|
||||||
|
{
|
||||||
|
newdata = g_strconcat (olddata, " , ", value, NULL);
|
||||||
|
g_hash_table_replace (blockcssprivate, g_strdup (domain), newdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_hash_table_insert (blockcssprivate, g_strdup (domain), g_strdup (value));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
adblock_frame_add_private (const gchar* line,
|
adblock_frame_add_private (const gchar* line,
|
||||||
const gchar* sep)
|
const gchar* sep)
|
||||||
|
@ -1234,15 +1287,13 @@ adblock_frame_add_private (const gchar* line,
|
||||||
/* strip ~ from domain */
|
/* strip ~ from domain */
|
||||||
if (domain[0] == '~')
|
if (domain[0] == '~')
|
||||||
domain++;
|
domain++;
|
||||||
g_string_append_printf (blockcssprivate, ";sites['%s']+=',%s'",
|
adblock_update_css_hash (g_strstrip (domain), data[1]);
|
||||||
g_strstrip (domain), data[1]);
|
|
||||||
}
|
}
|
||||||
g_strfreev (domains);
|
g_strfreev (domains);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_string_append_printf (blockcssprivate, ";sites['%s']+=',%s'",
|
adblock_update_css_hash (data[0], data[1]);
|
||||||
data[0], data[1]);
|
|
||||||
}
|
}
|
||||||
g_strfreev (data);
|
g_strfreev (data);
|
||||||
}
|
}
|
||||||
|
@ -1250,12 +1301,10 @@ adblock_frame_add_private (const gchar* line,
|
||||||
static gchar*
|
static gchar*
|
||||||
adblock_parse_line (gchar* line)
|
adblock_parse_line (gchar* line)
|
||||||
{
|
{
|
||||||
if (!line)
|
/* Skip invalid, empty and comment lines */
|
||||||
return NULL;
|
if (!(line && line[0] != ' ' && line[0] != '!' && line[0]))
|
||||||
g_strchomp (line);
|
|
||||||
/* Ignore comments and new lines */
|
|
||||||
if (line[0] == '!')
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* FIXME: No support for whitelisting */
|
/* FIXME: No support for whitelisting */
|
||||||
if (line[0] == '@' && line[1] == '@')
|
if (line[0] == '@' && line[1] == '@')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1263,9 +1312,7 @@ adblock_parse_line (gchar* line)
|
||||||
if (line[0] == '[')
|
if (line[0] == '[')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Skip garbage */
|
g_strchomp (line);
|
||||||
if (line[0] == ' ' || !line[0])
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Got CSS block hider */
|
/* Got CSS block hider */
|
||||||
if (line[0] == '#' && line[1] == '#' )
|
if (line[0] == '#' && line[1] == '#' )
|
||||||
|
@ -1283,13 +1330,13 @@ adblock_parse_line (gchar* line)
|
||||||
adblock_frame_add_private (line, "##");
|
adblock_frame_add_private (line, "##");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Got per domain CSS hider rule. Workaround */
|
/* Got per domain CSS hider rule. Workaround */
|
||||||
if (strchr (line, '#'))
|
if (strchr (line, '#'))
|
||||||
{
|
{
|
||||||
adblock_frame_add_private (line, "#");
|
adblock_frame_add_private (line, "#");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Got URL blocker rule */
|
/* Got URL blocker rule */
|
||||||
if (line[0] == '|' && line[1] == '|' )
|
if (line[0] == '|' && line[1] == '|' )
|
||||||
{
|
{
|
||||||
|
@ -1358,16 +1405,8 @@ adblock_deactivate_cb (MidoriExtension* extension,
|
||||||
browser, adblock_add_tab_cb, extension);
|
browser, adblock_add_tab_cb, extension);
|
||||||
midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, browser);
|
midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, browser);
|
||||||
|
|
||||||
if (blockcss)
|
adblock_destroy_db ();
|
||||||
g_string_free (blockcss, TRUE);
|
|
||||||
if (blockcssprivate)
|
|
||||||
g_string_free (blockcssprivate, TRUE);
|
|
||||||
|
|
||||||
midori_web_settings_remove_style (settings, "adblock-blockcss");
|
midori_web_settings_remove_style (settings, "adblock-blockcss");
|
||||||
blockcssprivate = blockcss = NULL;
|
|
||||||
g_hash_table_destroy (pattern);
|
|
||||||
g_hash_table_destroy (optslist);
|
|
||||||
g_hash_table_destroy (urlcache);
|
|
||||||
g_object_unref (settings);
|
g_object_unref (settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,7 +1537,7 @@ extension_init (void)
|
||||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||||
"name", _("Advertisement blocker"),
|
"name", _("Advertisement blocker"),
|
||||||
"description", _("Block advertisements according to a filter list"),
|
"description", _("Block advertisements according to a filter list"),
|
||||||
"version", "0.5" MIDORI_VERSION_SUFFIX,
|
"version", "0.6" MIDORI_VERSION_SUFFIX,
|
||||||
"authors", "Christian Dywan <christian@twotoasts.de>",
|
"authors", "Christian Dywan <christian@twotoasts.de>",
|
||||||
NULL);
|
NULL);
|
||||||
midori_extension_install_string_list (extension, "filters", NULL, G_MAXSIZE);
|
midori_extension_install_string_list (extension, "filters", NULL, G_MAXSIZE);
|
||||||
|
|
|
@ -48,11 +48,10 @@ colorful_tabs_view_notify_uri_cb (MidoriView* view,
|
||||||
|
|
||||||
if (!midori_uri_is_blank (midori_view_get_display_uri (view))
|
if (!midori_uri_is_blank (midori_view_get_display_uri (view))
|
||||||
&& (hostname = midori_uri_parse_hostname (midori_view_get_display_uri (view), NULL))
|
&& (hostname = midori_uri_parse_hostname (midori_view_get_display_uri (view), NULL))
|
||||||
&& katze_object_get_enum (view, "load-status") == MIDORI_LOAD_FINISHED)
|
&& midori_view_get_icon_uri (view) != NULL)
|
||||||
{
|
{
|
||||||
icon = midori_view_get_icon (view);
|
icon = midori_view_get_icon (view);
|
||||||
|
if (icon != NULL)
|
||||||
if (midori_view_get_icon_uri (view) != NULL)
|
|
||||||
{
|
{
|
||||||
GdkPixbuf* newpix;
|
GdkPixbuf* newpix;
|
||||||
guchar* pixels;
|
guchar* pixels;
|
||||||
|
|
|
@ -840,7 +840,8 @@ feed_panel_init (FeedPanel* panel)
|
||||||
|
|
||||||
webview = webkit_web_view_new ();
|
webview = webkit_web_view_new ();
|
||||||
#if GTK_CHECK_VERSION(3,0,0)
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
font_desc = gtk_style_context_get_font(gtk_widget_get_style_context(treeview), GTK_STATE_FLAG_NORMAL);
|
font_desc = (PangoFontDescription*)gtk_style_context_get_font (
|
||||||
|
gtk_widget_get_style_context (treeview), GTK_STATE_FLAG_NORMAL);
|
||||||
#else
|
#else
|
||||||
font_desc = treeview->style->font_desc;
|
font_desc = treeview->style->font_desc;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,600 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
|
|
||||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAXCHARS 60
|
|
||||||
#define MINCHARS 2
|
|
||||||
|
|
||||||
#include <midori/midori.h>
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#if HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static GHashTable* global_keys;
|
|
||||||
static gchar* jsforms;
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_toggle_state_cb (GtkAction* action,
|
|
||||||
MidoriBrowser* browser);
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
formhistory_prepare_js ()
|
|
||||||
{
|
|
||||||
gchar* autosuggest;
|
|
||||||
gchar* style;
|
|
||||||
guint i;
|
|
||||||
gchar* file;
|
|
||||||
|
|
||||||
file = sokoke_find_data_filename ("autosuggestcontrol.js", TRUE);
|
|
||||||
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
|
|
||||||
{
|
|
||||||
g_free (file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
g_strchomp (autosuggest);
|
|
||||||
|
|
||||||
katze_assign (file, sokoke_find_data_filename ("autosuggestcontrol.css", TRUE));
|
|
||||||
if (!g_file_get_contents (file, &style, NULL, NULL))
|
|
||||||
{
|
|
||||||
g_free (file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
g_strchomp (style);
|
|
||||||
i = 0;
|
|
||||||
while (style[i])
|
|
||||||
{
|
|
||||||
if (style[i] == '\n')
|
|
||||||
style[i] = ' ';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsforms = g_strdup_printf (
|
|
||||||
"%s"
|
|
||||||
"window.addEventListener ('DOMContentLoaded',"
|
|
||||||
"function () {"
|
|
||||||
" if (document.getElementById('formhistory'))"
|
|
||||||
" return;"
|
|
||||||
" if (!initSuggestions ())"
|
|
||||||
" return;"
|
|
||||||
" var mystyle = document.createElement('style');"
|
|
||||||
" mystyle.setAttribute('type', 'text/css');"
|
|
||||||
" mystyle.setAttribute('id', 'formhistory');"
|
|
||||||
" mystyle.appendChild(document.createTextNode('%s'));"
|
|
||||||
" var head = document.getElementsByTagName('head')[0];"
|
|
||||||
" if (head) head.appendChild(mystyle);"
|
|
||||||
"}, true);",
|
|
||||||
autosuggest,
|
|
||||||
style);
|
|
||||||
g_strstrip (jsforms);
|
|
||||||
g_free (file);
|
|
||||||
g_free (style);
|
|
||||||
g_free (autosuggest);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar*
|
|
||||||
formhistory_fixup_value (char* value)
|
|
||||||
{
|
|
||||||
guint i = 0;
|
|
||||||
g_strchomp (value);
|
|
||||||
while (value[i])
|
|
||||||
{
|
|
||||||
if (value[i] == '\n')
|
|
||||||
value[i] = ' ';
|
|
||||||
else if (value[i] == '"')
|
|
||||||
value[i] = '\'';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar*
|
|
||||||
formhistory_build_js ()
|
|
||||||
{
|
|
||||||
GString* suggestions;
|
|
||||||
GHashTableIter iter;
|
|
||||||
gpointer key, value;
|
|
||||||
|
|
||||||
suggestions = g_string_new (
|
|
||||||
"function FormSuggestions(eid) { "
|
|
||||||
"arr = new Array();");
|
|
||||||
g_hash_table_iter_init (&iter, global_keys);
|
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
{
|
|
||||||
g_string_append_printf (suggestions, " arr[\"%s\"] = [%s]; ",
|
|
||||||
(gchar*)key, (gchar*)value);
|
|
||||||
}
|
|
||||||
g_string_append (suggestions, "this.suggestions = arr[eid]; }");
|
|
||||||
g_string_append (suggestions, jsforms);
|
|
||||||
return g_string_free (suggestions, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_update_database (gpointer db,
|
|
||||||
const gchar* key,
|
|
||||||
const gchar* value)
|
|
||||||
{
|
|
||||||
gchar* sqlcmd;
|
|
||||||
gchar* errmsg;
|
|
||||||
gint success;
|
|
||||||
|
|
||||||
sqlcmd = sqlite3_mprintf ("INSERT INTO forms VALUES"
|
|
||||||
"('%q', '%q', '%q')",
|
|
||||||
NULL, key, value);
|
|
||||||
success = sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg);
|
|
||||||
sqlite3_free (sqlcmd);
|
|
||||||
if (success != SQLITE_OK)
|
|
||||||
{
|
|
||||||
g_printerr (_("Failed to add form value: %s\n"), errmsg);
|
|
||||||
g_free (errmsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
formhistory_update_main_hash (gchar* key,
|
|
||||||
gchar* value)
|
|
||||||
{
|
|
||||||
guint length;
|
|
||||||
gchar* tmp;
|
|
||||||
|
|
||||||
if (!(value && *value))
|
|
||||||
return FALSE;
|
|
||||||
length = strlen (value);
|
|
||||||
if (length > MAXCHARS || length < MINCHARS)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
formhistory_fixup_value (key);
|
|
||||||
formhistory_fixup_value (value);
|
|
||||||
if ((tmp = g_hash_table_lookup (global_keys, (gpointer)key)))
|
|
||||||
{
|
|
||||||
gchar* rvalue = g_strdup_printf ("\"%s\"",value);
|
|
||||||
gchar* patt = g_regex_escape_string (rvalue, -1);
|
|
||||||
if (!g_regex_match_simple (patt, tmp,
|
|
||||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
|
||||||
{
|
|
||||||
gchar* new_value = g_strdup_printf ("%s%s,", tmp, rvalue);
|
|
||||||
g_hash_table_insert (global_keys, g_strdup (key), new_value);
|
|
||||||
g_free (rvalue);
|
|
||||||
g_free (patt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_free (rvalue);
|
|
||||||
g_free (patt);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gchar* new_value = g_strdup_printf ("\"%s\",",value);
|
|
||||||
g_hash_table_replace (global_keys, g_strdup (key), new_value);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
|
||||||
WebKitWebFrame* web_frame,
|
|
||||||
WebKitNetworkRequest* request,
|
|
||||||
WebKitWebNavigationAction* action,
|
|
||||||
WebKitWebPolicyDecision* decision,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
/* The script returns form data in the form "field_name|,|value|,|field_type".
|
|
||||||
We are handling only input fields with 'text' or 'password' type.
|
|
||||||
The field separator is "|||" */
|
|
||||||
const gchar* script = "function dumpForm (inputs) {"
|
|
||||||
" var out = '';"
|
|
||||||
" for (i=0;i<inputs.length;i++) {"
|
|
||||||
" if (inputs[i].getAttribute('autocomplete') == 'off')"
|
|
||||||
" continue;"
|
|
||||||
" if (inputs[i].value && (inputs[i].type == 'text' || inputs[i].type == 'password')) {"
|
|
||||||
" var ename = inputs[i].getAttribute('name');"
|
|
||||||
" var eid = inputs[i].getAttribute('id');"
|
|
||||||
" if (!ename && eid)"
|
|
||||||
" ename=eid;"
|
|
||||||
" if (inputs[i].getAttribute('autocomplete') != 'off')"
|
|
||||||
" out += ename+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
|
||||||
" }"
|
|
||||||
" }"
|
|
||||||
" return out;"
|
|
||||||
"}"
|
|
||||||
"dumpForm (document.getElementsByTagName('input'))";
|
|
||||||
|
|
||||||
if (webkit_web_navigation_action_get_reason (action) == WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
|
|
||||||
{
|
|
||||||
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
|
|
||||||
gchar* value = sokoke_js_script_eval (js_context, script, NULL);
|
|
||||||
if (value && *value)
|
|
||||||
{
|
|
||||||
gpointer db = g_object_get_data (G_OBJECT (extension), "formhistory-db");
|
|
||||||
gchar** inputs = g_strsplit (value, "|||", 0);
|
|
||||||
guint i = 0;
|
|
||||||
while (inputs[i] != NULL)
|
|
||||||
{
|
|
||||||
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
|
||||||
if (parts && parts[0] && parts[1] && parts[2])
|
|
||||||
{
|
|
||||||
/* FIXME: We need to handle passwords */
|
|
||||||
if (strcmp (parts[2], "password"))
|
|
||||||
{
|
|
||||||
if (formhistory_update_main_hash (parts[0], parts[1]))
|
|
||||||
formhistory_update_database (db, parts[0], parts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_strfreev (parts);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
g_strfreev (inputs);
|
|
||||||
g_free (value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_window_object_cleared_cb (WebKitWebView* web_view,
|
|
||||||
WebKitWebFrame* web_frame,
|
|
||||||
JSContextRef js_context,
|
|
||||||
JSObjectRef js_window)
|
|
||||||
{
|
|
||||||
gchar* script;
|
|
||||||
const gchar* page_uri;
|
|
||||||
|
|
||||||
page_uri = webkit_web_frame_get_uri (web_frame);
|
|
||||||
if (!midori_uri_is_http (page_uri))
|
|
||||||
return;
|
|
||||||
|
|
||||||
script = formhistory_build_js ();
|
|
||||||
sokoke_js_script_eval (js_context, script, NULL);
|
|
||||||
g_free (script);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_add_tab_cb (MidoriBrowser* browser,
|
|
||||||
MidoriView* view,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
|
||||||
g_signal_connect (web_view, "window-object-cleared",
|
|
||||||
G_CALLBACK (formhistory_window_object_cleared_cb), NULL);
|
|
||||||
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
|
||||||
G_CALLBACK (formhistory_navigation_decision_cb), extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
|
||||||
MidoriBrowser* browser);
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_add_tab_foreach_cb (MidoriView* view,
|
|
||||||
MidoriBrowser* browser,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
formhistory_add_tab_cb (browser, view, extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_app_add_browser_cb (MidoriApp* app,
|
|
||||||
MidoriBrowser* browser,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
GtkAccelGroup* acg = gtk_accel_group_new ();
|
|
||||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
|
||||||
GtkAction* action = gtk_action_new ("FormHistoryToggleState",
|
|
||||||
_("Toggle form history state"),
|
|
||||||
_("Activate or deactivate form history for the current tab."), NULL);
|
|
||||||
gtk_window_add_accel_group (GTK_WINDOW (browser), acg);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", extension);
|
|
||||||
|
|
||||||
g_signal_connect (action, "activate",
|
|
||||||
G_CALLBACK (formhistory_toggle_state_cb), browser);
|
|
||||||
|
|
||||||
gtk_action_group_add_action_with_accel (action_group, action, "<Ctrl><Shift>F");
|
|
||||||
gtk_action_set_accel_group (action, acg);
|
|
||||||
gtk_action_connect_accelerator (action);
|
|
||||||
|
|
||||||
if (midori_extension_get_boolean (extension, "always-load"))
|
|
||||||
{
|
|
||||||
midori_browser_foreach (browser,
|
|
||||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
|
||||||
g_signal_connect (browser, "add-tab",
|
|
||||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
|
||||||
}
|
|
||||||
g_signal_connect (extension, "deactivate",
|
|
||||||
G_CALLBACK (formhistory_deactivate_cb), browser);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_deactivate_tabs (MidoriView* view,
|
|
||||||
MidoriBrowser* browser,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
web_view, formhistory_window_object_cleared_cb, NULL);
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
web_view, formhistory_navigation_decision_cb, extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
|
||||||
MidoriBrowser* browser)
|
|
||||||
{
|
|
||||||
MidoriApp* app = midori_extension_get_app (extension);
|
|
||||||
sqlite3* db;
|
|
||||||
|
|
||||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
|
||||||
GtkAction* action;
|
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
browser, formhistory_add_tab_cb, extension);
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
extension, formhistory_deactivate_cb, browser);
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
app, formhistory_app_add_browser_cb, extension);
|
|
||||||
midori_browser_foreach (browser,
|
|
||||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", NULL);
|
|
||||||
action = gtk_action_group_get_action ( action_group, "FormHistoryToggleState");
|
|
||||||
if (action != NULL)
|
|
||||||
{
|
|
||||||
gtk_action_group_remove_action (action_group, action);
|
|
||||||
g_object_unref (action);
|
|
||||||
}
|
|
||||||
|
|
||||||
katze_assign (jsforms, NULL);
|
|
||||||
if (global_keys)
|
|
||||||
g_hash_table_destroy (global_keys);
|
|
||||||
|
|
||||||
if ((db = g_object_get_data (G_OBJECT (extension), "formhistory-db")))
|
|
||||||
sqlite3_close (db);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
formhistory_add_field (gpointer data,
|
|
||||||
int argc,
|
|
||||||
char** argv,
|
|
||||||
char** colname)
|
|
||||||
{
|
|
||||||
gint i;
|
|
||||||
gint ncols = 3;
|
|
||||||
|
|
||||||
/* Test whether have the right number of columns */
|
|
||||||
g_return_val_if_fail (argc % ncols == 0, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < (argc - ncols) + 1; i++)
|
|
||||||
{
|
|
||||||
if (argv[i])
|
|
||||||
{
|
|
||||||
if (colname[i] && !g_ascii_strcasecmp (colname[i], "domain")
|
|
||||||
&& colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "field")
|
|
||||||
&& colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "value"))
|
|
||||||
{
|
|
||||||
gchar* key = argv[i + 1];
|
|
||||||
formhistory_update_main_hash (g_strdup (key), g_strdup (argv[i + 2]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_activate_cb (MidoriExtension* extension,
|
|
||||||
MidoriApp* app)
|
|
||||||
{
|
|
||||||
const gchar* config_dir;
|
|
||||||
gchar* filename;
|
|
||||||
sqlite3* db;
|
|
||||||
char* errmsg = NULL, *errmsg2 = NULL;
|
|
||||||
KatzeArray* browsers;
|
|
||||||
MidoriBrowser* browser;
|
|
||||||
|
|
||||||
global_keys = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
(GDestroyNotify)g_free,
|
|
||||||
(GDestroyNotify)g_free);
|
|
||||||
if(!jsforms)
|
|
||||||
formhistory_prepare_js ();
|
|
||||||
config_dir = midori_extension_get_config_dir (extension);
|
|
||||||
katze_mkdir_with_parents (config_dir, 0700);
|
|
||||||
filename = g_build_filename (config_dir, "forms.db", NULL);
|
|
||||||
if (sqlite3_open (filename, &db) != SQLITE_OK)
|
|
||||||
{
|
|
||||||
/* If the folder is /, this is a test run, thus no error */
|
|
||||||
if (!g_str_equal (midori_extension_get_config_dir (extension), "/"))
|
|
||||||
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
|
|
||||||
sqlite3_close (db);
|
|
||||||
}
|
|
||||||
g_free (filename);
|
|
||||||
if ((sqlite3_exec (db, "CREATE TABLE IF NOT EXISTS "
|
|
||||||
"forms (domain text, field text, value text)",
|
|
||||||
NULL, NULL, &errmsg) == SQLITE_OK)
|
|
||||||
&& (sqlite3_exec (db, "SELECT domain, field, value FROM forms ",
|
|
||||||
formhistory_add_field,
|
|
||||||
NULL, &errmsg2) == SQLITE_OK))
|
|
||||||
g_object_set_data (G_OBJECT (extension), "formhistory-db", db);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (errmsg)
|
|
||||||
{
|
|
||||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg);
|
|
||||||
sqlite3_free (errmsg);
|
|
||||||
if (errmsg2)
|
|
||||||
{
|
|
||||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg2);
|
|
||||||
sqlite3_free (errmsg2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sqlite3_close (db);
|
|
||||||
}
|
|
||||||
|
|
||||||
browsers = katze_object_get_object (app, "browsers");
|
|
||||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
|
||||||
formhistory_app_add_browser_cb (app, browser, extension);
|
|
||||||
g_signal_connect (app, "add-browser",
|
|
||||||
G_CALLBACK (formhistory_app_add_browser_cb), extension);
|
|
||||||
|
|
||||||
g_object_unref (browsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_preferences_response_cb (GtkWidget* dialog,
|
|
||||||
gint response_id,
|
|
||||||
MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
GtkWidget* checkbox;
|
|
||||||
gboolean old_state;
|
|
||||||
gboolean new_state;
|
|
||||||
MidoriApp* app;
|
|
||||||
KatzeArray* browsers;
|
|
||||||
MidoriBrowser* browser;
|
|
||||||
|
|
||||||
if (response_id == GTK_RESPONSE_APPLY)
|
|
||||||
{
|
|
||||||
checkbox = g_object_get_data (G_OBJECT (dialog), "always-load-checkbox");
|
|
||||||
new_state = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
|
|
||||||
old_state = midori_extension_get_boolean (extension, "always-load");
|
|
||||||
|
|
||||||
if (old_state != new_state)
|
|
||||||
{
|
|
||||||
midori_extension_set_boolean (extension, "always-load", new_state);
|
|
||||||
|
|
||||||
app = midori_extension_get_app (extension);
|
|
||||||
browsers = katze_object_get_object (app, "browsers");
|
|
||||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
|
||||||
{
|
|
||||||
midori_browser_foreach (browser,
|
|
||||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
|
||||||
g_signal_handlers_disconnect_by_func (
|
|
||||||
browser, formhistory_add_tab_cb, extension);
|
|
||||||
|
|
||||||
if (new_state)
|
|
||||||
{
|
|
||||||
midori_browser_foreach (browser,
|
|
||||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
|
||||||
g_signal_connect (browser, "add-tab",
|
|
||||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_preferences_cb (MidoriExtension* extension)
|
|
||||||
{
|
|
||||||
GtkWidget* dialog;
|
|
||||||
GtkWidget* content_area;
|
|
||||||
GtkWidget* checkbox;
|
|
||||||
|
|
||||||
dialog = gtk_dialog_new ();
|
|
||||||
|
|
||||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
|
||||||
|
|
||||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
|
||||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY);
|
|
||||||
|
|
||||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
|
||||||
checkbox = gtk_check_button_new_with_label (_("only activate form history via hotkey (Ctrl+Shift+F) per tab"));
|
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox),
|
|
||||||
!midori_extension_get_boolean (extension, "always-load"));
|
|
||||||
g_object_set_data (G_OBJECT (dialog), "always-load-checkbox", checkbox);
|
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), checkbox);
|
|
||||||
|
|
||||||
g_signal_connect (dialog,
|
|
||||||
"response",
|
|
||||||
G_CALLBACK (formhistory_preferences_response_cb),
|
|
||||||
extension);
|
|
||||||
gtk_widget_show_all (dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
formhistory_toggle_state_cb (GtkAction* action,
|
|
||||||
MidoriBrowser* browser)
|
|
||||||
{
|
|
||||||
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
|
||||||
MidoriExtension* extension = g_object_get_data (G_OBJECT (browser), "FormHistoryExtension");
|
|
||||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
|
||||||
|
|
||||||
if (g_signal_handler_find (web_view, G_SIGNAL_MATCH_FUNC,
|
|
||||||
g_signal_lookup ("window-object-cleared", MIDORI_TYPE_VIEW), 0, NULL,
|
|
||||||
formhistory_window_object_cleared_cb, extension))
|
|
||||||
{
|
|
||||||
formhistory_deactivate_tabs (view, browser, extension);
|
|
||||||
} else {
|
|
||||||
formhistory_add_tab_cb (browser, view, extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if G_ENABLE_DEBUG
|
|
||||||
/*
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>autosuggest testcase</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<form method=post>
|
|
||||||
<p><input type="text" id="txt1" /></p>
|
|
||||||
<p><input type="text" name="txt2" /></p>
|
|
||||||
<input type=submit>
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html> */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MidoriExtension*
|
|
||||||
extension_init (void)
|
|
||||||
{
|
|
||||||
gboolean should_init = TRUE;
|
|
||||||
const gchar* ver;
|
|
||||||
gchar* desc;
|
|
||||||
MidoriExtension* extension;
|
|
||||||
|
|
||||||
if (formhistory_prepare_js ())
|
|
||||||
{
|
|
||||||
ver = "1.0" MIDORI_VERSION_SUFFIX;
|
|
||||||
desc = g_strdup (_("Stores history of entered form data"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desc = g_strdup_printf (_("Not available: %s"),
|
|
||||||
_("Resource files not installed"));
|
|
||||||
ver = NULL;
|
|
||||||
should_init = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
|
||||||
"name", _("Form history filler"),
|
|
||||||
"description", desc,
|
|
||||||
"version", ver,
|
|
||||||
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_free (desc);
|
|
||||||
|
|
||||||
if (should_init)
|
|
||||||
{
|
|
||||||
midori_extension_install_boolean (extension, "always-load", TRUE);
|
|
||||||
g_signal_connect (extension, "activate",
|
|
||||||
G_CALLBACK (formhistory_activate_cb), NULL);
|
|
||||||
g_signal_connect (extension, "open-preferences",
|
|
||||||
G_CALLBACK (formhistory_preferences_cb), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return extension;
|
|
||||||
}
|
|
74
extensions/formhistory/formhistory-frontend.h
Normal file
74
extensions/formhistory/formhistory-frontend.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||||
|
Copyright (C) 2009-2012 Christian Dywan <christian@twotoasts.de>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FORMHISTORY_FRONTEND_H__
|
||||||
|
#define __FORMHISTORY_FRONTEND_H__
|
||||||
|
#include <midori/midori.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 1)
|
||||||
|
#define FORMHISTORY_USE_GDOM 1
|
||||||
|
#else
|
||||||
|
#define FORMHISTORY_USE_JS 1
|
||||||
|
#endif
|
||||||
|
#define MAXPASSSIZE 64
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
sqlite3* db;
|
||||||
|
#ifdef FORMHISTORY_USE_GDOM
|
||||||
|
WebKitDOMElement* element;
|
||||||
|
int completion_timeout;
|
||||||
|
GtkTreeModel* completion_model;
|
||||||
|
GtkWidget* treeview;
|
||||||
|
GtkWidget* popup;
|
||||||
|
gchar* oldkeyword;
|
||||||
|
glong selection_index;
|
||||||
|
#else
|
||||||
|
gchar* jsforms;
|
||||||
|
#endif
|
||||||
|
gchar* master_password;
|
||||||
|
int master_password_canceled;
|
||||||
|
} FormHistoryPriv;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gchar* domain;
|
||||||
|
gchar* form_data;
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
} FormhistoryPasswordEntry;
|
||||||
|
|
||||||
|
FormHistoryPriv*
|
||||||
|
formhistory_private_new ();
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_private_destroy (FormHistoryPriv *priv);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
formhistory_construct_popup_gui (FormHistoryPriv* priv);
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||||
|
JSContextRef js_context,
|
||||||
|
MidoriExtension* extension);
|
||||||
|
|
||||||
|
#ifdef FORMHISTORY_USE_GDOM
|
||||||
|
void
|
||||||
|
formhistory_suggestions_hide_cb (WebKitDOMElement* element,
|
||||||
|
WebKitDOMEvent* dom_event,
|
||||||
|
FormHistoryPriv* priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
516
extensions/formhistory/formhistory-gdom-frontend.c
Normal file
516
extensions/formhistory/formhistory-gdom-frontend.c
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||||
|
Copyright (C) 2009-2012 Christian Dywan <christian@twotoasts.de>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include "formhistory-frontend.h"
|
||||||
|
#ifdef FORMHISTORY_USE_GDOM
|
||||||
|
#define COMPLETION_DELAY 200
|
||||||
|
|
||||||
|
FormHistoryPriv*
|
||||||
|
formhistory_private_new ()
|
||||||
|
{
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
|
||||||
|
priv = g_slice_new (FormHistoryPriv);
|
||||||
|
priv->oldkeyword = g_strdup ("");
|
||||||
|
priv->selection_index = -1;
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_suggestions_hide_cb (WebKitDOMElement* element,
|
||||||
|
WebKitDOMEvent* dom_event,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
if (gtk_widget_get_visible (priv->popup))
|
||||||
|
gtk_widget_hide (priv->popup);
|
||||||
|
priv->selection_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_suggestion_set (GtkTreePath* path,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar* value;
|
||||||
|
|
||||||
|
if (!gtk_tree_model_get_iter (priv->completion_model, &iter, path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_tree_model_get (priv->completion_model, &iter, 0, &value, -1);
|
||||||
|
g_object_set (priv->element, "value", value, NULL);
|
||||||
|
g_free (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
formhistory_suggestion_selected_cb (GtkWidget* treeview,
|
||||||
|
GdkEventButton* event,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
|
||||||
|
{
|
||||||
|
GtkTreePath* path;
|
||||||
|
|
||||||
|
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
|
||||||
|
event->x, event->y, &path, NULL, NULL, NULL))
|
||||||
|
{
|
||||||
|
formhistory_suggestion_set (path, priv);
|
||||||
|
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||||
|
gtk_tree_path_free (path);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
formhistory_suggestion_remove (GtkTreePath* path,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar* sqlcmd;
|
||||||
|
char* errmsg = NULL;
|
||||||
|
gchar* name;
|
||||||
|
gchar* value;
|
||||||
|
|
||||||
|
if (!gtk_tree_model_get_iter (priv->completion_model, &iter, path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!priv->db)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_tree_model_get (priv->completion_model, &iter, 0, &value, -1);
|
||||||
|
g_object_get (priv->element, "name", &name, NULL);
|
||||||
|
gtk_list_store_remove (GTK_LIST_STORE (priv->completion_model), &iter);
|
||||||
|
|
||||||
|
sqlcmd = sqlite3_mprintf ("DELETE FROM forms WHERE field = '%q' AND value = '%q'",
|
||||||
|
name, value);
|
||||||
|
g_free (name);
|
||||||
|
g_free (value);
|
||||||
|
sqlite3_exec (priv->db, sqlcmd, NULL, NULL, &errmsg);
|
||||||
|
sqlite3_free (sqlcmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_absolute_offset_for_element (WebKitDOMElement* element,
|
||||||
|
WebKitDOMDocument* element_document,
|
||||||
|
WebKitDOMNodeList* frames,
|
||||||
|
glong* x,
|
||||||
|
glong* y,
|
||||||
|
gboolean ismainframe)
|
||||||
|
{
|
||||||
|
WebKitDOMElement* offset_parent;
|
||||||
|
gint offset_top = 0, offset_left = 0;
|
||||||
|
gulong i;
|
||||||
|
|
||||||
|
g_object_get (element, "offset-left", &offset_left,
|
||||||
|
"offset-top", &offset_top,
|
||||||
|
"offset-parent", &offset_parent,
|
||||||
|
NULL);
|
||||||
|
*x += offset_left;
|
||||||
|
*y += offset_top;
|
||||||
|
/* To avoid deadlock check only first element of the mainframe parent */
|
||||||
|
if (ismainframe == TRUE)
|
||||||
|
return;
|
||||||
|
if (offset_parent)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
/* Element havent returned any parents. Thats mean or there is no parents or we are inside the frame
|
||||||
|
Loop over all frames we have to find frame == element_document which is a root for our element
|
||||||
|
and get its offsets */
|
||||||
|
for (i = 0; i < webkit_dom_node_list_get_length (frames); i++)
|
||||||
|
{
|
||||||
|
WebKitDOMDocument *fdoc;
|
||||||
|
WebKitDOMNode *frame = webkit_dom_node_list_item (frames, i);
|
||||||
|
|
||||||
|
if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (frame))
|
||||||
|
fdoc = webkit_dom_html_iframe_element_get_content_document (WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame));
|
||||||
|
else
|
||||||
|
fdoc = webkit_dom_html_frame_element_get_content_document (WEBKIT_DOM_HTML_FRAME_ELEMENT (frame));
|
||||||
|
if (fdoc == element_document)
|
||||||
|
{
|
||||||
|
offset_parent = WEBKIT_DOM_ELEMENT (frame);
|
||||||
|
ismainframe = TRUE;
|
||||||
|
/* Add extra 4px to ~cover size of borders */
|
||||||
|
*y += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finish:
|
||||||
|
if (offset_parent)
|
||||||
|
get_absolute_offset_for_element (offset_parent, element_document, frames, x, y, ismainframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_reposition_popup (FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
WebKitDOMDocument* element_document;
|
||||||
|
WebKitDOMNodeList* frames;
|
||||||
|
GtkWidget* view;
|
||||||
|
GdkWindow* window;
|
||||||
|
GtkWidget* toplevel;
|
||||||
|
gint rx, ry;
|
||||||
|
gint wx, wy;
|
||||||
|
glong x = 0, y = 0;
|
||||||
|
glong height;
|
||||||
|
|
||||||
|
view = g_object_get_data (G_OBJECT (priv->element), "webview");
|
||||||
|
toplevel = gtk_widget_get_toplevel (view);
|
||||||
|
/* Position of a root window */
|
||||||
|
window = gtk_widget_get_window (toplevel);
|
||||||
|
gdk_window_get_position (window, &rx, &ry);
|
||||||
|
|
||||||
|
/* Postion of webview in root window */
|
||||||
|
window = gtk_widget_get_window (view);
|
||||||
|
gdk_window_get_position (window, &wx, &wy);
|
||||||
|
|
||||||
|
/* Position of editbox on the webview */
|
||||||
|
frames = g_object_get_data (G_OBJECT (priv->element), "framelist");
|
||||||
|
element_document = g_object_get_data (G_OBJECT (priv->element), "doc");
|
||||||
|
get_absolute_offset_for_element (priv->element, element_document, frames, &x, &y, FALSE);
|
||||||
|
/* Add height as menu should start under editbox, now on top of it */
|
||||||
|
g_object_get (priv->element, "client-height", &height, NULL);
|
||||||
|
y += height + 1;
|
||||||
|
gtk_window_move (GTK_WINDOW (priv->popup), rx + wx + x, ry +wy + y);
|
||||||
|
|
||||||
|
/* Window configuration */
|
||||||
|
gtk_window_set_screen (GTK_WINDOW (priv->popup), gtk_widget_get_screen (view));
|
||||||
|
gtk_window_set_transient_for (GTK_WINDOW (priv->popup), GTK_WINDOW (toplevel));
|
||||||
|
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (priv->treeview));
|
||||||
|
/* FIXME: Adjust size according to treeview width and some reasonable height */
|
||||||
|
gtk_window_resize (GTK_WINDOW (priv->popup), 50, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
formhistory_suggestions_show (FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
GtkListStore* store;
|
||||||
|
static sqlite3_stmt* stmt;
|
||||||
|
gchar* value, * name;
|
||||||
|
const char* sqlcmd;
|
||||||
|
gint result;
|
||||||
|
gchar* likedvalue;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv->element, FALSE);
|
||||||
|
|
||||||
|
g_object_get (priv->element,
|
||||||
|
"name", &name,
|
||||||
|
"value", &value,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
katze_assign (priv->oldkeyword, g_strdup (value));
|
||||||
|
if (!priv->popup)
|
||||||
|
formhistory_construct_popup_gui (priv);
|
||||||
|
|
||||||
|
if (!stmt)
|
||||||
|
{
|
||||||
|
if (!priv->db)
|
||||||
|
goto free_data;
|
||||||
|
|
||||||
|
sqlcmd = "SELECT DISTINCT value FROM forms WHERE field = ?1 and value like ?2";
|
||||||
|
sqlite3_prepare_v2 (priv->db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
likedvalue = g_strdup_printf ("%s%%", value);
|
||||||
|
sqlite3_bind_text (stmt, 1, name, -1, NULL);
|
||||||
|
sqlite3_bind_text (stmt, 2, likedvalue, -1, g_free);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
|
||||||
|
if (result != SQLITE_ROW)
|
||||||
|
{
|
||||||
|
if (result == SQLITE_ERROR)
|
||||||
|
g_print (_("Failed to select suggestions\n"));
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
sqlite3_clear_bindings (stmt);
|
||||||
|
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||||
|
goto free_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
store = GTK_LIST_STORE (priv->completion_model);
|
||||||
|
gtk_list_store_clear (store);
|
||||||
|
|
||||||
|
while (result == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
const unsigned char* text = sqlite3_column_text (stmt, 0);
|
||||||
|
pos++;
|
||||||
|
gtk_list_store_insert_with_values (store, NULL, pos, 0, text, -1);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
}
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
sqlite3_clear_bindings (stmt);
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (priv->popup))
|
||||||
|
{
|
||||||
|
formhistory_reposition_popup (priv);
|
||||||
|
gtk_widget_show_all (priv->popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_data:
|
||||||
|
g_free (name);
|
||||||
|
g_free (value);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_editbox_key_pressed_cb (WebKitDOMElement* element,
|
||||||
|
WebKitDOMEvent* dom_event,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
glong key;
|
||||||
|
GtkTreePath* path;
|
||||||
|
gchar* keyword;
|
||||||
|
gint matches;
|
||||||
|
|
||||||
|
/* FIXME: Priv is still set after module is disabled */
|
||||||
|
g_return_if_fail (priv);
|
||||||
|
g_return_if_fail (element);
|
||||||
|
|
||||||
|
if (priv->completion_timeout > 0)
|
||||||
|
g_source_remove (priv->completion_timeout);
|
||||||
|
|
||||||
|
katze_object_assign (priv->element, g_object_ref (element));
|
||||||
|
|
||||||
|
key = webkit_dom_ui_event_get_key_code (WEBKIT_DOM_UI_EVENT (dom_event));
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
/* ESC key*/
|
||||||
|
case 27:
|
||||||
|
case 35:
|
||||||
|
case 36:
|
||||||
|
/* Left key*/
|
||||||
|
case 37:
|
||||||
|
/* Right key*/
|
||||||
|
case 39:
|
||||||
|
/* Enter key*/
|
||||||
|
case 13:
|
||||||
|
if (key == 27)
|
||||||
|
g_object_set (element, "value", priv->oldkeyword, NULL);
|
||||||
|
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
/* Del key */
|
||||||
|
case 46:
|
||||||
|
/* Up key */
|
||||||
|
case 38:
|
||||||
|
/* Down key */
|
||||||
|
case 40:
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (priv->popup))
|
||||||
|
{
|
||||||
|
formhistory_suggestions_show (priv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
matches = gtk_tree_model_iter_n_children (priv->completion_model, NULL);
|
||||||
|
if (key == 38)
|
||||||
|
{
|
||||||
|
if (priv->selection_index <= 0)
|
||||||
|
priv->selection_index = matches - 1;
|
||||||
|
else
|
||||||
|
priv->selection_index = MAX (priv->selection_index - 1, 0);
|
||||||
|
}
|
||||||
|
else if (key == 40)
|
||||||
|
{
|
||||||
|
if (priv->selection_index == matches - 1)
|
||||||
|
priv->selection_index = 0;
|
||||||
|
else
|
||||||
|
priv->selection_index = MIN (priv->selection_index + 1, matches -1);
|
||||||
|
}
|
||||||
|
if (priv->selection_index == -1)
|
||||||
|
{
|
||||||
|
/* No element is selected */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = gtk_tree_path_new_from_indices (priv->selection_index, -1);
|
||||||
|
if (key == 46)
|
||||||
|
{
|
||||||
|
g_object_set (element, "value", priv->oldkeyword, NULL);
|
||||||
|
formhistory_suggestion_remove (path, priv);
|
||||||
|
matches--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches == 0)
|
||||||
|
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path, NULL, FALSE);
|
||||||
|
formhistory_suggestion_set (path, priv);
|
||||||
|
}
|
||||||
|
gtk_tree_path_free (path);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
/* PgUp, PgDn, Ins */
|
||||||
|
case 33:
|
||||||
|
case 34:
|
||||||
|
case 45:
|
||||||
|
/* Shift, Ctrl, Alt, Tab, Caps Lock*/
|
||||||
|
case 16:
|
||||||
|
case 17:
|
||||||
|
case 18:
|
||||||
|
case 20:
|
||||||
|
case 9:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (element, "value", &keyword, NULL);
|
||||||
|
if (!(keyword && *keyword && *keyword != ' '))
|
||||||
|
{
|
||||||
|
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||||
|
goto free_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the same keyword is submitted there's no need to regenerate suggestions */
|
||||||
|
if (gtk_widget_get_visible (priv->popup) &&
|
||||||
|
!g_strcmp0 (keyword, priv->oldkeyword))
|
||||||
|
goto free_data;
|
||||||
|
priv->completion_timeout = g_timeout_add (COMPLETION_DELAY,
|
||||||
|
(GSourceFunc)formhistory_suggestions_show, priv);
|
||||||
|
free_data:
|
||||||
|
g_free (keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_DOMContentLoaded_cb (WebKitDOMElement* window,
|
||||||
|
WebKitDOMEvent* dom_event,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
gulong i;
|
||||||
|
WebKitDOMDocument* doc;
|
||||||
|
WebKitDOMNodeList* inputs;
|
||||||
|
WebKitDOMNodeList* frames;
|
||||||
|
GtkWidget* web_view;
|
||||||
|
|
||||||
|
if (WEBKIT_DOM_IS_DOCUMENT (window))
|
||||||
|
doc = WEBKIT_DOM_DOCUMENT (window);
|
||||||
|
else
|
||||||
|
doc = webkit_dom_dom_window_get_document (WEBKIT_DOM_DOM_WINDOW (window));
|
||||||
|
inputs = webkit_dom_document_query_selector_all (doc, "input[type='text']", NULL);
|
||||||
|
frames = g_object_get_data (G_OBJECT (window), "framelist");
|
||||||
|
web_view = g_object_get_data (G_OBJECT (window), "webview");
|
||||||
|
|
||||||
|
for (i = 0; i < webkit_dom_node_list_get_length (inputs); i++)
|
||||||
|
{
|
||||||
|
WebKitDOMNode* element = webkit_dom_node_list_item (inputs, i);
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 6, 1)
|
||||||
|
gchar* autocomplete = webkit_dom_html_input_element_get_autocomplete (
|
||||||
|
WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
|
||||||
|
gboolean off = !g_strcmp0 (autocomplete, "off");
|
||||||
|
g_free (autocomplete);
|
||||||
|
if (off)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (element), "doc", doc);
|
||||||
|
g_object_set_data (G_OBJECT (element), "webview", web_view);
|
||||||
|
g_object_set_data (G_OBJECT (element), "framelist", frames);
|
||||||
|
/* Add dblclick? */
|
||||||
|
webkit_dom_event_target_add_event_listener (
|
||||||
|
WEBKIT_DOM_EVENT_TARGET (element), "keyup",
|
||||||
|
G_CALLBACK (formhistory_editbox_key_pressed_cb), false,
|
||||||
|
priv);
|
||||||
|
webkit_dom_event_target_add_event_listener (
|
||||||
|
WEBKIT_DOM_EVENT_TARGET (element), "blur",
|
||||||
|
G_CALLBACK (formhistory_suggestions_hide_cb), false,
|
||||||
|
priv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||||
|
JSContextRef js_context,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
WebKitDOMDocument* doc;
|
||||||
|
WebKitDOMNodeList* frames;
|
||||||
|
gulong i;
|
||||||
|
|
||||||
|
FormHistoryPriv* priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||||
|
doc = webkit_web_view_get_dom_document (web_view);
|
||||||
|
frames = webkit_dom_document_query_selector_all (doc, "iframe, frame", NULL);
|
||||||
|
g_object_set_data (G_OBJECT (doc), "framelist", frames);
|
||||||
|
g_object_set_data (G_OBJECT (doc), "webview", web_view);
|
||||||
|
/* Connect to DOMContentLoaded of the main frame */
|
||||||
|
webkit_dom_event_target_add_event_listener(
|
||||||
|
WEBKIT_DOM_EVENT_TARGET (doc), "DOMContentLoaded",
|
||||||
|
G_CALLBACK (formhistory_DOMContentLoaded_cb), false,
|
||||||
|
priv);
|
||||||
|
|
||||||
|
/* Connect to DOMContentLoaded of frames */
|
||||||
|
for (i = 0; i < webkit_dom_node_list_get_length (frames); i++)
|
||||||
|
{
|
||||||
|
WebKitDOMDOMWindow* framewin;
|
||||||
|
|
||||||
|
WebKitDOMNode* frame = webkit_dom_node_list_item (frames, i);
|
||||||
|
if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (frame))
|
||||||
|
framewin = webkit_dom_html_iframe_element_get_content_window (WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame));
|
||||||
|
else
|
||||||
|
framewin = webkit_dom_html_frame_element_get_content_window (WEBKIT_DOM_HTML_FRAME_ELEMENT (frame));
|
||||||
|
g_object_set_data (G_OBJECT (framewin), "framelist", frames);
|
||||||
|
g_object_set_data (G_OBJECT (framewin), "webview", (GtkWidget*)web_view);
|
||||||
|
webkit_dom_event_target_add_event_listener (
|
||||||
|
WEBKIT_DOM_EVENT_TARGET (framewin), "DOMContentLoaded",
|
||||||
|
G_CALLBACK (formhistory_DOMContentLoaded_cb), false,
|
||||||
|
priv);
|
||||||
|
}
|
||||||
|
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_private_destroy (FormHistoryPriv *priv)
|
||||||
|
{
|
||||||
|
if (priv->db)
|
||||||
|
{
|
||||||
|
sqlite3_close (priv->db);
|
||||||
|
priv->db = NULL;
|
||||||
|
}
|
||||||
|
katze_assign (priv->oldkeyword, NULL);
|
||||||
|
gtk_widget_destroy (priv->popup);
|
||||||
|
priv->popup = NULL;
|
||||||
|
katze_object_assign (priv->element, NULL);
|
||||||
|
g_slice_free (FormHistoryPriv, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
formhistory_construct_popup_gui (FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
GtkTreeModel* model = NULL;
|
||||||
|
GtkWidget* popup;
|
||||||
|
GtkWidget* popup_frame;
|
||||||
|
GtkWidget* scrolled;
|
||||||
|
GtkWidget* treeview;
|
||||||
|
GtkCellRenderer* renderer;
|
||||||
|
GtkTreeViewColumn* column;
|
||||||
|
|
||||||
|
model = (GtkTreeModel*) gtk_list_store_new (1, G_TYPE_STRING);
|
||||||
|
priv->completion_model = model;
|
||||||
|
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||||
|
gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
|
||||||
|
popup_frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (popup_frame), GTK_SHADOW_ETCHED_IN);
|
||||||
|
gtk_container_add (GTK_CONTAINER (popup), popup_frame);
|
||||||
|
scrolled = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
|
||||||
|
"hscrollbar-policy", GTK_POLICY_NEVER,
|
||||||
|
"vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (popup_frame), scrolled);
|
||||||
|
treeview = gtk_tree_view_new_with_model (model);
|
||||||
|
priv->treeview = treeview;
|
||||||
|
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
||||||
|
gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (treeview), TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (scrolled), treeview);
|
||||||
|
gtk_widget_set_size_request (gtk_scrolled_window_get_vscrollbar (
|
||||||
|
GTK_SCROLLED_WINDOW (scrolled)), -1, 0);
|
||||||
|
|
||||||
|
renderer = gtk_cell_renderer_text_new ();
|
||||||
|
column = gtk_tree_view_column_new_with_attributes ("suggestions", renderer, "text", 0, NULL);
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||||
|
priv->popup = popup;
|
||||||
|
|
||||||
|
g_signal_connect (treeview, "button-press-event",
|
||||||
|
G_CALLBACK (formhistory_suggestion_selected_cb), priv);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
143
extensions/formhistory/formhistory-js-frontend.c
Normal file
143
extensions/formhistory/formhistory-js-frontend.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||||
|
Copyright (C) 2009-2012 Christian Dywan <christian@twotoasts.de>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include "formhistory-frontend.h"
|
||||||
|
#ifdef FORMHISTORY_USE_JS
|
||||||
|
|
||||||
|
FormHistoryPriv*
|
||||||
|
formhistory_private_new ()
|
||||||
|
{
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
|
||||||
|
priv = g_slice_new (FormHistoryPriv);
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
formhistory_construct_popup_gui (FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
gchar* autosuggest;
|
||||||
|
gchar* style;
|
||||||
|
guint i;
|
||||||
|
gchar* file;
|
||||||
|
|
||||||
|
file = sokoke_find_data_filename ("autosuggestcontrol.js", TRUE);
|
||||||
|
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
|
||||||
|
{
|
||||||
|
g_free (file);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_strchomp (autosuggest);
|
||||||
|
|
||||||
|
katze_assign (file, sokoke_find_data_filename ("autosuggestcontrol.css", TRUE));
|
||||||
|
if (!g_file_get_contents (file, &style, NULL, NULL))
|
||||||
|
{
|
||||||
|
g_free (file);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_strchomp (style);
|
||||||
|
g_free (file);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (style[i])
|
||||||
|
{
|
||||||
|
if (style[i] == '\n')
|
||||||
|
style[i] = ' ';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->jsforms = g_strdup_printf (
|
||||||
|
"%s"
|
||||||
|
"window.addEventListener ('DOMContentLoaded',"
|
||||||
|
"function () {"
|
||||||
|
" if (document.getElementById('formhistory'))"
|
||||||
|
" return;"
|
||||||
|
" if (!initSuggestions ())"
|
||||||
|
" return;"
|
||||||
|
" var mystyle = document.createElement('style');"
|
||||||
|
" mystyle.setAttribute('type', 'text/css');"
|
||||||
|
" mystyle.setAttribute('id', 'formhistory');"
|
||||||
|
" mystyle.appendChild(document.createTextNode('%s'));"
|
||||||
|
" var head = document.getElementsByTagName('head')[0];"
|
||||||
|
" if (head) head.appendChild(mystyle);"
|
||||||
|
"}, true);",
|
||||||
|
autosuggest,
|
||||||
|
style);
|
||||||
|
g_strstrip (priv->jsforms);
|
||||||
|
g_free (style);
|
||||||
|
g_free (autosuggest);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||||
|
JSContextRef js_context,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
GString* suggestions;
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
static sqlite3_stmt* stmt;
|
||||||
|
const char* sqlcmd;
|
||||||
|
const unsigned char* key;
|
||||||
|
const unsigned char* value;
|
||||||
|
|
||||||
|
gint result, pos;
|
||||||
|
|
||||||
|
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||||
|
if (!priv->db)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!stmt)
|
||||||
|
{
|
||||||
|
sqlcmd = "SELECT DISTINCT group_concat(value,'\",\"'), field FROM forms \
|
||||||
|
GROUP BY field ORDER BY field";
|
||||||
|
sqlite3_prepare_v2 (priv->db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||||
|
}
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
if (result != SQLITE_ROW)
|
||||||
|
{
|
||||||
|
if (result == SQLITE_ERROR)
|
||||||
|
g_print (_("Failed to select suggestions\n"));
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
suggestions = g_string_new (
|
||||||
|
"function FormSuggestions(eid) { "
|
||||||
|
"arr = new Array();");
|
||||||
|
|
||||||
|
while (result == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
value = sqlite3_column_text (stmt, 0);
|
||||||
|
key = sqlite3_column_text (stmt, 1);
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
g_string_append_printf (suggestions, " arr[\"%s\"] = [\"%s\"]; ",
|
||||||
|
(gchar*)key, (gchar*)value);
|
||||||
|
}
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
}
|
||||||
|
g_string_append (suggestions, "this.suggestions = arr[eid]; }");
|
||||||
|
g_string_append (suggestions, priv->jsforms);
|
||||||
|
sokoke_js_script_eval (js_context, suggestions->str, NULL);
|
||||||
|
g_string_free (suggestions, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
formhistory_private_destroy (FormHistoryPriv *priv)
|
||||||
|
{
|
||||||
|
if (priv->db)
|
||||||
|
{
|
||||||
|
sqlite3_close (priv->db);
|
||||||
|
priv->db = NULL;
|
||||||
|
}
|
||||||
|
katze_assign (priv->jsforms, NULL);
|
||||||
|
g_slice_free (FormHistoryPriv, priv);
|
||||||
|
}
|
||||||
|
#endif
|
679
extensions/formhistory/formhistory.c
Normal file
679
extensions/formhistory/formhistory.c
Normal file
|
@ -0,0 +1,679 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||||
|
Copyright (C) 2009-2012 Christian Dywan <christian@twotoasts.de>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#define MAXCHARS 60
|
||||||
|
#define MINCHARS 2
|
||||||
|
#define GTK_RESPONSE_IGNORE 99
|
||||||
|
#include "formhistory-frontend.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_toggle_state_cb (GtkAction* action,
|
||||||
|
MidoriBrowser* browser);
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_update_database (gpointer db,
|
||||||
|
const gchar* host,
|
||||||
|
const gchar* key,
|
||||||
|
const gchar* value)
|
||||||
|
{
|
||||||
|
gchar* sqlcmd;
|
||||||
|
gchar* errmsg;
|
||||||
|
gint success;
|
||||||
|
|
||||||
|
if (!(value && *value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sqlcmd = sqlite3_mprintf ("INSERT INTO forms VALUES"
|
||||||
|
"('%q', '%q', '%q')",
|
||||||
|
host, key, value);
|
||||||
|
success = sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg);
|
||||||
|
sqlite3_free (sqlcmd);
|
||||||
|
if (success != SQLITE_OK)
|
||||||
|
{
|
||||||
|
g_printerr (_("Failed to add form value: %s\n"), errmsg);
|
||||||
|
g_free (errmsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
formhistory_get_login_data (gpointer db,
|
||||||
|
const gchar* domain)
|
||||||
|
{
|
||||||
|
static sqlite3_stmt* stmt;
|
||||||
|
const char* sqlcmd;
|
||||||
|
gint result;
|
||||||
|
gchar* value = NULL;
|
||||||
|
|
||||||
|
if (!stmt)
|
||||||
|
{
|
||||||
|
sqlcmd = "SELECT value FROM forms WHERE domain = ?1 and field = 'MidoriPasswordManager' limit 1";
|
||||||
|
sqlite3_prepare_v2 (db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||||
|
}
|
||||||
|
sqlite3_bind_text (stmt, 1, domain, -1, NULL);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
if (result == SQLITE_ROW)
|
||||||
|
value = g_strdup ((gchar*)sqlite3_column_text (stmt, 0));
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
sqlite3_clear_bindings (stmt);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
formhistory_check_master_password (GtkWidget* parent,
|
||||||
|
FormHistoryPriv* priv)
|
||||||
|
{
|
||||||
|
GtkWidget* dialog;
|
||||||
|
GtkWidget* content_area;
|
||||||
|
GtkWidget* hbox;
|
||||||
|
GtkWidget* image;
|
||||||
|
GtkWidget* label;
|
||||||
|
GtkWidget* entry;
|
||||||
|
const gchar* title;
|
||||||
|
static int alive;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
/* Password is set */
|
||||||
|
if (priv->master_password && *priv->master_password)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Other prompt is active */
|
||||||
|
if (alive == 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Prompt was cancelled */
|
||||||
|
if (priv->master_password_canceled == 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
alive = 1;
|
||||||
|
title = _("Form history");
|
||||||
|
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||||
|
NULL);
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (content_area), 5);
|
||||||
|
|
||||||
|
hbox = gtk_hbox_new (FALSE, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
|
||||||
|
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
|
||||||
|
GTK_ICON_SIZE_DIALOG);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
label = gtk_label_new (_("Master password required\n"
|
||||||
|
"to open password database"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
|
|
||||||
|
entry = gtk_entry_new ();
|
||||||
|
g_object_set (entry, "truncate-multiline", TRUE, NULL);
|
||||||
|
gtk_entry_set_visibility(GTK_ENTRY (entry),FALSE);
|
||||||
|
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), entry);
|
||||||
|
|
||||||
|
gtk_widget_show_all (entry);
|
||||||
|
gtk_widget_show_all (hbox);
|
||||||
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||||
|
|
||||||
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
|
||||||
|
{
|
||||||
|
/* FIXME: add password verification */
|
||||||
|
katze_assign (priv->master_password,
|
||||||
|
g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))));
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
priv->master_password_canceled = 1;
|
||||||
|
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
alive = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
formhistory_encrypt (const gchar* data,
|
||||||
|
const gchar* password)
|
||||||
|
{
|
||||||
|
/* TODO: Implement persistent storage/ keyring support */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_remember_password_response (GtkWidget* infobar,
|
||||||
|
gint response_id,
|
||||||
|
FormhistoryPasswordEntry* entry)
|
||||||
|
{
|
||||||
|
gchar* encrypted_form;
|
||||||
|
|
||||||
|
if (response_id == GTK_RESPONSE_IGNORE)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (formhistory_check_master_password (NULL, entry->priv))
|
||||||
|
{
|
||||||
|
if (response_id != GTK_RESPONSE_ACCEPT)
|
||||||
|
katze_assign (entry->form_data, g_strdup ("never"));
|
||||||
|
|
||||||
|
if ((encrypted_form = formhistory_encrypt (entry->form_data,
|
||||||
|
entry->priv->master_password)))
|
||||||
|
formhistory_update_database (entry->priv->db, entry->domain, "MidoriPasswordManager", encrypted_form);
|
||||||
|
g_free (encrypted_form);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
g_free (entry->form_data);
|
||||||
|
g_free (entry->domain);
|
||||||
|
g_slice_free (FormhistoryPasswordEntry, entry);
|
||||||
|
gtk_widget_destroy (infobar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
||||||
|
WebKitWebFrame* web_frame,
|
||||||
|
WebKitNetworkRequest* request,
|
||||||
|
WebKitWebNavigationAction* action,
|
||||||
|
WebKitWebPolicyDecision* decision,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
JSContextRef js_context;
|
||||||
|
gchar* value;
|
||||||
|
|
||||||
|
/* The script returns form data in the form "field_name|,|value|,|field_type".
|
||||||
|
We are handling only input fields with 'text' or 'password' type.
|
||||||
|
The field separator is "|||" */
|
||||||
|
const gchar* script = "function dumpForm (inputs) {"
|
||||||
|
" var out = '';"
|
||||||
|
" for (i=0;i<inputs.length;i++) {"
|
||||||
|
" if (inputs[i].getAttribute('autocomplete') == 'off' && "
|
||||||
|
" inputs[i].type == 'text')"
|
||||||
|
" continue;"
|
||||||
|
" if (inputs[i].value && (inputs[i].type == 'text' || inputs[i].type == 'password')) {"
|
||||||
|
" var ename = inputs[i].getAttribute('name');"
|
||||||
|
" var eid = inputs[i].getAttribute('id');"
|
||||||
|
" if (!eid && ename)"
|
||||||
|
" eid=ename;"
|
||||||
|
" out += eid+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
||||||
|
" }"
|
||||||
|
" }"
|
||||||
|
" return out;"
|
||||||
|
"}"
|
||||||
|
"dumpForm (document.getElementsByTagName('input'))";
|
||||||
|
|
||||||
|
if (webkit_web_navigation_action_get_reason (action) != WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||||
|
js_context = webkit_web_frame_get_global_context (web_frame);
|
||||||
|
value = sokoke_js_script_eval (js_context, script, NULL);
|
||||||
|
|
||||||
|
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||||
|
if (value && *value)
|
||||||
|
{
|
||||||
|
gchar** inputs = g_strsplit (value, "|||", 0);
|
||||||
|
guint i = 0;
|
||||||
|
while (inputs[i] != NULL)
|
||||||
|
{
|
||||||
|
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||||
|
if (parts && parts[0] && parts[1] && parts[2])
|
||||||
|
{
|
||||||
|
if (strcmp (parts[2], "password"))
|
||||||
|
formhistory_update_database (priv->db, NULL, parts[0], parts[1]);
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gchar* data;
|
||||||
|
gchar* domain;
|
||||||
|
#if 0
|
||||||
|
FormhistoryPasswordEntry* entry;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
domain = midori_uri_parse_hostname (webkit_web_frame_get_uri (web_frame), NULL);
|
||||||
|
data = formhistory_get_login_data (priv->db, domain);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
g_free (data);
|
||||||
|
g_free (domain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
entry = g_slice_new (FormhistoryPasswordEntry);
|
||||||
|
/* Domain and form data are freed from infopanel callback*/
|
||||||
|
entry->form_data = g_strdup (value);
|
||||||
|
entry->domain = domain;
|
||||||
|
entry->priv = priv;
|
||||||
|
g_object_set_data (G_OBJECT (web_view), "FormHistoryPasswordEntry", entry);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
g_strfreev (parts);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
g_strfreev (inputs);
|
||||||
|
g_free (value);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_window_object_cleared_cb (WebKitWebView* web_view,
|
||||||
|
WebKitWebFrame* web_frame,
|
||||||
|
JSContextRef js_context,
|
||||||
|
JSObjectRef js_window,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
const gchar* page_uri;
|
||||||
|
FormhistoryPasswordEntry* entry;
|
||||||
|
GtkWidget* view;
|
||||||
|
|
||||||
|
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||||
|
if (!page_uri)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!midori_uri_is_http (page_uri) && !g_str_has_prefix (page_uri, "file"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
formhistory_setup_suggestions (web_view, js_context, extension);
|
||||||
|
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||||
|
entry = g_object_get_data (G_OBJECT (web_view), "FormHistoryPasswordEntry");
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
const gchar* message = _("Remember password on this page?");
|
||||||
|
view = midori_browser_get_current_tab (midori_app_get_browser (
|
||||||
|
midori_extension_get_app (extension)));
|
||||||
|
midori_view_add_info_bar (MIDORI_VIEW (view), GTK_MESSAGE_QUESTION, message,
|
||||||
|
G_CALLBACK (formhistory_remember_password_response), entry,
|
||||||
|
_("Remember"), GTK_RESPONSE_ACCEPT,
|
||||||
|
_("Not now"), GTK_RESPONSE_IGNORE,
|
||||||
|
_("Never for this page"), GTK_RESPONSE_CANCEL, NULL);
|
||||||
|
g_object_set_data (G_OBJECT (web_view), "FormHistoryPasswordEntry", NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||||
|
static gchar*
|
||||||
|
formhistory_decrypt (const gchar* data,
|
||||||
|
const gchar* password)
|
||||||
|
{
|
||||||
|
/* TODO: Implement persistent storage/ keyring support */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_fill_login_data (JSContextRef js_context,
|
||||||
|
FormHistoryPriv* priv,
|
||||||
|
const gchar* data)
|
||||||
|
{
|
||||||
|
gchar* decrypted_data = NULL;
|
||||||
|
guint i = 0;
|
||||||
|
GString *script;
|
||||||
|
gchar** inputs;
|
||||||
|
|
||||||
|
/* Handle case that user dont want to store password */
|
||||||
|
if (!strncmp (data, "never", 5))
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!formhistory_check_master_password (NULL, priv))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(decrypted_data = formhistory_decrypt (data, priv->master_password)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
script = g_string_new ("");
|
||||||
|
inputs = g_strsplit (decrypted_data, "|||", 0);
|
||||||
|
while (inputs[i] != NULL)
|
||||||
|
{
|
||||||
|
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||||
|
if (parts && parts[0] && parts[1] && parts[2])
|
||||||
|
{
|
||||||
|
g_string_append_printf (script, "node = null;"
|
||||||
|
"node = document.getElementById ('%s');"
|
||||||
|
"if (!node) { node = document.getElementsByName ('%s')[0]; }"
|
||||||
|
"if (node && node.type == '%s') { node.value = '%s'; }",
|
||||||
|
parts[0], parts[0], parts[2], parts[1]);
|
||||||
|
}
|
||||||
|
g_strfreev (parts);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
g_free (decrypted_data);
|
||||||
|
g_strfreev (inputs);
|
||||||
|
g_free (sokoke_js_script_eval (js_context, script->str, NULL));
|
||||||
|
g_string_free (script, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_frame_loaded_cb (WebKitWebView* web_view,
|
||||||
|
WebKitWebFrame* web_frame,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
const gchar* page_uri;
|
||||||
|
const gchar* count_request;
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
JSContextRef js_context;
|
||||||
|
gchar* data;
|
||||||
|
gchar* domain;
|
||||||
|
gchar* count;
|
||||||
|
|
||||||
|
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||||
|
if (!page_uri)
|
||||||
|
return;
|
||||||
|
|
||||||
|
count_request = "document.querySelectorAll('input[type=password]').length";
|
||||||
|
js_context = webkit_web_frame_get_global_context (web_frame);
|
||||||
|
count = sokoke_js_script_eval (js_context, count_request, NULL);
|
||||||
|
if (count && count[0] == '0')
|
||||||
|
{
|
||||||
|
g_free (count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_free (count);
|
||||||
|
|
||||||
|
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||||
|
domain = midori_uri_parse_hostname (webkit_web_frame_get_uri (web_frame), NULL);
|
||||||
|
data = formhistory_get_login_data (priv->db, domain);
|
||||||
|
g_free (domain);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
formhistory_fill_login_data (js_context, priv, data);
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||||
|
MidoriBrowser* browser);
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_add_tab_cb (MidoriBrowser* browser,
|
||||||
|
MidoriView* view,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||||
|
|
||||||
|
g_signal_connect (web_view, "window-object-cleared",
|
||||||
|
G_CALLBACK (formhistory_window_object_cleared_cb), extension);
|
||||||
|
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
||||||
|
G_CALLBACK (formhistory_navigation_decision_cb), extension);
|
||||||
|
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||||
|
g_signal_connect (web_view, "onload-event",
|
||||||
|
G_CALLBACK (formhistory_frame_loaded_cb), extension);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_add_tab_foreach_cb (MidoriView* view,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
formhistory_add_tab_cb (NULL, view, extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_app_add_browser_cb (MidoriApp* app,
|
||||||
|
MidoriBrowser* browser,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
|
||||||
|
GtkAccelGroup* acg = gtk_accel_group_new ();
|
||||||
|
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||||
|
GtkAction* action = gtk_action_new ("FormHistoryToggleState",
|
||||||
|
_("Toggle form history state"),
|
||||||
|
_("Activate or deactivate form history for the current tab."), NULL);
|
||||||
|
gtk_window_add_accel_group (GTK_WINDOW (browser), acg);
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", extension);
|
||||||
|
|
||||||
|
g_signal_connect (action, "activate",
|
||||||
|
G_CALLBACK (formhistory_toggle_state_cb), browser);
|
||||||
|
|
||||||
|
gtk_action_group_add_action_with_accel (action_group, action, "<Ctrl><Shift>F");
|
||||||
|
gtk_action_set_accel_group (action, acg);
|
||||||
|
gtk_action_connect_accelerator (action);
|
||||||
|
|
||||||
|
if (midori_extension_get_boolean (extension, "always-load"))
|
||||||
|
{
|
||||||
|
midori_browser_foreach (browser,
|
||||||
|
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||||
|
g_signal_connect (browser, "add-tab",
|
||||||
|
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||||
|
}
|
||||||
|
g_signal_connect (extension, "deactivate",
|
||||||
|
G_CALLBACK (formhistory_deactivate_cb), browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_deactivate_tab (MidoriView* view,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
web_view, formhistory_window_object_cleared_cb, extension);
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
web_view, formhistory_navigation_decision_cb, extension);
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
web_view, formhistory_frame_loaded_cb, extension);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||||
|
MidoriBrowser* browser)
|
||||||
|
{
|
||||||
|
MidoriApp* app = midori_extension_get_app (extension);
|
||||||
|
FormHistoryPriv* priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||||
|
|
||||||
|
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||||
|
GtkAction* action;
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
browser, formhistory_add_tab_cb, extension);
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
extension, formhistory_deactivate_cb, browser);
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
app, formhistory_app_add_browser_cb, extension);
|
||||||
|
midori_browser_foreach (browser,
|
||||||
|
(GtkCallback)formhistory_deactivate_tab, extension);
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", NULL);
|
||||||
|
action = gtk_action_group_get_action (action_group, "FormHistoryToggleState");
|
||||||
|
if (action != NULL)
|
||||||
|
{
|
||||||
|
gtk_action_group_remove_action (action_group, action);
|
||||||
|
g_object_unref (action);
|
||||||
|
}
|
||||||
|
|
||||||
|
formhistory_private_destroy (priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_activate_cb (MidoriExtension* extension,
|
||||||
|
MidoriApp* app)
|
||||||
|
{
|
||||||
|
const gchar* config_dir;
|
||||||
|
gchar* filename;
|
||||||
|
sqlite3* db;
|
||||||
|
char* errmsg = NULL, *errmsg2 = NULL;
|
||||||
|
KatzeArray* browsers;
|
||||||
|
MidoriBrowser* browser;
|
||||||
|
FormHistoryPriv* priv;
|
||||||
|
|
||||||
|
priv = formhistory_private_new ();
|
||||||
|
priv->master_password = NULL;
|
||||||
|
priv->master_password_canceled = 0;
|
||||||
|
formhistory_construct_popup_gui (priv);
|
||||||
|
|
||||||
|
config_dir = midori_extension_get_config_dir (extension);
|
||||||
|
katze_mkdir_with_parents (config_dir, 0700);
|
||||||
|
filename = g_build_filename (config_dir, "forms.db", NULL);
|
||||||
|
if (sqlite3_open (filename, &db) != SQLITE_OK)
|
||||||
|
{
|
||||||
|
/* If the folder is /, this is a test run, thus no error */
|
||||||
|
if (!g_str_equal (midori_extension_get_config_dir (extension), "/"))
|
||||||
|
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
|
||||||
|
sqlite3_close (db);
|
||||||
|
}
|
||||||
|
g_free (filename);
|
||||||
|
if ((sqlite3_exec (db, "CREATE TABLE IF NOT EXISTS "
|
||||||
|
"forms (domain text, field text, value text)",
|
||||||
|
NULL, NULL, &errmsg) == SQLITE_OK))
|
||||||
|
{
|
||||||
|
sqlite3_exec (db,
|
||||||
|
/* "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY" */
|
||||||
|
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
|
||||||
|
NULL, NULL, &errmsg);
|
||||||
|
priv->db = db;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (errmsg)
|
||||||
|
{
|
||||||
|
g_critical (_("Failed to execute database statement: %s\n"), errmsg);
|
||||||
|
sqlite3_free (errmsg);
|
||||||
|
if (errmsg2)
|
||||||
|
{
|
||||||
|
g_critical (_("Failed to execute database statement: %s\n"), errmsg2);
|
||||||
|
sqlite3_free (errmsg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_close (db);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (extension), "priv", priv);
|
||||||
|
browsers = katze_object_get_object (app, "browsers");
|
||||||
|
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||||
|
formhistory_app_add_browser_cb (app, browser, extension);
|
||||||
|
g_signal_connect (app, "add-browser",
|
||||||
|
G_CALLBACK (formhistory_app_add_browser_cb), extension);
|
||||||
|
|
||||||
|
g_object_unref (browsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_preferences_response_cb (GtkWidget* dialog,
|
||||||
|
gint response_id,
|
||||||
|
MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
GtkWidget* checkbox;
|
||||||
|
gboolean old_state;
|
||||||
|
gboolean new_state;
|
||||||
|
MidoriApp* app;
|
||||||
|
KatzeArray* browsers;
|
||||||
|
MidoriBrowser* browser;
|
||||||
|
|
||||||
|
if (response_id == GTK_RESPONSE_APPLY)
|
||||||
|
{
|
||||||
|
checkbox = g_object_get_data (G_OBJECT (dialog), "always-load-checkbox");
|
||||||
|
new_state = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
|
||||||
|
old_state = midori_extension_get_boolean (extension, "always-load");
|
||||||
|
|
||||||
|
if (old_state != new_state)
|
||||||
|
{
|
||||||
|
midori_extension_set_boolean (extension, "always-load", new_state);
|
||||||
|
|
||||||
|
app = midori_extension_get_app (extension);
|
||||||
|
browsers = katze_object_get_object (app, "browsers");
|
||||||
|
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||||
|
{
|
||||||
|
midori_browser_foreach (browser,
|
||||||
|
(GtkCallback)formhistory_deactivate_tab, extension);
|
||||||
|
g_signal_handlers_disconnect_by_func (
|
||||||
|
browser, formhistory_add_tab_cb, extension);
|
||||||
|
|
||||||
|
if (new_state)
|
||||||
|
{
|
||||||
|
midori_browser_foreach (browser,
|
||||||
|
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||||
|
g_signal_connect (browser, "add-tab",
|
||||||
|
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_preferences_cb (MidoriExtension* extension)
|
||||||
|
{
|
||||||
|
GtkWidget* dialog;
|
||||||
|
GtkWidget* content_area;
|
||||||
|
GtkWidget* checkbox;
|
||||||
|
|
||||||
|
dialog = gtk_dialog_new ();
|
||||||
|
|
||||||
|
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||||
|
|
||||||
|
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
||||||
|
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY);
|
||||||
|
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
checkbox = gtk_check_button_new_with_label (_("Only activate form history via hotkey (Ctrl+Shift+F) per tab"));
|
||||||
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox),
|
||||||
|
!midori_extension_get_boolean (extension, "always-load"));
|
||||||
|
g_object_set_data (G_OBJECT (dialog), "always-load-checkbox", checkbox);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), checkbox);
|
||||||
|
/* FIXME: Add pref to disable password manager */
|
||||||
|
|
||||||
|
g_signal_connect (dialog,
|
||||||
|
"response",
|
||||||
|
G_CALLBACK (formhistory_preferences_response_cb),
|
||||||
|
extension);
|
||||||
|
gtk_widget_show_all (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
formhistory_toggle_state_cb (GtkAction* action,
|
||||||
|
MidoriBrowser* browser)
|
||||||
|
{
|
||||||
|
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
||||||
|
MidoriExtension* extension = g_object_get_data (G_OBJECT (browser), "FormHistoryExtension");
|
||||||
|
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||||
|
|
||||||
|
if (g_signal_handler_find (web_view, G_SIGNAL_MATCH_FUNC,
|
||||||
|
g_signal_lookup ("window-object-cleared", MIDORI_TYPE_VIEW), 0, NULL,
|
||||||
|
formhistory_window_object_cleared_cb, extension))
|
||||||
|
{
|
||||||
|
formhistory_deactivate_tab (view, extension);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
formhistory_add_tab_cb (browser, view, extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
MidoriExtension*
|
||||||
|
extension_init (void)
|
||||||
|
{
|
||||||
|
MidoriExtension* extension;
|
||||||
|
|
||||||
|
|
||||||
|
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||||
|
"name", _("Form history filler"),
|
||||||
|
"description", _("Stores history of entered form data"),
|
||||||
|
"version", "2.0" MIDORI_VERSION_SUFFIX,
|
||||||
|
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
midori_extension_install_boolean (extension, "always-load", TRUE);
|
||||||
|
g_signal_connect (extension, "activate",
|
||||||
|
G_CALLBACK (formhistory_activate_cb), NULL);
|
||||||
|
g_signal_connect (extension, "open-preferences",
|
||||||
|
G_CALLBACK (formhistory_preferences_cb), NULL);
|
||||||
|
|
||||||
|
return extension;
|
||||||
|
}
|
|
@ -180,8 +180,6 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
||||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||||
#endif
|
#endif
|
||||||
NULL);
|
NULL);
|
||||||
g_signal_connect (dialog, "destroy",
|
|
||||||
G_CALLBACK (gtk_widget_destroyed), &dialog);
|
|
||||||
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PROPERTIES);
|
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PROPERTIES);
|
||||||
sokoke_widget_get_text_size (dialog, "M", &width, &height);
|
sokoke_widget_get_text_size (dialog, "M", &width, &height);
|
||||||
gtk_window_set_default_size (GTK_WINDOW (dialog), width * 52, height * 24);
|
gtk_window_set_default_size (GTK_WINDOW (dialog), width * 52, height * 24);
|
||||||
|
|
|
@ -66,11 +66,14 @@ statusbar_features_browser_notify_tab_cb (MidoriBrowser* browser,
|
||||||
GtkWidget* combobox)
|
GtkWidget* combobox)
|
||||||
{
|
{
|
||||||
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
||||||
gchar* zoom_level_text = g_strdup_printf ("%d%%",
|
gchar* text;
|
||||||
(gint)(midori_view_get_zoom_level (view) * 100));
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combobox))),
|
if (view == NULL)
|
||||||
zoom_level_text);
|
return;
|
||||||
g_free (zoom_level_text);
|
|
||||||
|
text = g_strdup_printf ("%d%%", (gint)(midori_view_get_zoom_level (view) * 100));
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combobox))), text);
|
||||||
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -142,6 +145,8 @@ statusbar_features_app_add_browser_cb (MidoriApp* app,
|
||||||
g_signal_connect (toolbar, "notify::toolbar-style",
|
g_signal_connect (toolbar, "notify::toolbar-style",
|
||||||
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
|
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
|
||||||
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
||||||
|
if (midori_web_settings_has_plugin_support ())
|
||||||
|
{
|
||||||
button = katze_property_proxy (settings, "enable-plugins", "toggle");
|
button = katze_property_proxy (settings, "enable-plugins", "toggle");
|
||||||
g_object_set_data (G_OBJECT (button), "feature-label", _("Netscape plugins"));
|
g_object_set_data (G_OBJECT (button), "feature-label", _("Netscape plugins"));
|
||||||
image = gtk_image_new_from_stock (STOCK_PLUGINS, GTK_ICON_SIZE_MENU);
|
image = gtk_image_new_from_stock (STOCK_PLUGINS, GTK_ICON_SIZE_MENU);
|
||||||
|
@ -151,6 +156,7 @@ statusbar_features_app_add_browser_cb (MidoriApp* app,
|
||||||
g_signal_connect (toolbar, "notify::toolbar-style",
|
g_signal_connect (toolbar, "notify::toolbar-style",
|
||||||
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
|
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
|
||||||
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
||||||
|
}
|
||||||
button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
|
button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
|
||||||
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
||||||
button = gtk_combo_box_text_new_with_entry ();
|
button = gtk_combo_box_text_new_with_entry ();
|
||||||
|
@ -162,8 +168,9 @@ statusbar_features_app_add_browser_cb (MidoriApp* app,
|
||||||
G_CALLBACK (statusbar_features_zoom_level_changed_cb), browser);
|
G_CALLBACK (statusbar_features_zoom_level_changed_cb), browser);
|
||||||
g_signal_connect (browser, "notify::tab",
|
g_signal_connect (browser, "notify::tab",
|
||||||
G_CALLBACK (statusbar_features_browser_notify_tab_cb), button);
|
G_CALLBACK (statusbar_features_browser_notify_tab_cb), button);
|
||||||
|
statusbar_features_browser_notify_tab_cb (browser, NULL, button);
|
||||||
gtk_widget_show_all (bbox);
|
gtk_widget_show_all (bbox);
|
||||||
gtk_box_pack_start (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
|
gtk_box_pack_end (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
|
||||||
g_object_unref (statusbar);
|
g_object_unref (statusbar);
|
||||||
|
|
||||||
g_signal_connect (extension, "deactivate",
|
g_signal_connect (extension, "deactivate",
|
||||||
|
|
|
@ -394,11 +394,7 @@ static TBEditorWidget *tb_editor_create_dialog(MidoriBrowser *parent)
|
||||||
GTK_WINDOW(parent),
|
GTK_WINDOW(parent),
|
||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
|
||||||
#if !GTK_CHECK_VERSION(3,0,0)
|
vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||||
vbox = (GTK_DIALOG(dialog))->vbox;
|
|
||||||
#else
|
|
||||||
vbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
|
|
||||||
#endif
|
|
||||||
gtk_box_set_spacing(GTK_BOX(vbox), 6);
|
gtk_box_set_spacing(GTK_BOX(vbox), 6);
|
||||||
gtk_widget_set_name(dialog, "GeanyDialog");
|
gtk_widget_set_name(dialog, "GeanyDialog");
|
||||||
gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
|
gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
|
||||||
|
|
|
@ -27,9 +27,9 @@ sokoke_on_entry_focus_in_event (GtkEntry* entry,
|
||||||
g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
|
g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
|
||||||
if (has_default)
|
if (has_default)
|
||||||
{
|
{
|
||||||
gtk_entry_set_text (entry, "");
|
|
||||||
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
|
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
|
||||||
GINT_TO_POINTER (0));
|
GINT_TO_POINTER (0));
|
||||||
|
gtk_entry_set_text (entry, "");
|
||||||
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
||||||
PANGO_STYLE_NORMAL);
|
PANGO_STYLE_NORMAL);
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ sokoke_on_entry_focus_out_event (GtkEntry* entry,
|
||||||
{
|
{
|
||||||
const gchar* default_text = (const gchar*)g_object_get_data (
|
const gchar* default_text = (const gchar*)g_object_get_data (
|
||||||
G_OBJECT (entry), "sokoke_default_text");
|
G_OBJECT (entry), "sokoke_default_text");
|
||||||
gtk_entry_set_text (entry, default_text);
|
|
||||||
g_object_set_data (G_OBJECT (entry),
|
g_object_set_data (G_OBJECT (entry),
|
||||||
"sokoke_has_default", GINT_TO_POINTER (1));
|
"sokoke_has_default", GINT_TO_POINTER (1));
|
||||||
|
gtk_entry_set_text (entry, default_text);
|
||||||
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
||||||
PANGO_STYLE_ITALIC);
|
PANGO_STYLE_ITALIC);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,9 @@ gtk_entry_set_placeholder_text (GtkEntry* entry,
|
||||||
/* Note: The default text initially overwrites any previous text */
|
/* Note: The default text initially overwrites any previous text */
|
||||||
gchar* old_value = g_object_get_data (G_OBJECT (entry),
|
gchar* old_value = g_object_get_data (G_OBJECT (entry),
|
||||||
"sokoke_default_text");
|
"sokoke_default_text");
|
||||||
|
g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
|
||||||
|
(gpointer)default_text);
|
||||||
|
|
||||||
if (!old_value)
|
if (!old_value)
|
||||||
{
|
{
|
||||||
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
|
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
|
||||||
|
@ -98,8 +101,12 @@ gtk_entry_set_placeholder_text (GtkEntry* entry,
|
||||||
PANGO_STYLE_ITALIC);
|
PANGO_STYLE_ITALIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
|
}
|
||||||
(gpointer)default_text);
|
|
||||||
|
const gchar*
|
||||||
|
gtk_entry_get_placeholder_text (GtkEntry* entry)
|
||||||
|
{
|
||||||
|
return g_object_get_data (G_OBJECT (entry), "sokoke_default_text");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION (3, 2, 0)
|
#if GTK_CHECK_VERSION (3, 2, 0) && defined (GTK_DISABLE_DEPRECATED)
|
||||||
#define GTK_TYPE_VBOX GTK_TYPE_BOX
|
#define GTK_TYPE_VBOX GTK_TYPE_BOX
|
||||||
#define GtkVBox GtkBox
|
#define GtkVBox GtkBox
|
||||||
#define GtkVBoxClass GtkBoxClass
|
#define GtkVBoxClass GtkBoxClass
|
||||||
|
@ -89,8 +89,10 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
#if !GTK_CHECK_VERSION (3, 2, 0) && defined (HAVE_HILDON_2_2)
|
#if !GTK_CHECK_VERSION (3, 2, 0) && defined (HAVE_HILDON_2_2)
|
||||||
#define gtk_entry_set_placeholder_text hildon_gtk_entry_set_placeholder_text
|
#define gtk_entry_set_placeholder_text hildon_gtk_entry_set_placeholder_text
|
||||||
|
#define gtk_entry_get_placeholder_text hildon_gtk_entry_get_placeholder_text
|
||||||
#elif !GTK_CHECK_VERSION (3, 2, 0)
|
#elif !GTK_CHECK_VERSION (3, 2, 0)
|
||||||
#define gtk_entry_set_placeholder_text sokoke_entry_set_default_text
|
void gtk_entry_set_placeholder_text (GtkEntry* entry, const gchar* text);
|
||||||
|
const gchar* gtk_entry_get_placeholder_text (GtkEntry* entry);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !GTK_CHECK_VERSION(2, 12, 0)
|
#if !GTK_CHECK_VERSION(2, 12, 0)
|
||||||
|
|
|
@ -74,6 +74,13 @@ GList* kalistglobal;
|
||||||
static void
|
static void
|
||||||
katze_array_finalize (GObject* object);
|
katze_array_finalize (GObject* object);
|
||||||
|
|
||||||
|
static void
|
||||||
|
_katze_array_update (KatzeArray* array)
|
||||||
|
{
|
||||||
|
g_object_set_data (G_OBJECT (array), "last-update",
|
||||||
|
GINT_TO_POINTER (time (NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_katze_array_add_item (KatzeArray* array,
|
_katze_array_add_item (KatzeArray* array,
|
||||||
gpointer item)
|
gpointer item)
|
||||||
|
@ -84,6 +91,7 @@ _katze_array_add_item (KatzeArray* array,
|
||||||
katze_item_set_parent (item, array);
|
katze_item_set_parent (item, array);
|
||||||
|
|
||||||
array->items = g_list_append (array->items, item);
|
array->items = g_list_append (array->items, item);
|
||||||
|
_katze_array_update (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -95,6 +103,7 @@ _katze_array_remove_item (KatzeArray* array,
|
||||||
if (KATZE_IS_ITEM (item))
|
if (KATZE_IS_ITEM (item))
|
||||||
katze_item_set_parent (item, NULL);
|
katze_item_set_parent (item, NULL);
|
||||||
g_object_unref (item);
|
g_object_unref (item);
|
||||||
|
_katze_array_update (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -104,6 +113,7 @@ _katze_array_move_item (KatzeArray* array,
|
||||||
{
|
{
|
||||||
array->items = g_list_remove (array->items, item);
|
array->items = g_list_remove (array->items, item);
|
||||||
array->items = g_list_insert (array->items, item, position);
|
array->items = g_list_insert (array->items, item, position);
|
||||||
|
_katze_array_update (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -112,9 +122,10 @@ _katze_array_clear (KatzeArray* array)
|
||||||
GObject* item;
|
GObject* item;
|
||||||
|
|
||||||
while ((item = g_list_nth_data (array->items, 0)))
|
while ((item = g_list_nth_data (array->items, 0)))
|
||||||
katze_array_remove_item (array, item);
|
g_signal_emit (array, signals[REMOVE_ITEM], 0, item);
|
||||||
g_list_free (array->items);
|
g_list_free (array->items);
|
||||||
array->items = NULL;
|
array->items = NULL;
|
||||||
|
_katze_array_update (array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -192,7 +203,7 @@ katze_array_class_init (KatzeArrayClass* class)
|
||||||
"update",
|
"update",
|
||||||
G_TYPE_FROM_CLASS (class),
|
G_TYPE_FROM_CLASS (class),
|
||||||
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
|
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
|
||||||
0,
|
G_STRUCT_OFFSET (KatzeArrayClass, update),
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
@ -205,6 +216,7 @@ katze_array_class_init (KatzeArrayClass* class)
|
||||||
class->remove_item = _katze_array_remove_item;
|
class->remove_item = _katze_array_remove_item;
|
||||||
class->move_item = _katze_array_move_item;
|
class->move_item = _katze_array_move_item;
|
||||||
class->clear = _katze_array_clear;
|
class->clear = _katze_array_clear;
|
||||||
|
class->update = _katze_array_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -217,14 +229,11 @@ katze_array_init (KatzeArray* array)
|
||||||
static void
|
static void
|
||||||
katze_array_finalize (GObject* object)
|
katze_array_finalize (GObject* object)
|
||||||
{
|
{
|
||||||
KatzeArray* array;
|
KatzeArray* array = KATZE_ARRAY (object);
|
||||||
guint i;
|
GList* items;
|
||||||
gpointer item;
|
|
||||||
|
|
||||||
array = KATZE_ARRAY (object);
|
for (items = array->items; items; items = g_list_next (items))
|
||||||
i = 0;
|
g_object_unref (items->data);
|
||||||
while ((item = g_list_nth_data (array->items, i++)))
|
|
||||||
g_object_unref (item);
|
|
||||||
g_list_free (array->items);
|
g_list_free (array->items);
|
||||||
|
|
||||||
G_OBJECT_CLASS (katze_array_parent_class)->finalize (object);
|
G_OBJECT_CLASS (katze_array_parent_class)->finalize (object);
|
||||||
|
@ -364,37 +373,39 @@ katze_array_get_item_index (KatzeArray* array,
|
||||||
/**
|
/**
|
||||||
* katze_array_find_token:
|
* katze_array_find_token:
|
||||||
* @array: a #KatzeArray
|
* @array: a #KatzeArray
|
||||||
* @token: a token string
|
* @token: a token string, or "token keywords" string
|
||||||
*
|
*
|
||||||
* Looks up an item in the array which has the specified token.
|
* Looks up an item in the array which has the specified token.
|
||||||
*
|
*
|
||||||
* This function will silently fail if the type of the list
|
* This function will fail if the type of the list
|
||||||
* is not based on #GObject and only #KatzeItem children
|
* is not based on #KatzeItem children.
|
||||||
* are checked for their token, any other objects are skipped.
|
|
||||||
*
|
*
|
||||||
* Note that @token is by definition unique to one item.
|
* Note that @token is by definition unique to one item.
|
||||||
*
|
*
|
||||||
|
* Since 0.4.4 @token can be a "token keywords" string.
|
||||||
|
*
|
||||||
* Return value: an item, or %NULL
|
* Return value: an item, or %NULL
|
||||||
**/
|
**/
|
||||||
gpointer
|
gpointer
|
||||||
katze_array_find_token (KatzeArray* array,
|
katze_array_find_token (KatzeArray* array,
|
||||||
const gchar* token)
|
const gchar* token)
|
||||||
{
|
{
|
||||||
guint i;
|
goffset token_length;
|
||||||
gpointer item;
|
GList* items;
|
||||||
|
|
||||||
g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
|
g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
|
||||||
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
|
||||||
|
g_return_val_if_fail (token != NULL, NULL);
|
||||||
|
|
||||||
i = 0;
|
token_length = strchr (token, ' ') - token;
|
||||||
while ((item = g_list_nth_data (array->items, i++)))
|
if (token_length < 1)
|
||||||
|
token_length = strlen (token);
|
||||||
|
|
||||||
|
for (items = array->items; items; items = g_list_next (items))
|
||||||
{
|
{
|
||||||
const gchar* found_token;
|
const gchar* found_token = ((KatzeItem*)items->data)->token;
|
||||||
|
if (found_token != NULL && !strncmp (token, found_token, token_length))
|
||||||
if (!KATZE_IS_ITEM (item))
|
return items->data;
|
||||||
continue;
|
|
||||||
found_token = ((KatzeItem*)item)->token;
|
|
||||||
if (!g_strcmp0 (found_token, token))
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -406,9 +417,8 @@ katze_array_find_token (KatzeArray* array,
|
||||||
*
|
*
|
||||||
* Looks up an item in the array which has the specified URI.
|
* Looks up an item in the array which has the specified URI.
|
||||||
*
|
*
|
||||||
* This function will silently fail if the type of the list
|
* This function will fail if the type of the list
|
||||||
* is not based on #GObject and only #KatzeItem children
|
* is not based on #KatzeItem children.
|
||||||
* are checked for their token, any other objects are skipped.
|
|
||||||
*
|
*
|
||||||
* Return value: an item, or %NULL
|
* Return value: an item, or %NULL
|
||||||
*
|
*
|
||||||
|
@ -418,19 +428,17 @@ gpointer
|
||||||
katze_array_find_uri (KatzeArray* array,
|
katze_array_find_uri (KatzeArray* array,
|
||||||
const gchar* uri)
|
const gchar* uri)
|
||||||
{
|
{
|
||||||
guint i;
|
GList* items;
|
||||||
gpointer item;
|
|
||||||
|
|
||||||
i = 0;
|
g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
|
||||||
while ((item = g_list_nth_data (array->items, i++)))
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
|
||||||
|
g_return_val_if_fail (uri != NULL, NULL);
|
||||||
|
|
||||||
|
for (items = array->items; items; items = g_list_next (items))
|
||||||
{
|
{
|
||||||
const gchar* found_uri;
|
const gchar* found_uri = ((KatzeItem*)items->data)->uri;
|
||||||
|
if (found_uri != NULL && !strcmp (found_uri, uri))
|
||||||
if (!KATZE_IS_ITEM (item))
|
return items->data;
|
||||||
continue;
|
|
||||||
found_uri = ((KatzeItem*)item)->uri;
|
|
||||||
if (!g_strcmp0 (found_uri, uri))
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,11 +355,16 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
||||||
gint summand;
|
gint summand;
|
||||||
KatzeItem* item;
|
KatzeItem* item;
|
||||||
GtkWidget* menuitem;
|
GtkWidget* menuitem;
|
||||||
const gchar* icon_name;
|
|
||||||
GdkPixbuf* icon;
|
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
GtkWidget* submenu;
|
GtkWidget* submenu;
|
||||||
|
|
||||||
|
g_return_if_fail (KATZE_IS_ARRAY_ACTION (array_action));
|
||||||
|
g_return_if_fail (KATZE_IS_ITEM (array));
|
||||||
|
g_return_if_fail (GTK_IS_MENU_SHELL (menu));
|
||||||
|
g_return_if_fail (GTK_IS_TOOL_ITEM (proxy)
|
||||||
|
|| GTK_IS_MENU_ITEM (proxy)
|
||||||
|
|| GTK_IS_WINDOW (proxy));
|
||||||
|
|
||||||
if (!KATZE_IS_ARRAY (array))
|
if (!KATZE_IS_ARRAY (array))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -385,18 +390,7 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
||||||
}
|
}
|
||||||
menuitem = katze_image_menu_item_new_ellipsized (
|
menuitem = katze_image_menu_item_new_ellipsized (
|
||||||
katze_item_get_name (item));
|
katze_item_get_name (item));
|
||||||
if ((icon_name = katze_item_get_icon (item)) && *icon_name)
|
image = katze_item_get_image (item);
|
||||||
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (KATZE_ITEM_IS_FOLDER (item))
|
|
||||||
icon = gtk_widget_render_icon (menuitem,
|
|
||||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
|
||||||
else
|
|
||||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
|
||||||
image = gtk_image_new_from_pixbuf (icon);
|
|
||||||
g_object_unref (icon);
|
|
||||||
}
|
|
||||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
||||||
gtk_image_menu_item_set_always_show_image (
|
gtk_image_menu_item_set_always_show_image (
|
||||||
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
||||||
|
@ -406,8 +400,13 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
||||||
{
|
{
|
||||||
submenu = gtk_menu_new ();
|
submenu = gtk_menu_new ();
|
||||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
||||||
|
/* Make sure menu appears to contain items */
|
||||||
|
gtk_menu_shell_append (GTK_MENU_SHELL (submenu),
|
||||||
|
gtk_separator_menu_item_new ());
|
||||||
g_signal_connect (menuitem, "select",
|
g_signal_connect (menuitem, "select",
|
||||||
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
||||||
|
g_signal_connect (menuitem, "activate",
|
||||||
|
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -421,21 +420,39 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
katze_array_action_menu_item_select_cb (GtkWidget* proxy,
|
katze_array_action_menu_item_need_update (KatzeArrayAction* array_action,
|
||||||
KatzeArrayAction* array_action)
|
GtkWidget* proxy)
|
||||||
{
|
{
|
||||||
GtkWidget* menu;
|
GtkWidget* menu;
|
||||||
KatzeArray* array;
|
KatzeArray* array;
|
||||||
|
gint last_array_update, last_proxy_update;
|
||||||
gboolean handled;
|
gboolean handled;
|
||||||
|
|
||||||
|
array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
||||||
|
/* last-update is set on all arrays; consider public API */
|
||||||
|
last_array_update = GPOINTER_TO_INT (
|
||||||
|
g_object_get_data (G_OBJECT (array), "last-update"));
|
||||||
|
last_proxy_update = GPOINTER_TO_INT (
|
||||||
|
g_object_get_data (G_OBJECT (proxy), "last-update"));
|
||||||
|
if (last_proxy_update > last_array_update)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
|
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
|
||||||
gtk_container_foreach (GTK_CONTAINER (menu),
|
gtk_container_foreach (GTK_CONTAINER (menu),
|
||||||
(GtkCallback)(gtk_widget_destroy), NULL);
|
(GtkCallback)(gtk_widget_destroy), NULL);
|
||||||
|
|
||||||
array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
|
||||||
katze_array_action_generate_menu (array_action, array, GTK_MENU_SHELL (menu), proxy);
|
katze_array_action_generate_menu (array_action, array, GTK_MENU_SHELL (menu), proxy);
|
||||||
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0, menu, array, &handled);
|
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0, menu, array, &handled);
|
||||||
|
g_object_set_data (G_OBJECT (proxy), "last-update",
|
||||||
|
GINT_TO_POINTER (time (NULL)));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
katze_array_action_menu_item_select_cb (GtkWidget* proxy,
|
||||||
|
KatzeArrayAction* array_action)
|
||||||
|
{
|
||||||
|
katze_array_action_menu_item_need_update (array_action, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -458,20 +475,21 @@ katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
|
||||||
KatzeArray* array;
|
KatzeArray* array;
|
||||||
gboolean handled = FALSE;
|
gboolean handled = FALSE;
|
||||||
|
|
||||||
|
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
||||||
if (GTK_IS_MENU_ITEM (proxy))
|
if (GTK_IS_MENU_ITEM (proxy))
|
||||||
{
|
{
|
||||||
g_object_set_data (G_OBJECT (proxy), "KatzeItem", array_action->array);
|
if (katze_array_action_menu_item_need_update (array_action, proxy))
|
||||||
katze_array_action_menu_item_select_cb (proxy, array_action);
|
{
|
||||||
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0,
|
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0,
|
||||||
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)),
|
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)),
|
||||||
array_action->array, &handled);
|
array, &handled);
|
||||||
if (!handled)
|
if (!handled)
|
||||||
g_signal_emit (array_action, signals[POPULATE_POPUP], 0,
|
g_signal_emit (array_action, signals[POPULATE_POPUP], 0,
|
||||||
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)));
|
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
|
|
||||||
if (KATZE_IS_ITEM (array) && katze_item_get_uri ((KatzeItem*)array))
|
if (KATZE_IS_ITEM (array) && katze_item_get_uri ((KatzeItem*)array))
|
||||||
{
|
{
|
||||||
katze_array_action_activate_item (array_action, KATZE_ITEM (array), 1);
|
katze_array_action_activate_item (array_action, KATZE_ITEM (array), 1);
|
||||||
|
@ -552,7 +570,6 @@ katze_array_action_item_notify_cb (KatzeItem* item,
|
||||||
const gchar* property;
|
const gchar* property;
|
||||||
const gchar* title;
|
const gchar* title;
|
||||||
const gchar* desc;
|
const gchar* desc;
|
||||||
GdkPixbuf* icon;
|
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
|
|
||||||
if (!G_IS_PARAM_SPEC_STRING (pspec))
|
if (!G_IS_PARAM_SPEC_STRING (pspec))
|
||||||
|
@ -579,16 +596,13 @@ katze_array_action_item_notify_cb (KatzeItem* item,
|
||||||
}
|
}
|
||||||
else if (KATZE_ITEM_IS_BOOKMARK (item) && !strcmp (property, "uri"))
|
else if (KATZE_ITEM_IS_BOOKMARK (item) && !strcmp (property, "uri"))
|
||||||
{
|
{
|
||||||
icon = katze_load_cached_icon (katze_item_get_uri (item), GTK_WIDGET (toolitem));
|
image = katze_item_get_image (item);
|
||||||
image = gtk_image_new_from_pixbuf (icon);
|
|
||||||
g_object_unref (icon);
|
|
||||||
gtk_widget_show (image);
|
gtk_widget_show (image);
|
||||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||||
}
|
}
|
||||||
else if (!strcmp (property, "icon"))
|
else if (!strcmp (property, "icon"))
|
||||||
{
|
{
|
||||||
image = gtk_image_new_from_icon_name (katze_item_get_icon (item),
|
image = katze_item_get_image (item);
|
||||||
GTK_ICON_SIZE_MENU);
|
|
||||||
gtk_widget_show (image);
|
gtk_widget_show (image);
|
||||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||||
}
|
}
|
||||||
|
@ -600,25 +614,12 @@ katze_array_action_proxy_create_menu_proxy_cb (GtkWidget* proxy,
|
||||||
{
|
{
|
||||||
KatzeArrayAction* array_action;
|
KatzeArrayAction* array_action;
|
||||||
GtkWidget* menuitem;
|
GtkWidget* menuitem;
|
||||||
const gchar* icon_name;
|
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
GdkPixbuf* icon;
|
|
||||||
|
|
||||||
array_action = g_object_get_data (G_OBJECT (proxy), "KatzeArrayAction");
|
array_action = g_object_get_data (G_OBJECT (proxy), "KatzeArrayAction");
|
||||||
menuitem = katze_image_menu_item_new_ellipsized (
|
menuitem = katze_image_menu_item_new_ellipsized (
|
||||||
katze_item_get_name (item));
|
katze_item_get_name (item));
|
||||||
if ((icon_name = katze_item_get_icon (item)) && *icon_name)
|
image = katze_item_get_image (item);
|
||||||
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (KATZE_ITEM_IS_FOLDER (item))
|
|
||||||
icon = gtk_widget_render_icon (menuitem,
|
|
||||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
|
||||||
else
|
|
||||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
|
||||||
image = gtk_image_new_from_pixbuf (icon);
|
|
||||||
g_object_unref (icon);
|
|
||||||
}
|
|
||||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
||||||
gtk_image_menu_item_set_always_show_image (
|
gtk_image_menu_item_set_always_show_image (
|
||||||
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
||||||
|
@ -674,7 +675,6 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
||||||
const gchar* uri;
|
const gchar* uri;
|
||||||
const gchar* desc;
|
const gchar* desc;
|
||||||
GtkToolItem* toolitem;
|
GtkToolItem* toolitem;
|
||||||
GdkPixbuf* icon;
|
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
GtkWidget* label;
|
GtkWidget* label;
|
||||||
|
|
||||||
|
@ -686,20 +686,12 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
||||||
return gtk_separator_tool_item_new ();
|
return gtk_separator_tool_item_new ();
|
||||||
|
|
||||||
if (KATZE_ITEM_IS_FOLDER (item))
|
if (KATZE_ITEM_IS_FOLDER (item))
|
||||||
{
|
|
||||||
toolitem = gtk_toggle_tool_button_new ();
|
toolitem = gtk_toggle_tool_button_new ();
|
||||||
icon = gtk_widget_render_icon (GTK_WIDGET (toolitem),
|
|
||||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
toolitem = gtk_tool_button_new (NULL, "");
|
toolitem = gtk_tool_button_new (NULL, "");
|
||||||
icon = katze_load_cached_icon (uri, GTK_WIDGET (toolitem));
|
|
||||||
}
|
|
||||||
g_signal_connect (toolitem, "create-menu-proxy",
|
g_signal_connect (toolitem, "create-menu-proxy",
|
||||||
G_CALLBACK (katze_array_action_proxy_create_menu_proxy_cb), item);
|
G_CALLBACK (katze_array_action_proxy_create_menu_proxy_cb), item);
|
||||||
image = gtk_image_new_from_pixbuf (icon);
|
image = katze_item_get_image (item);
|
||||||
g_object_unref (icon);
|
|
||||||
gtk_widget_show (image);
|
gtk_widget_show (image);
|
||||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||||
label = gtk_label_new (NULL);
|
label = gtk_label_new (NULL);
|
||||||
|
@ -739,6 +731,9 @@ static void
|
||||||
katze_array_action_connect_proxy (GtkAction* action,
|
katze_array_action_connect_proxy (GtkAction* action,
|
||||||
GtkWidget* proxy)
|
GtkWidget* proxy)
|
||||||
{
|
{
|
||||||
|
KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (action);
|
||||||
|
g_object_set_data (G_OBJECT (proxy), "KatzeItem", array_action->array);
|
||||||
|
|
||||||
GTK_ACTION_CLASS (katze_array_action_parent_class)->connect_proxy (
|
GTK_ACTION_CLASS (katze_array_action_parent_class)->connect_proxy (
|
||||||
action, proxy);
|
action, proxy);
|
||||||
|
|
||||||
|
@ -750,9 +745,10 @@ katze_array_action_connect_proxy (GtkAction* action,
|
||||||
else if (GTK_IS_MENU_ITEM (proxy))
|
else if (GTK_IS_MENU_ITEM (proxy))
|
||||||
{
|
{
|
||||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (proxy), gtk_menu_new ());
|
gtk_menu_item_set_submenu (GTK_MENU_ITEM (proxy), gtk_menu_new ());
|
||||||
/* FIXME: 'select' doesn't cover all ways of selection */
|
|
||||||
g_signal_connect (proxy, "select",
|
g_signal_connect (proxy, "select",
|
||||||
G_CALLBACK (katze_array_action_proxy_clicked_cb), action);
|
G_CALLBACK (katze_array_action_proxy_clicked_cb), action);
|
||||||
|
g_signal_connect (proxy, "activate",
|
||||||
|
G_CALLBACK (katze_array_action_proxy_clicked_cb), action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;"
|
#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;"
|
||||||
#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
|
#define CREATE_TABLE "CREATE TABLE IF NOT EXISTS moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
|
||||||
#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);"
|
#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);"
|
||||||
#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;"
|
#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;"
|
||||||
|
|
||||||
|
@ -71,80 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (KatzeHttpCookiesSqlite, katze_http_cookies_sqlite, G_TY
|
||||||
Copyright (C) 2009 Collabora Ltd.
|
Copyright (C) 2009 Collabora Ltd.
|
||||||
Mostly copied from libSoup 2.30, coding style retained */
|
Mostly copied from libSoup 2.30, coding style retained */
|
||||||
|
|
||||||
static void
|
|
||||||
try_create_table (sqlite3 *db)
|
|
||||||
{
|
|
||||||
char *error = NULL;
|
|
||||||
|
|
||||||
if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) {
|
|
||||||
g_warning ("Failed to execute query: %s", error);
|
|
||||||
sqlite3_free (error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
exec_query_with_try_create_table (sqlite3* db,
|
|
||||||
const char* sql,
|
|
||||||
int (*callback)(void*,int,char**,char**),
|
|
||||||
void *argument)
|
|
||||||
{
|
|
||||||
char *error = NULL;
|
|
||||||
gboolean try_create = TRUE;
|
|
||||||
|
|
||||||
try_exec:
|
|
||||||
if (sqlite3_exec (db, sql, callback, argument, &error)) {
|
|
||||||
if (try_create) {
|
|
||||||
try_create = FALSE;
|
|
||||||
try_create_table (db);
|
|
||||||
sqlite3_free (error);
|
|
||||||
error = NULL;
|
|
||||||
goto try_exec;
|
|
||||||
} else {
|
|
||||||
g_warning ("Failed to execute query: %s", error);
|
|
||||||
sqlite3_free (error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
callback (void *data, int argc, char **argv, char **colname)
|
|
||||||
{
|
|
||||||
SoupCookie *cookie = NULL;
|
|
||||||
SoupCookieJar *jar = SOUP_COOKIE_JAR (data);
|
|
||||||
|
|
||||||
char *name, *value, *host, *path;
|
|
||||||
gint64 expire_time;
|
|
||||||
time_t now;
|
|
||||||
int max_age;
|
|
||||||
gboolean http_only = FALSE, secure = FALSE;
|
|
||||||
|
|
||||||
now = time (NULL);
|
|
||||||
|
|
||||||
name = argv[COL_NAME];
|
|
||||||
value = argv[COL_VALUE];
|
|
||||||
host = argv[COL_HOST];
|
|
||||||
path = argv[COL_PATH];
|
|
||||||
expire_time = g_ascii_strtoull (argv[COL_EXPIRY], NULL, 10);
|
|
||||||
|
|
||||||
if (now >= expire_time)
|
|
||||||
return 0;
|
|
||||||
max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
|
|
||||||
|
|
||||||
http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0);
|
|
||||||
secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0);
|
|
||||||
|
|
||||||
cookie = soup_cookie_new (name, value, host, path, max_age);
|
|
||||||
|
|
||||||
if (secure)
|
|
||||||
soup_cookie_set_secure (cookie, TRUE);
|
|
||||||
if (http_only)
|
|
||||||
soup_cookie_set_http_only (cookie, TRUE);
|
|
||||||
|
|
||||||
soup_cookie_jar_add_cookie (jar, cookie);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Follows sqlite3 convention; returns TRUE on error */
|
/* Follows sqlite3 convention; returns TRUE on error */
|
||||||
static gboolean
|
static gboolean
|
||||||
katze_http_cookies_sqlite_open_db (KatzeHttpCookiesSqlite* http_cookies)
|
katze_http_cookies_sqlite_open_db (KatzeHttpCookiesSqlite* http_cookies)
|
||||||
|
@ -157,23 +83,91 @@ katze_http_cookies_sqlite_open_db (KatzeHttpCookiesSqlite* http_cookies)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sqlite3_exec (http_cookies->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) {
|
if (sqlite3_exec (http_cookies->db, CREATE_TABLE, NULL, NULL, &error)) {
|
||||||
g_warning ("Failed to execute query: %s", error);
|
g_warning ("Failed to execute query: %s", error);
|
||||||
sqlite3_free (error);
|
sqlite3_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sqlite3_exec (http_cookies->db, "PRAGMA secure_delete = 1;",
|
||||||
|
NULL, NULL, &error)) {
|
||||||
|
g_warning ("Failed to execute query: %s", error);
|
||||||
|
sqlite3_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_exec (http_cookies->db,
|
||||||
|
/* Arguably cookies are like a cache, so performance over integrity */
|
||||||
|
"PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;"
|
||||||
|
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
|
||||||
|
NULL, NULL, &error);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
katze_http_cookies_sqlite_load (KatzeHttpCookiesSqlite* http_cookies)
|
katze_http_cookies_sqlite_load (KatzeHttpCookiesSqlite* http_cookies)
|
||||||
{
|
{
|
||||||
|
const char *name, *value, *host, *path;
|
||||||
|
sqlite3_stmt* stmt;
|
||||||
|
SoupCookie *cookie = NULL;
|
||||||
|
gint64 expire_time;
|
||||||
|
time_t now;
|
||||||
|
int max_age;
|
||||||
|
gboolean http_only = FALSE, secure = FALSE;
|
||||||
|
char *query;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (http_cookies->db == NULL) {
|
if (http_cookies->db == NULL) {
|
||||||
if (katze_http_cookies_sqlite_open_db (http_cookies))
|
if (katze_http_cookies_sqlite_open_db (http_cookies))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exec_query_with_try_create_table (http_cookies->db, QUERY_ALL, callback, http_cookies->jar);
|
sqlite3_prepare_v2 (http_cookies->db, QUERY_ALL, strlen (QUERY_ALL) + 1, &stmt, NULL);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
if (result != SQLITE_ROW)
|
||||||
|
{
|
||||||
|
if (result == SQLITE_ERROR)
|
||||||
|
g_print (_("Failed to load cookies\n"));
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (result == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
now = time (NULL);
|
||||||
|
name = (const char*)sqlite3_column_text (stmt, COL_NAME);
|
||||||
|
value = (const char*)sqlite3_column_text (stmt, COL_VALUE);
|
||||||
|
host = (const char*)sqlite3_column_text (stmt, COL_HOST);
|
||||||
|
path = (const char*)sqlite3_column_text (stmt, COL_PATH);
|
||||||
|
expire_time = sqlite3_column_int64 (stmt,COL_EXPIRY);
|
||||||
|
secure = sqlite3_column_int (stmt, COL_SECURE);
|
||||||
|
http_only = sqlite3_column_int (stmt, COL_HTTP_ONLY);
|
||||||
|
|
||||||
|
if (now >= expire_time)
|
||||||
|
{
|
||||||
|
/* Cookie expired, remove it from database */
|
||||||
|
query = sqlite3_mprintf (QUERY_DELETE, name, host);
|
||||||
|
sqlite3_exec (http_cookies->db, QUERY_DELETE, NULL, NULL, NULL);
|
||||||
|
sqlite3_free (query);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
|
||||||
|
cookie = soup_cookie_new (name, value, host, path, max_age);
|
||||||
|
|
||||||
|
if (secure)
|
||||||
|
soup_cookie_set_secure (cookie, TRUE);
|
||||||
|
if (http_only)
|
||||||
|
soup_cookie_set_http_only (cookie, TRUE);
|
||||||
|
|
||||||
|
soup_cookie_jar_add_cookie (http_cookies->jar, cookie);
|
||||||
|
result = sqlite3_step (stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stmt)
|
||||||
|
{
|
||||||
|
sqlite3_reset (stmt);
|
||||||
|
sqlite3_clear_bindings (stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
||||||
|
@ -220,7 +214,7 @@ katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
||||||
query = sqlite3_mprintf (QUERY_DELETE,
|
query = sqlite3_mprintf (QUERY_DELETE,
|
||||||
old_cookie->name,
|
old_cookie->name,
|
||||||
old_cookie->domain);
|
old_cookie->domain);
|
||||||
exec_query_with_try_create_table (http_cookies->db, query, NULL, NULL);
|
sqlite3_exec (http_cookies->db, query, NULL, NULL, NULL);
|
||||||
sqlite3_free (query);
|
sqlite3_free (query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +228,7 @@ katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
||||||
expires,
|
expires,
|
||||||
new_cookie->secure,
|
new_cookie->secure,
|
||||||
new_cookie->http_only);
|
new_cookie->http_only);
|
||||||
exec_query_with_try_create_table (http_cookies->db, query, NULL, NULL);
|
sqlite3_exec (http_cookies->db, query, NULL, NULL, NULL);
|
||||||
sqlite3_free (query);
|
sqlite3_free (query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,6 +315,8 @@ katze_item_set_name (KatzeItem* item,
|
||||||
g_return_if_fail (KATZE_IS_ITEM (item));
|
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||||
|
|
||||||
katze_assign (item->name, g_strdup (name));
|
katze_assign (item->name, g_strdup (name));
|
||||||
|
if (item->parent)
|
||||||
|
katze_array_update ((KatzeArray*)item->parent);
|
||||||
g_object_notify (G_OBJECT (item), "name");
|
g_object_notify (G_OBJECT (item), "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,9 +416,51 @@ katze_item_set_icon (KatzeItem* item,
|
||||||
g_return_if_fail (KATZE_IS_ITEM (item));
|
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||||
|
|
||||||
katze_item_set_meta_string (item, "icon", icon);
|
katze_item_set_meta_string (item, "icon", icon);
|
||||||
|
if (item->parent)
|
||||||
|
katze_array_update ((KatzeArray*)item->parent);
|
||||||
g_object_notify (G_OBJECT (item), "icon");
|
g_object_notify (G_OBJECT (item), "icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* katze_item_get_image:
|
||||||
|
* @item: a #KatzeItem
|
||||||
|
*
|
||||||
|
* Retrieves a #GtkImage fit to display @item.
|
||||||
|
*
|
||||||
|
* Return value: the icon of the item
|
||||||
|
*
|
||||||
|
* Since: 0.4.4
|
||||||
|
**/
|
||||||
|
GtkWidget*
|
||||||
|
katze_item_get_image (KatzeItem* item)
|
||||||
|
{
|
||||||
|
GtkWidget* image;
|
||||||
|
GdkPixbuf* pixbuf;
|
||||||
|
const gchar* icon;
|
||||||
|
|
||||||
|
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||||
|
|
||||||
|
if (KATZE_ITEM_IS_FOLDER (item))
|
||||||
|
image = gtk_image_new_from_stock (GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
|
||||||
|
else if ((pixbuf = g_object_get_data (G_OBJECT (item), "pixbuf")))
|
||||||
|
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||||
|
else if ((icon = katze_item_get_icon (item)) && !strchr (icon, '/'))
|
||||||
|
image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(icon && (pixbuf = katze_load_cached_icon (icon, NULL))))
|
||||||
|
pixbuf = katze_load_cached_icon (item->uri, NULL);
|
||||||
|
if (pixbuf)
|
||||||
|
{
|
||||||
|
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
image = gtk_image_new_from_stock (GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* katze_item_get_token:
|
* katze_item_get_token:
|
||||||
* @item: a #KatzeItem
|
* @item: a #KatzeItem
|
||||||
|
@ -527,17 +571,22 @@ katze_item_set_meta_data_value (KatzeItem* item,
|
||||||
* Return value: a string, or %NULL
|
* Return value: a string, or %NULL
|
||||||
*
|
*
|
||||||
* Since: 0.1.8
|
* Since: 0.1.8
|
||||||
|
*
|
||||||
|
* Since 0.4.4 "" is treated like %NULL.
|
||||||
**/
|
**/
|
||||||
const gchar*
|
const gchar*
|
||||||
katze_item_get_meta_string (KatzeItem* item,
|
katze_item_get_meta_string (KatzeItem* item,
|
||||||
const gchar* key)
|
const gchar* key)
|
||||||
{
|
{
|
||||||
|
const gchar* value;
|
||||||
|
|
||||||
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||||
g_return_val_if_fail (key != NULL, NULL);
|
g_return_val_if_fail (key != NULL, NULL);
|
||||||
|
|
||||||
if (g_str_has_prefix (key, "midori:"))
|
if (g_str_has_prefix (key, "midori:"))
|
||||||
key = &key[7];
|
key = &key[7];
|
||||||
return g_hash_table_lookup (item->metadata, key);
|
value = g_hash_table_lookup (item->metadata, key);
|
||||||
|
return value && *value ? value : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#ifndef __KATZE_ITEM_H__
|
#ifndef __KATZE_ITEM_H__
|
||||||
#define __KATZE_ITEM_H__
|
#define __KATZE_ITEM_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -91,6 +91,9 @@ void
|
||||||
katze_item_set_icon (KatzeItem* item,
|
katze_item_set_icon (KatzeItem* item,
|
||||||
const gchar* icon);
|
const gchar* icon);
|
||||||
|
|
||||||
|
GtkWidget*
|
||||||
|
katze_item_get_image (KatzeItem* item);
|
||||||
|
|
||||||
const gchar*
|
const gchar*
|
||||||
katze_item_get_token (KatzeItem* item);
|
katze_item_get_token (KatzeItem* item);
|
||||||
|
|
||||||
|
|
|
@ -97,8 +97,8 @@ katze_throbber_realize (GtkWidget* widget);
|
||||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
static void
|
static void
|
||||||
katze_throbber_get_preferred_height (GtkWidget *widget,
|
katze_throbber_get_preferred_height (GtkWidget *widget,
|
||||||
gint *minimal_width,
|
gint *minimal_height,
|
||||||
gint *natural_width);
|
gint *natural_height);
|
||||||
static void
|
static void
|
||||||
katze_throbber_get_preferred_width (GtkWidget *widget,
|
katze_throbber_get_preferred_width (GtkWidget *widget,
|
||||||
gint *minimal_width,
|
gint *minimal_width,
|
||||||
|
@ -495,8 +495,8 @@ katze_throbber_set_animated (KatzeThrobber* throbber,
|
||||||
(GSourceFunc)katze_throbber_timeout,
|
(GSourceFunc)katze_throbber_timeout,
|
||||||
throbber,
|
throbber,
|
||||||
(GDestroyNotify)katze_throbber_timeout_destroy);
|
(GDestroyNotify)katze_throbber_timeout_destroy);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (throbber));
|
|
||||||
#endif
|
#endif
|
||||||
|
gtk_widget_queue_draw (GTK_WIDGET (throbber));
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (throbber), "animated");
|
g_object_notify (G_OBJECT (throbber), "animated");
|
||||||
}
|
}
|
||||||
|
@ -857,14 +857,14 @@ katze_throbber_size_request (GtkWidget* widget,
|
||||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
static void
|
static void
|
||||||
katze_throbber_get_preferred_height (GtkWidget *widget,
|
katze_throbber_get_preferred_height (GtkWidget *widget,
|
||||||
gint *minimal_width,
|
gint *minimal_height,
|
||||||
gint *natural_width)
|
gint *natural_height)
|
||||||
{
|
{
|
||||||
GtkRequisition requisition;
|
GtkRequisition requisition;
|
||||||
|
|
||||||
katze_throbber_size_request (widget, &requisition);
|
katze_throbber_size_request (widget, &requisition);
|
||||||
|
|
||||||
*minimal_width = *natural_width = requisition.height;
|
*minimal_height = *natural_height = requisition.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -902,6 +902,7 @@ katze_throbber_aligned_coords (GtkWidget* widget,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
allocation.x = allocation.y = 0;
|
||||||
allocation.width = gtk_widget_get_allocated_width (widget);
|
allocation.width = gtk_widget_get_allocated_width (widget);
|
||||||
allocation.height = gtk_widget_get_allocated_height (widget);
|
allocation.height = gtk_widget_get_allocated_height (widget);
|
||||||
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
||||||
|
|
|
@ -910,21 +910,29 @@ katze_widget_popup_position_menu (GtkMenu* menu,
|
||||||
GtkRequisition widget_req;
|
GtkRequisition widget_req;
|
||||||
KatzePopupInfo* info = user_data;
|
KatzePopupInfo* info = user_data;
|
||||||
GtkWidget* widget = info->widget;
|
GtkWidget* widget = info->widget;
|
||||||
|
GdkWindow* window = gtk_widget_get_window (widget);
|
||||||
gint widget_height;
|
gint widget_height;
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
if (GTK_IS_ENTRY (widget))
|
||||||
|
window = gdk_window_get_parent (window);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Retrieve size and position of both widget and menu */
|
/* Retrieve size and position of both widget and menu */
|
||||||
if (!gtk_widget_get_has_window (widget))
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
{
|
gdk_window_get_origin (window, &wx, &wy);
|
||||||
gdk_window_get_position (gtk_widget_get_window (widget), &wx, &wy);
|
|
||||||
wx += allocation.x;
|
wx += allocation.x;
|
||||||
wy += allocation.y;
|
wy += allocation.y;
|
||||||
}
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
else
|
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
|
||||||
gdk_window_get_origin (gtk_widget_get_window (widget), &wx, &wy);
|
gtk_widget_get_preferred_size (widget, &widget_req, NULL);
|
||||||
|
#else
|
||||||
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
|
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
|
||||||
gtk_widget_size_request (widget, &widget_req);
|
gtk_widget_size_request (widget, &widget_req);
|
||||||
|
#endif
|
||||||
menu_width = menu_req.width;
|
menu_width = menu_req.width;
|
||||||
widget_height = widget_req.height; /* Better than allocation.height */
|
widget_height = widget_req.height; /* Better than allocation.height */
|
||||||
|
|
||||||
|
@ -1190,6 +1198,16 @@ katze_strip_mnemonics (const gchar* original)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gchar*
|
||||||
|
katze_skip_whitespace (const gchar* str)
|
||||||
|
{
|
||||||
|
if (str == NULL)
|
||||||
|
return NULL;
|
||||||
|
while (*str == ' ' || *str == '\t' || *str == '\n')
|
||||||
|
str++;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* katze_object_has_property:
|
* katze_object_has_property:
|
||||||
* @object: a #GObject
|
* @object: a #GObject
|
||||||
|
@ -1520,6 +1538,8 @@ katze_uri_entry_changed_cb (GtkWidget* entry,
|
||||||
{
|
{
|
||||||
const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry));
|
const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||||
gboolean valid = midori_uri_is_location (uri);
|
gboolean valid = midori_uri_is_location (uri);
|
||||||
|
if (!valid && g_object_get_data (G_OBJECT (entry), "allow_%s"))
|
||||||
|
valid = uri && g_str_has_prefix (uri, "%s");
|
||||||
if (*uri && !valid)
|
if (*uri && !valid)
|
||||||
{
|
{
|
||||||
GdkColor bg_color = { 0 };
|
GdkColor bg_color = { 0 };
|
||||||
|
|
|
@ -58,6 +58,20 @@ G_BEGIN_DECLS
|
||||||
**/
|
**/
|
||||||
#define katze_strv_assign(lvalue, rvalue) lvalue = (g_strfreev (lvalue), rvalue)
|
#define katze_strv_assign(lvalue, rvalue) lvalue = (g_strfreev (lvalue), rvalue)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* katze_str_non_null:
|
||||||
|
* @str: a string, or %NULL
|
||||||
|
*
|
||||||
|
* Returns "" if @str is %NULL.
|
||||||
|
*
|
||||||
|
* Since: 0.4.4
|
||||||
|
**/
|
||||||
|
static inline const gchar*
|
||||||
|
katze_str_non_null (const gchar* str)
|
||||||
|
{
|
||||||
|
return str ? str : "";
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget*
|
GtkWidget*
|
||||||
katze_property_proxy (gpointer object,
|
katze_property_proxy (gpointer object,
|
||||||
const gchar* property,
|
const gchar* property,
|
||||||
|
@ -101,6 +115,9 @@ katze_bookmark_populate_tree_view (KatzeArray* array,
|
||||||
gchar*
|
gchar*
|
||||||
katze_strip_mnemonics (const gchar* original);
|
katze_strip_mnemonics (const gchar* original);
|
||||||
|
|
||||||
|
const gchar*
|
||||||
|
katze_skip_whitespace (const gchar* str);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
katze_object_has_property (gpointer object,
|
katze_object_has_property (gpointer object,
|
||||||
const gchar* property);
|
const gchar* property);
|
||||||
|
|
|
@ -85,6 +85,9 @@ namespace Midori {
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
return keywords;
|
return keywords;
|
||||||
string escaped = GLib.Uri.escape_string (keywords, ":/", true);
|
string escaped = GLib.Uri.escape_string (keywords, ":/", true);
|
||||||
|
/* Allow DuckDuckGo to distinguish Midori and in turn share revenue */
|
||||||
|
if (uri == "https://duckduckgo.com/?q=%s")
|
||||||
|
return "https://duckduckgo.com/?q=%s&t=midori".printf (escaped);
|
||||||
if (uri.str ("%s") != null)
|
if (uri.str ("%s") != null)
|
||||||
return uri.printf (escaped);
|
return uri.printf (escaped);
|
||||||
return uri + escaped;
|
return uri + escaped;
|
||||||
|
@ -122,8 +125,17 @@ namespace Midori {
|
||||||
FIXME: Schemes are not handled
|
FIXME: Schemes are not handled
|
||||||
hostname_is_ip_address () is not used because
|
hostname_is_ip_address () is not used because
|
||||||
we'd have to separate the path from the URI first. */
|
we'd have to separate the path from the URI first. */
|
||||||
return uri != null && uri[0].isdigit ()
|
if (uri == null)
|
||||||
&& (uri.chr (4, '.') != null || uri.chr (4, ':') != null);
|
return false;
|
||||||
|
/* IPv4 */
|
||||||
|
if (uri[0].isdigit () && (uri.chr (4, '.') != null))
|
||||||
|
return true;
|
||||||
|
/* IPv6 */
|
||||||
|
if (uri[0].isalnum () && uri[1].isalnum ()
|
||||||
|
&& uri[2].isalnum () && uri[3].isalnum () && uri[4] == ':'
|
||||||
|
&& (uri[5] == ':' || uri[5].isalnum ()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
public static bool is_valid (string? uri) {
|
public static bool is_valid (string? uri) {
|
||||||
return uri != null
|
return uri != null
|
||||||
|
|
142
midori/main.c
142
midori/main.c
|
@ -441,7 +441,10 @@ midori_history_initialize (KatzeArray* array,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_exec (db, "PRAGMA journal_mode = TRUNCATE;", NULL, NULL, errmsg);
|
sqlite3_exec (db,
|
||||||
|
/* "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY" */
|
||||||
|
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
|
||||||
|
NULL, NULL, errmsg);
|
||||||
if (*errmsg)
|
if (*errmsg)
|
||||||
{
|
{
|
||||||
g_warning ("Failed to set journal mode: %s", *errmsg);
|
g_warning ("Failed to set journal mode: %s", *errmsg);
|
||||||
|
@ -528,14 +531,14 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
|
||||||
"DELETE FROM bookmarks WHERE uri = '%q' "
|
"DELETE FROM bookmarks WHERE uri = '%q' "
|
||||||
" AND folder = '%q'",
|
" AND folder = '%q'",
|
||||||
katze_item_get_uri (item),
|
katze_item_get_uri (item),
|
||||||
katze_item_get_meta_string (item, "folder"));
|
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
|
||||||
|
|
||||||
else
|
else
|
||||||
sqlcmd = sqlite3_mprintf (
|
sqlcmd = sqlite3_mprintf (
|
||||||
"DELETE FROM bookmarks WHERE title = '%q'"
|
"DELETE FROM bookmarks WHERE title = '%q'"
|
||||||
" AND folder = '%q'",
|
" AND folder = '%q'",
|
||||||
katze_item_get_name (item),
|
katze_item_get_name (item),
|
||||||
katze_item_get_meta_string (item, "folder"));
|
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
|
||||||
|
|
||||||
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
|
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
|
@ -958,19 +961,22 @@ midori_soup_session_settings_accept_language_cb (SoupSession* session,
|
||||||
if (referer && destination && !strstr (referer, destination->host))
|
if (referer && destination && !strstr (referer, destination->host))
|
||||||
{
|
{
|
||||||
SoupURI* stripped_uri = soup_uri_new (referer);
|
SoupURI* stripped_uri = soup_uri_new (referer);
|
||||||
|
if (stripped_uri != NULL)
|
||||||
|
{
|
||||||
gchar* stripped_referer;
|
gchar* stripped_referer;
|
||||||
soup_uri_set_path (stripped_uri, NULL);
|
soup_uri_set_path (stripped_uri, NULL);
|
||||||
soup_uri_set_query (stripped_uri, NULL);
|
soup_uri_set_query (stripped_uri, NULL);
|
||||||
stripped_referer = soup_uri_to_string (stripped_uri, FALSE);
|
stripped_referer = soup_uri_to_string (stripped_uri, FALSE);
|
||||||
soup_uri_free (stripped_uri);
|
soup_uri_free (stripped_uri);
|
||||||
if (g_getenv ("MIDORI_SOUP_DEBUG"))
|
if (g_getenv ("MIDORI_SOUP_DEBUG"))
|
||||||
g_message ("Referer stripped");
|
g_message ("Referer %s stripped to %s", referer, stripped_referer);
|
||||||
soup_message_headers_replace (msg->request_headers, "Referer",
|
soup_message_headers_replace (msg->request_headers, "Referer",
|
||||||
stripped_referer);
|
stripped_referer);
|
||||||
g_free (stripped_referer);
|
g_free (stripped_referer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_soup_session_debug (SoupSession* session)
|
midori_soup_session_debug (SoupSession* session)
|
||||||
|
@ -1029,6 +1035,7 @@ midori_load_soup_session (gpointer settings)
|
||||||
NULL);
|
NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (session), "midori-settings", settings);
|
||||||
soup_session_settings_notify_http_proxy_cb (settings, NULL, session);
|
soup_session_settings_notify_http_proxy_cb (settings, NULL, session);
|
||||||
g_signal_connect (settings, "notify::http-proxy",
|
g_signal_connect (settings, "notify::http-proxy",
|
||||||
G_CALLBACK (soup_session_settings_notify_http_proxy_cb), session);
|
G_CALLBACK (soup_session_settings_notify_http_proxy_cb), session);
|
||||||
|
@ -1474,21 +1481,6 @@ snapshot_load_finished_cb (GtkWidget* web_view,
|
||||||
gtk_main_quit ();
|
gtk_main_quit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
midori_web_app_browser_notify_load_status_cb (MidoriBrowser* browser,
|
|
||||||
GParamSpec* pspec,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
if (katze_object_get_enum (browser, "load-status") != MIDORI_LOAD_PROVISIONAL)
|
|
||||||
{
|
|
||||||
GtkWidget* view = midori_browser_get_current_tab (browser);
|
|
||||||
GdkPixbuf* icon = midori_view_get_icon (MIDORI_VIEW (view));
|
|
||||||
if (midori_view_is_blank (MIDORI_VIEW (view)))
|
|
||||||
icon = NULL;
|
|
||||||
gtk_window_set_icon (GTK_WINDOW (browser), icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static MidoriBrowser*
|
static MidoriBrowser*
|
||||||
midori_web_app_browser_new_window_cb (MidoriBrowser* browser,
|
midori_web_app_browser_new_window_cb (MidoriBrowser* browser,
|
||||||
MidoriBrowser* new_browser,
|
MidoriBrowser* new_browser,
|
||||||
|
@ -1521,9 +1513,7 @@ midori_prepare_uri (const gchar *uri)
|
||||||
{
|
{
|
||||||
gchar* uri_ready;
|
gchar* uri_ready;
|
||||||
|
|
||||||
if (g_path_is_absolute (uri))
|
if (g_str_has_prefix(uri, "javascript:"))
|
||||||
return g_filename_to_uri (uri, NULL, NULL);
|
|
||||||
else if (g_str_has_prefix(uri, "javascript:"))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
else if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
||||||
{
|
{
|
||||||
|
@ -1729,31 +1719,24 @@ midori_setup_inactivity_reset (MidoriBrowser* browser,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
midori_clear_page_icons_cb (void)
|
|
||||||
{
|
|
||||||
gchar* cache = g_build_filename (g_get_user_cache_dir (),
|
|
||||||
PACKAGE_NAME, "icons", NULL);
|
|
||||||
sokoke_remove_path (cache, TRUE);
|
|
||||||
g_free (cache);
|
|
||||||
cache = g_build_filename (g_get_user_data_dir (),
|
|
||||||
"webkit", "icondatabase", NULL);
|
|
||||||
sokoke_remove_path (cache, TRUE);
|
|
||||||
g_free (cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_clear_web_cookies_cb (void)
|
midori_clear_web_cookies_cb (void)
|
||||||
{
|
{
|
||||||
SoupSession* session = webkit_get_default_session ();
|
SoupSession* session = webkit_get_default_session ();
|
||||||
|
MidoriWebSettings* settings = g_object_get_data (G_OBJECT (session), "midori-settings");
|
||||||
SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
|
SoupSessionFeature* jar = soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR);
|
||||||
GSList* cookies = soup_cookie_jar_all_cookies (SOUP_COOKIE_JAR (jar));
|
GSList* cookies = soup_cookie_jar_all_cookies (SOUP_COOKIE_JAR (jar));
|
||||||
SoupSessionFeature* feature;
|
SoupSessionFeature* feature;
|
||||||
|
gchar* cache;
|
||||||
|
|
||||||
|
/* HTTP Cookies/ Web Cookies */
|
||||||
for (; cookies != NULL; cookies = g_slist_next (cookies))
|
for (; cookies != NULL; cookies = g_slist_next (cookies))
|
||||||
{
|
{
|
||||||
SoupCookie* cookie = cookies->data;
|
const gchar* domain = ((SoupCookie*)cookies->data)->domain;
|
||||||
soup_cookie_jar_delete_cookie ((SoupCookieJar*)jar, cookie);
|
if (midori_web_settings_get_site_data_policy (settings, domain)
|
||||||
|
== MIDORI_SITE_DATA_PRESERVE)
|
||||||
|
continue;
|
||||||
|
soup_cookie_jar_delete_cookie ((SoupCookieJar*)jar, cookies->data);
|
||||||
}
|
}
|
||||||
soup_cookies_free (cookies);
|
soup_cookies_free (cookies);
|
||||||
/* Removing KatzeHttpCookies makes it save outstanding changes */
|
/* Removing KatzeHttpCookies makes it save outstanding changes */
|
||||||
|
@ -1764,18 +1747,36 @@ midori_clear_web_cookies_cb (void)
|
||||||
soup_session_add_feature (session, feature);
|
soup_session_add_feature (session, feature);
|
||||||
g_object_unref (feature);
|
g_object_unref (feature);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
/* Local shared objects/ Flash cookies */
|
||||||
static void
|
if (midori_web_settings_has_plugin_support ())
|
||||||
midori_clear_flash_cookies_cb (void)
|
|
||||||
{
|
{
|
||||||
gchar* cache = g_build_filename (g_get_home_dir (), ".macromedia",
|
#ifdef GDK_WINDOWING_X11
|
||||||
"Flash_Player", NULL);
|
cache = g_build_filename (g_get_home_dir (), ".macromedia", "Flash_Player", NULL);
|
||||||
|
sokoke_remove_path (cache, TRUE);
|
||||||
|
g_free (cache);
|
||||||
|
#elif defined(GDK_WINDOWING_WIN32)
|
||||||
|
cache = g_build_filename (g_get_user_data_dir (), "Macromedia", "Flash Player", NULL);
|
||||||
|
sokoke_remove_path (cache, TRUE);
|
||||||
|
g_free (cache);
|
||||||
|
#elif defined(GDK_WINDOWING_QUARTZ)
|
||||||
|
cache = g_build_filename (g_get_home_dir (), "Library", "Preferences",
|
||||||
|
"Macromedia", "Flash Player", NULL);
|
||||||
sokoke_remove_path (cache, TRUE);
|
sokoke_remove_path (cache, TRUE);
|
||||||
g_free (cache);
|
g_free (cache);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 databases */
|
||||||
|
webkit_remove_all_web_databases ();
|
||||||
|
|
||||||
|
/* HTML5 offline application caches */
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 3, 13)
|
||||||
|
/* Changing the size implies clearing the cache */
|
||||||
|
webkit_application_cache_set_maximum_size (
|
||||||
|
webkit_application_cache_get_maximum_size () - 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_clear_saved_logins_cb (void)
|
midori_clear_saved_logins_cb (void)
|
||||||
|
@ -1794,35 +1795,33 @@ midori_clear_saved_logins_cb (void)
|
||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
midori_clear_html5_databases_cb (void)
|
|
||||||
{
|
|
||||||
webkit_remove_all_web_databases ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WEBKIT_CHECK_VERSION (1, 3, 11)
|
#if WEBKIT_CHECK_VERSION (1, 3, 11)
|
||||||
static void
|
static void
|
||||||
midori_clear_web_cache_cb (void)
|
midori_clear_web_cache_cb (void)
|
||||||
{
|
{
|
||||||
SoupSession* session = webkit_get_default_session ();
|
SoupSession* session = webkit_get_default_session ();
|
||||||
SoupSessionFeature* feature = soup_session_get_feature (session, SOUP_TYPE_CACHE);
|
SoupSessionFeature* feature = soup_session_get_feature (session, SOUP_TYPE_CACHE);
|
||||||
gchar* path = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME, "web", NULL);
|
gchar* cache = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME, "web", NULL);
|
||||||
soup_cache_clear (SOUP_CACHE (feature));
|
soup_cache_clear (SOUP_CACHE (feature));
|
||||||
soup_cache_flush (SOUP_CACHE (feature));
|
soup_cache_flush (SOUP_CACHE (feature));
|
||||||
sokoke_remove_path (path, TRUE);
|
sokoke_remove_path (cache, TRUE);
|
||||||
g_free (path);
|
g_free (cache);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WEBKIT_CHECK_VERSION (1, 3, 13)
|
|
||||||
static void
|
static void
|
||||||
midori_clear_offline_appcache_cb (void)
|
midori_clear_page_icons_cb (void)
|
||||||
{
|
{
|
||||||
/* Changing the size implies clearing the cache */
|
gchar* cache = g_build_filename (g_get_user_cache_dir (),
|
||||||
unsigned long long maximum = webkit_application_cache_get_maximum_size ();
|
PACKAGE_NAME, "icons", NULL);
|
||||||
webkit_application_cache_set_maximum_size (maximum - 1);
|
/* FIXME: Exclude search engine icons */
|
||||||
|
sokoke_remove_path (cache, TRUE);
|
||||||
|
g_free (cache);
|
||||||
|
cache = g_build_filename (g_get_user_data_dir (),
|
||||||
|
"webkit", "icondatabase", NULL);
|
||||||
|
sokoke_remove_path (cache, TRUE);
|
||||||
|
g_free (cache);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_log_to_file (const gchar* log_domain,
|
midori_log_to_file (const gchar* log_domain,
|
||||||
|
@ -2009,6 +2008,9 @@ main (int argc,
|
||||||
else
|
else
|
||||||
g_set_application_name (_("Midori"));
|
g_set_application_name (_("Midori"));
|
||||||
|
|
||||||
|
/* Versioned prgname to override menuproxy blacklist */
|
||||||
|
g_set_prgname (PACKAGE_NAME "4");
|
||||||
|
|
||||||
if (version)
|
if (version)
|
||||||
{
|
{
|
||||||
g_print (
|
g_print (
|
||||||
|
@ -2104,34 +2106,24 @@ main (int argc,
|
||||||
g_log_set_default_handler (midori_log_to_file, (gpointer)logfile);
|
g_log_set_default_handler (midori_log_to_file, (gpointer)logfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
sokoke_register_privacy_item ("page-icons", _("Website icons"),
|
|
||||||
G_CALLBACK (midori_clear_page_icons_cb));
|
|
||||||
/* i18n: Logins and passwords in websites and web forms */
|
/* i18n: Logins and passwords in websites and web forms */
|
||||||
sokoke_register_privacy_item ("formhistory", _("Saved logins and _passwords"),
|
sokoke_register_privacy_item ("formhistory", _("Saved logins and _passwords"),
|
||||||
G_CALLBACK (midori_clear_saved_logins_cb));
|
G_CALLBACK (midori_clear_saved_logins_cb));
|
||||||
sokoke_register_privacy_item ("web-cookies", _("Cookies"),
|
sokoke_register_privacy_item ("web-cookies", _("Cookies and Website data"),
|
||||||
G_CALLBACK (midori_clear_web_cookies_cb));
|
G_CALLBACK (midori_clear_web_cookies_cb));
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
sokoke_register_privacy_item ("flash-cookies", _("'Flash' Cookies"),
|
|
||||||
G_CALLBACK (midori_clear_flash_cookies_cb));
|
|
||||||
#endif
|
|
||||||
sokoke_register_privacy_item ("html5-databases", _("HTML5 _Databases"),
|
|
||||||
G_CALLBACK (midori_clear_html5_databases_cb));
|
|
||||||
#if WEBKIT_CHECK_VERSION (1, 3, 11)
|
#if WEBKIT_CHECK_VERSION (1, 3, 11)
|
||||||
|
/* TODO: Preserve page icons of search engines and merge privacy items */
|
||||||
sokoke_register_privacy_item ("web-cache", _("Web Cache"),
|
sokoke_register_privacy_item ("web-cache", _("Web Cache"),
|
||||||
G_CALLBACK (midori_clear_web_cache_cb));
|
G_CALLBACK (midori_clear_web_cache_cb));
|
||||||
sokoke_register_privacy_item ("offline-appcache", _("Offline Application Cache"),
|
|
||||||
G_CALLBACK (midori_clear_offline_appcache_cb));
|
|
||||||
#endif
|
#endif
|
||||||
|
sokoke_register_privacy_item ("page-icons", _("Website icons"),
|
||||||
|
G_CALLBACK (midori_clear_page_icons_cb));
|
||||||
|
|
||||||
/* Web Application or Private Browsing support */
|
/* Web Application or Private Browsing support */
|
||||||
if (webapp || private || run)
|
if (webapp || private || run)
|
||||||
{
|
{
|
||||||
SoupSession* session = webkit_get_default_session ();
|
SoupSession* session = webkit_get_default_session ();
|
||||||
MidoriBrowser* browser = midori_browser_new ();
|
MidoriBrowser* browser = midori_browser_new ();
|
||||||
/* Update window icon according to page */
|
|
||||||
g_signal_connect (browser, "notify::load-status",
|
|
||||||
G_CALLBACK (midori_web_app_browser_notify_load_status_cb), NULL);
|
|
||||||
g_signal_connect (browser, "new-window",
|
g_signal_connect (browser, "new-window",
|
||||||
G_CALLBACK (midori_web_app_browser_new_window_cb), NULL);
|
G_CALLBACK (midori_web_app_browser_new_window_cb), NULL);
|
||||||
g_object_set_data (G_OBJECT (webkit_get_default_session ()),
|
g_object_set_data (G_OBJECT (webkit_get_default_session ()),
|
||||||
|
@ -2283,6 +2275,10 @@ main (int argc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Informative text for private browsing unless we have a URI */
|
||||||
|
if (private && webapp == NULL && uris == NULL)
|
||||||
|
midori_browser_add_uri (browser, "about:private");
|
||||||
|
|
||||||
if (midori_browser_get_current_uri (browser) == NULL)
|
if (midori_browser_get_current_uri (browser) == NULL)
|
||||||
midori_browser_add_uri (browser, "about:blank");
|
midori_browser_add_uri (browser, "about:blank");
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ struct _MidoriApp
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
MidoriBrowser* browser;
|
MidoriBrowser* browser;
|
||||||
GtkAccelGroup* accel_group;
|
|
||||||
|
|
||||||
gchar* name;
|
gchar* name;
|
||||||
MidoriWebSettings* settings;
|
MidoriWebSettings* settings;
|
||||||
|
@ -216,7 +215,6 @@ _midori_app_add_browser (MidoriApp* app,
|
||||||
g_return_if_fail (MIDORI_IS_APP (app));
|
g_return_if_fail (MIDORI_IS_APP (app));
|
||||||
g_return_if_fail (MIDORI_IS_BROWSER (browser));
|
g_return_if_fail (MIDORI_IS_BROWSER (browser));
|
||||||
|
|
||||||
gtk_window_add_accel_group (GTK_WINDOW (browser), app->accel_group);
|
|
||||||
g_object_connect (browser,
|
g_object_connect (browser,
|
||||||
"signal::focus-in-event", midori_browser_focus_in_event_cb, app,
|
"signal::focus-in-event", midori_browser_focus_in_event_cb, app,
|
||||||
"signal::new-window", midori_browser_new_window_cb, app,
|
"signal::new-window", midori_browser_new_window_cb, app,
|
||||||
|
@ -722,12 +720,16 @@ midori_app_create_instance (MidoriApp* app)
|
||||||
|
|
||||||
if (!app->name)
|
if (!app->name)
|
||||||
{
|
{
|
||||||
|
#if HAVE_UNIQUE
|
||||||
const gchar* config = sokoke_set_config_dir (NULL);
|
const gchar* config = sokoke_set_config_dir (NULL);
|
||||||
gchar* name_hash;
|
gchar* name_hash;
|
||||||
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1);
|
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1);
|
||||||
app->name = g_strconcat ("midori", "_", name_hash, NULL);
|
app->name = g_strconcat ("midori", "_", name_hash, NULL);
|
||||||
g_free (name_hash);
|
g_free (name_hash);
|
||||||
g_object_notify (G_OBJECT (app), "name");
|
g_object_notify (G_OBJECT (app), "name");
|
||||||
|
#else
|
||||||
|
app->name = g_strdup (PACKAGE_NAME);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(display = gdk_display_get_default ()))
|
if (!(display = gdk_display_get_default ()))
|
||||||
|
@ -767,8 +769,6 @@ midori_app_create_instance (MidoriApp* app)
|
||||||
static void
|
static void
|
||||||
midori_app_init (MidoriApp* app)
|
midori_app_init (MidoriApp* app)
|
||||||
{
|
{
|
||||||
app->accel_group = gtk_accel_group_new ();
|
|
||||||
|
|
||||||
app->settings = NULL;
|
app->settings = NULL;
|
||||||
app->bookmarks = NULL;
|
app->bookmarks = NULL;
|
||||||
app->trash = NULL;
|
app->trash = NULL;
|
||||||
|
@ -793,8 +793,6 @@ midori_app_finalize (GObject* object)
|
||||||
{
|
{
|
||||||
MidoriApp* app = MIDORI_APP (object);
|
MidoriApp* app = MIDORI_APP (object);
|
||||||
|
|
||||||
g_object_unref (app->accel_group);
|
|
||||||
|
|
||||||
katze_assign (app->name, NULL);
|
katze_assign (app->name, NULL);
|
||||||
katze_object_assign (app->settings, NULL);
|
katze_object_assign (app->settings, NULL);
|
||||||
katze_object_assign (app->bookmarks, NULL);
|
katze_object_assign (app->bookmarks, NULL);
|
||||||
|
@ -1351,7 +1349,9 @@ midori_app_setup (gchar** argument_vector)
|
||||||
|
|
||||||
/* libSoup uses threads, therefore if WebKit is built with libSoup
|
/* libSoup uses threads, therefore if WebKit is built with libSoup
|
||||||
* or Midori is using it, we need to initialize threads. */
|
* or Midori is using it, we need to initialize threads. */
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 32, 0)
|
||||||
if (!g_thread_supported ()) g_thread_init (NULL);
|
if (!g_thread_supported ()) g_thread_init (NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLE_NLS
|
#if ENABLE_NLS
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
|
|
|
@ -1067,28 +1067,32 @@ katze_array_from_sqlite (sqlite3* db,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* midori_array_query:
|
* midori_array_query_recursive:
|
||||||
* @array: the main bookmark array
|
* @array: the main bookmark array
|
||||||
* @fields: comma separated list of fields
|
* @fields: comma separated list of fields
|
||||||
* @condition: condition, like "folder = '%q'"
|
* @condition: condition, like "folder = '%q'"
|
||||||
* @value: a value to be inserted if @condition contains %q
|
* @value: a value to be inserted if @condition contains %q
|
||||||
|
* @recursive: if %TRUE include children
|
||||||
*
|
*
|
||||||
* Stores the result in a #KatzeArray.
|
* Stores the result in a #KatzeArray.
|
||||||
*
|
*
|
||||||
* Return value: a #KatzeArray on success, %NULL otherwise
|
* Return value: a #KatzeArray on success, %NULL otherwise
|
||||||
*
|
*
|
||||||
* Since: 0.4.3
|
* Since: 0.4.4
|
||||||
**/
|
**/
|
||||||
KatzeArray*
|
KatzeArray*
|
||||||
midori_array_query (KatzeArray* bookmarks,
|
midori_array_query_recursive (KatzeArray* bookmarks,
|
||||||
const gchar* fields,
|
const gchar* fields,
|
||||||
const gchar* condition,
|
const gchar* condition,
|
||||||
const gchar* value)
|
const gchar* value,
|
||||||
|
gboolean recursive)
|
||||||
{
|
{
|
||||||
sqlite3* db;
|
sqlite3* db;
|
||||||
gchar* sqlcmd;
|
gchar* sqlcmd;
|
||||||
char* sqlcmd_value;
|
char* sqlcmd_value;
|
||||||
KatzeArray* array;
|
KatzeArray* array;
|
||||||
|
KatzeItem* item;
|
||||||
|
GList* list;
|
||||||
|
|
||||||
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
|
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
|
||||||
g_return_val_if_fail (fields, NULL);
|
g_return_val_if_fail (fields, NULL);
|
||||||
|
@ -1108,6 +1112,45 @@ midori_array_query (KatzeArray* bookmarks,
|
||||||
else
|
else
|
||||||
array = katze_array_from_sqlite (db, sqlcmd);
|
array = katze_array_from_sqlite (db, sqlcmd);
|
||||||
g_free (sqlcmd);
|
g_free (sqlcmd);
|
||||||
|
|
||||||
|
if (!recursive)
|
||||||
|
return array;
|
||||||
|
|
||||||
|
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
|
||||||
|
{
|
||||||
|
if (KATZE_ITEM_IS_FOLDER (item))
|
||||||
|
{
|
||||||
|
KatzeArray* subarray = midori_array_query_recursive (bookmarks,
|
||||||
|
fields, "folder='%q'", item->name, TRUE);
|
||||||
|
katze_item_set_name (KATZE_ITEM (subarray), item->name);
|
||||||
|
katze_array_add_item (array, subarray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_list_free (list);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* midori_array_query:
|
||||||
|
* @array: the main bookmark array
|
||||||
|
* @fields: comma separated list of fields
|
||||||
|
* @condition: condition, like "folder = '%q'"
|
||||||
|
* @value: a value to be inserted if @condition contains %q
|
||||||
|
*
|
||||||
|
* Stores the result in a #KatzeArray.
|
||||||
|
*
|
||||||
|
* Return value: a #KatzeArray on success, %NULL otherwise
|
||||||
|
*
|
||||||
|
* Since: 0.4.3
|
||||||
|
*
|
||||||
|
* Deprecated: 0.4.4: Use midori_array_query_recursive() instead.
|
||||||
|
**/
|
||||||
|
KatzeArray*
|
||||||
|
midori_array_query (KatzeArray* bookmarks,
|
||||||
|
const gchar* fields,
|
||||||
|
const gchar* condition,
|
||||||
|
const gchar* value)
|
||||||
|
{
|
||||||
|
return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,13 @@ midori_array_query (KatzeArray* array,
|
||||||
const gchar* condition,
|
const gchar* condition,
|
||||||
const gchar* value);
|
const gchar* value);
|
||||||
|
|
||||||
|
KatzeArray*
|
||||||
|
midori_array_query_recursive (KatzeArray* array,
|
||||||
|
const gchar* fields,
|
||||||
|
const gchar* condition,
|
||||||
|
const gchar* value,
|
||||||
|
gboolean recursive);
|
||||||
|
|
||||||
KatzeArray*
|
KatzeArray*
|
||||||
katze_array_from_sqlite (sqlite3* db,
|
katze_array_from_sqlite (sqlite3* db,
|
||||||
const gchar* sqlcmd);
|
const gchar* sqlcmd);
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_HILDON_2_2
|
#ifdef HAVE_HILDON_2_2
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
#include <mce/mode-names.h>
|
#include <mce/mode-names.h>
|
||||||
|
@ -65,7 +61,6 @@ struct _MidoriBrowser
|
||||||
|
|
||||||
GtkActionGroup* action_group;
|
GtkActionGroup* action_group;
|
||||||
GtkWidget* menubar;
|
GtkWidget* menubar;
|
||||||
GtkWidget* menu_tools;
|
|
||||||
GtkWidget* throbber;
|
GtkWidget* throbber;
|
||||||
GtkWidget* navigationbar;
|
GtkWidget* navigationbar;
|
||||||
GtkWidget* bookmarkbar;
|
GtkWidget* bookmarkbar;
|
||||||
|
@ -177,11 +172,6 @@ midori_bookmarks_import_array_db (sqlite3* db,
|
||||||
KatzeArray* array,
|
KatzeArray* array,
|
||||||
gchar* folder);
|
gchar* folder);
|
||||||
|
|
||||||
void
|
|
||||||
midori_bookmarks_export_array_db (sqlite3* db,
|
|
||||||
KatzeArray* array,
|
|
||||||
const gchar* folder);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
midori_browser_open_bookmark (MidoriBrowser* browser,
|
midori_browser_open_bookmark (MidoriBrowser* browser,
|
||||||
KatzeItem* item);
|
KatzeItem* item);
|
||||||
|
@ -303,8 +293,7 @@ _midori_browser_update_interface (MidoriBrowser* browser)
|
||||||
_action_set_sensitive (browser, "Next",
|
_action_set_sensitive (browser, "Next",
|
||||||
midori_view_get_next_page (view) != NULL);
|
midori_view_get_next_page (view) != NULL);
|
||||||
|
|
||||||
gtk_action_set_visible (_action_by_name (browser, "AddSpeedDial"),
|
_action_set_visible (browser, "AddSpeedDial", !midori_view_is_blank (view));
|
||||||
!midori_view_is_blank (view));
|
|
||||||
_action_set_sensitive (browser, "SaveAs", midori_view_can_save (view));
|
_action_set_sensitive (browser, "SaveAs", midori_view_can_save (view));
|
||||||
_action_set_sensitive (browser, "Print", midori_view_can_print (view));
|
_action_set_sensitive (browser, "Print", midori_view_can_print (view));
|
||||||
_action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (view));
|
_action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (view));
|
||||||
|
@ -355,13 +344,13 @@ _midori_browser_update_interface (MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
midori_location_action_set_secondary_icon (
|
midori_location_action_set_secondary_icon (
|
||||||
MIDORI_LOCATION_ACTION (action), STOCK_NEWS_FEED);
|
MIDORI_LOCATION_ACTION (action), STOCK_NEWS_FEED);
|
||||||
gtk_action_set_sensitive (_action_by_name (browser, "AddNewsFeed"), TRUE);
|
_action_set_sensitive (browser, "AddNewsFeed", TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
midori_location_action_set_secondary_icon (
|
midori_location_action_set_secondary_icon (
|
||||||
MIDORI_LOCATION_ACTION (action), GTK_STOCK_JUMP_TO);
|
MIDORI_LOCATION_ACTION (action), GTK_STOCK_JUMP_TO);
|
||||||
gtk_action_set_sensitive (_action_by_name (browser, "AddNewsFeed"), FALSE);
|
_action_set_sensitive (browser, "AddNewsFeed", FALSE);
|
||||||
}
|
}
|
||||||
midori_location_action_set_security_hint (
|
midori_location_action_set_security_hint (
|
||||||
MIDORI_LOCATION_ACTION (action), midori_view_get_security (view));
|
MIDORI_LOCATION_ACTION (action), midori_view_get_security (view));
|
||||||
|
@ -484,19 +473,16 @@ midori_view_notify_icon_cb (MidoriView* view,
|
||||||
GParamSpec* pspec,
|
GParamSpec* pspec,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
const gchar* uri;
|
|
||||||
GtkAction* action;
|
GtkAction* action;
|
||||||
|
|
||||||
if (midori_browser_get_current_tab (browser) != (GtkWidget*)view)
|
if (midori_browser_get_current_tab (browser) != (GtkWidget*)view)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uri = midori_view_get_display_uri (view);
|
|
||||||
action = _action_by_name (browser, "Location");
|
action = _action_by_name (browser, "Location");
|
||||||
if (browser->maximum_history_age)
|
|
||||||
midori_location_action_set_icon_for_uri (
|
|
||||||
MIDORI_LOCATION_ACTION (action), midori_view_get_icon (view), uri);
|
|
||||||
midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
|
midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
|
||||||
midori_view_get_icon (view));
|
midori_view_get_icon (view));
|
||||||
|
if (sokoke_is_app_or_private ())
|
||||||
|
gtk_window_set_icon (GTK_WINDOW (browser), midori_view_get_icon (view));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -532,7 +518,7 @@ midori_view_notify_load_status_cb (GtkWidget* widget,
|
||||||
/* This is a hack to ensure that the address entry is focussed
|
/* This is a hack to ensure that the address entry is focussed
|
||||||
with speed dial open. */
|
with speed dial open. */
|
||||||
if (midori_view_is_blank (view))
|
if (midori_view_is_blank (view))
|
||||||
gtk_action_activate (_action_by_name (browser, "Location"));
|
midori_browser_activate_action (browser, "Location");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (browser), "load-status");
|
g_object_notify (G_OBJECT (browser), "load-status");
|
||||||
|
@ -995,14 +981,9 @@ midori_browser_prepare_download (MidoriBrowser* browser,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
|
||||||
midori_browser_save_source (const gchar* uri,
|
|
||||||
const gchar* data,
|
|
||||||
const size_t len,
|
|
||||||
const gchar* outfile);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_browser_save_uri (MidoriBrowser* browser,
|
midori_browser_save_uri (MidoriBrowser* browser,
|
||||||
|
MidoriView* view,
|
||||||
const gchar* uri)
|
const gchar* uri)
|
||||||
{
|
{
|
||||||
static gchar* last_dir = NULL;
|
static gchar* last_dir = NULL;
|
||||||
|
@ -1011,7 +992,6 @@ midori_browser_save_uri (MidoriBrowser* browser,
|
||||||
gchar* filename;
|
gchar* filename;
|
||||||
gchar* dirname;
|
gchar* dirname;
|
||||||
gchar* last_slash;
|
gchar* last_slash;
|
||||||
gchar* folder;
|
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (GTK_WIDGET (browser)))
|
if (!gtk_widget_get_visible (GTK_WIDGET (browser)))
|
||||||
return;
|
return;
|
||||||
|
@ -1049,24 +1029,11 @@ midori_browser_save_uri (MidoriBrowser* browser,
|
||||||
|
|
||||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
|
||||||
{
|
{
|
||||||
GtkWidget* view;
|
|
||||||
GtkWidget* web_view;
|
|
||||||
WebKitWebDataSource *data_source;
|
|
||||||
WebKitWebFrame *frame;
|
|
||||||
const GString *data;
|
|
||||||
|
|
||||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||||
folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
|
midori_view_save_source (view, uri, filename);
|
||||||
view = midori_browser_get_current_tab (browser);
|
|
||||||
web_view = midori_view_get_web_view (MIDORI_VIEW (view));
|
|
||||||
frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
|
|
||||||
data_source = webkit_web_frame_get_data_source (frame);
|
|
||||||
data = webkit_web_data_source_get_data (data_source);
|
|
||||||
if (data)
|
|
||||||
midori_browser_save_source (uri, data->str, data->len, filename);
|
|
||||||
|
|
||||||
g_free (last_dir);
|
katze_assign (last_dir,
|
||||||
last_dir = folder;
|
gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)));
|
||||||
}
|
}
|
||||||
gtk_widget_destroy (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
}
|
}
|
||||||
|
@ -1076,10 +1043,8 @@ midori_view_save_as_cb (GtkWidget* menuitem,
|
||||||
const gchar* uri,
|
const gchar* uri,
|
||||||
GtkWidget* view)
|
GtkWidget* view)
|
||||||
{
|
{
|
||||||
MidoriBrowser* browser;
|
MidoriBrowser* browser = midori_browser_get_for_widget (view);
|
||||||
|
midori_browser_save_uri (browser, MIDORI_VIEW (view), uri);
|
||||||
browser = midori_browser_get_for_widget (menuitem);
|
|
||||||
midori_browser_save_uri (browser, uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
static gchar*
|
||||||
|
@ -1185,7 +1150,7 @@ midori_view_activate_action_cb (GtkWidget* view,
|
||||||
const gchar* action,
|
const gchar* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
_midori_browser_activate_action (browser, action);
|
midori_browser_activate_action (browser, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1246,11 +1211,11 @@ midori_browser_view_copy_history (GtkWidget* view_to,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gboolean
|
||||||
midori_browser_notify_new_tab_timeout_cb (MidoriBrowser *browser)
|
midori_browser_notify_new_tab_timeout_cb (MidoriBrowser *browser)
|
||||||
{
|
{
|
||||||
gtk_window_set_opacity (GTK_WINDOW (browser), 1);
|
gtk_window_set_opacity (GTK_WINDOW (browser), 1);
|
||||||
return 0;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1351,20 +1316,129 @@ midori_view_download_save_as_response_cb (GtkWidget* dialog,
|
||||||
gtk_widget_hide (dialog);
|
gtk_widget_hide (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
midori_browser_download_status_cb (WebKitDownload* download,
|
||||||
|
GParamSpec* pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
const gchar* uri = webkit_download_get_destination_uri (download);
|
||||||
|
switch (webkit_download_get_status (download))
|
||||||
|
{
|
||||||
|
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
|
||||||
|
if (!g_app_info_launch_default_for_uri (uri, NULL, NULL))
|
||||||
|
{
|
||||||
|
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||||
|
_("Error opening the image!"),
|
||||||
|
_("Can not open selected image in a default viewer."), FALSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WEBKIT_DOWNLOAD_STATUS_ERROR:
|
||||||
|
webkit_download_cancel (download);
|
||||||
|
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||||
|
_("Error downloading the image!"),
|
||||||
|
_("Can not downlaod selected image."), FALSE);
|
||||||
|
break;
|
||||||
|
case WEBKIT_DOWNLOAD_STATUS_CREATED:
|
||||||
|
case WEBKIT_DOWNLOAD_STATUS_STARTED:
|
||||||
|
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
midori_browser_download_prepare_filename (gchar* filename)
|
||||||
|
{
|
||||||
|
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
const gchar* dot_pos;
|
||||||
|
const gchar* last_separator;
|
||||||
|
gchar* serial;
|
||||||
|
GString* tmp_filename;
|
||||||
|
gssize position;
|
||||||
|
|
||||||
|
last_separator = strrchr (filename, G_DIR_SEPARATOR);
|
||||||
|
dot_pos = strrchr ((last_separator) ? last_separator : filename, '.');
|
||||||
|
position = dot_pos ? (dot_pos - filename) : (gssize) strlen (filename);
|
||||||
|
tmp_filename = g_string_new (NULL);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
serial = g_strdup_printf ("-%d", i++);
|
||||||
|
g_string_assign (tmp_filename, filename);
|
||||||
|
g_string_insert (tmp_filename, position, serial);
|
||||||
|
g_free (serial);
|
||||||
|
} while (g_file_test (tmp_filename->str, G_FILE_TEST_EXISTS));
|
||||||
|
|
||||||
|
g_free (filename);
|
||||||
|
filename = g_string_free (tmp_filename, FALSE);
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar*
|
||||||
|
midori_browser_download_prepare_destination_uri (WebKitDownload* download,
|
||||||
|
const gchar* folder)
|
||||||
|
{
|
||||||
|
const gchar* suggested_filename;
|
||||||
|
GFile* file_source;
|
||||||
|
gchar* file_basename;
|
||||||
|
gchar* download_dir = NULL;
|
||||||
|
gchar* destination_uri;
|
||||||
|
gchar* destination_filename;
|
||||||
|
gchar* midori_tmp_dir;
|
||||||
|
|
||||||
|
suggested_filename = webkit_download_get_suggested_filename (download);
|
||||||
|
file_source = g_file_new_for_uri (suggested_filename);
|
||||||
|
file_basename = g_file_get_basename (file_source);
|
||||||
|
if (folder == NULL)
|
||||||
|
{
|
||||||
|
midori_tmp_dir = g_strconcat ("midori-", g_get_user_name (), NULL);
|
||||||
|
download_dir = g_build_filename (g_get_tmp_dir (), midori_tmp_dir, NULL);
|
||||||
|
g_free (midori_tmp_dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
download_dir = (gchar*)folder;
|
||||||
|
destination_filename = g_build_filename (download_dir, file_basename, NULL);
|
||||||
|
destination_filename = midori_browser_download_prepare_filename (destination_filename);
|
||||||
|
destination_uri = g_filename_to_uri (destination_filename, NULL, NULL);
|
||||||
|
|
||||||
|
if (!g_file_test (download_dir, G_FILE_TEST_EXISTS))
|
||||||
|
katze_mkdir_with_parents (download_dir, 0700);
|
||||||
|
|
||||||
|
g_free (file_basename);
|
||||||
|
if (folder == NULL)
|
||||||
|
g_free (download_dir);
|
||||||
|
g_free (destination_filename);
|
||||||
|
g_object_unref (file_source);
|
||||||
|
|
||||||
|
return destination_uri;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
midori_view_download_requested_cb (GtkWidget* view,
|
midori_view_download_requested_cb (GtkWidget* view,
|
||||||
WebKitDownload* download,
|
WebKitDownload* download,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
if (!webkit_download_get_destination_uri (download))
|
if (g_object_get_data (G_OBJECT (download), "open-in-viewer"))
|
||||||
|
{
|
||||||
|
gchar* destination_uri =
|
||||||
|
midori_browser_download_prepare_destination_uri (download, NULL);
|
||||||
|
midori_browser_prepare_download (browser, download, destination_uri);
|
||||||
|
g_signal_connect (download, "notify::status",
|
||||||
|
G_CALLBACK (midori_browser_download_status_cb), (gpointer) browser);
|
||||||
|
webkit_download_start (download);
|
||||||
|
g_free (destination_uri);
|
||||||
|
}
|
||||||
|
else if (!webkit_download_get_destination_uri (download))
|
||||||
{
|
{
|
||||||
gchar* folder;
|
|
||||||
if (g_object_get_data (G_OBJECT (download), "save-as-download"))
|
if (g_object_get_data (G_OBJECT (download), "save-as-download"))
|
||||||
{
|
{
|
||||||
static GtkWidget* dialog = NULL;
|
static GtkWidget* dialog = NULL;
|
||||||
|
|
||||||
if (!dialog)
|
if (!dialog)
|
||||||
{
|
{
|
||||||
|
gchar* folder;
|
||||||
dialog = sokoke_file_chooser_dialog_new (_("Save file"),
|
dialog = sokoke_file_chooser_dialog_new (_("Save file"),
|
||||||
GTK_WINDOW (browser), GTK_FILE_CHOOSER_ACTION_SAVE);
|
GTK_WINDOW (browser), GTK_FILE_CHOOSER_ACTION_SAVE);
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation (
|
gtk_file_chooser_set_do_overwrite_confirmation (
|
||||||
|
@ -1385,58 +1459,12 @@ midori_view_download_requested_cb (GtkWidget* view,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const gchar* suggested;
|
gchar* folder = g_object_get_data (G_OBJECT (download), "open-download")
|
||||||
gchar* basename;
|
? NULL : katze_object_get_string (browser->settings, "download-folder");
|
||||||
gchar* filename;
|
gchar* destination_uri =
|
||||||
gchar* uri;
|
midori_browser_download_prepare_destination_uri (download, folder);
|
||||||
|
midori_browser_prepare_download (browser, download, destination_uri);
|
||||||
if (g_object_get_data (G_OBJECT (download), "open-download"))
|
g_free (destination_uri);
|
||||||
folder = g_strdup (g_get_tmp_dir ());
|
|
||||||
else
|
|
||||||
folder = katze_object_get_string (browser->settings, "download-folder");
|
|
||||||
suggested = webkit_download_get_suggested_filename (download);
|
|
||||||
/* The suggested name may contain a folder name */
|
|
||||||
basename = g_path_get_basename (suggested);
|
|
||||||
filename = g_build_filename (folder, basename, NULL);
|
|
||||||
g_free (basename);
|
|
||||||
/* If the filename exists, choose a different name */
|
|
||||||
if (g_access (filename, F_OK) == 0)
|
|
||||||
{
|
|
||||||
/* Put the number in front of the extension */
|
|
||||||
gchar* extension = strrchr (filename, '.');
|
|
||||||
gsize length = extension ? (gsize)(extension - filename) : strlen (filename);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (g_ascii_isdigit (filename[length - 1]))
|
|
||||||
filename[length - 1] += 1; /* FIXME: This will increment '9' to ':' */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gchar* new_filename;
|
|
||||||
if (extension)
|
|
||||||
{
|
|
||||||
/* Change the '.' to a '\0' to put the 0 in between */
|
|
||||||
*extension++ = '\0';
|
|
||||||
new_filename= g_strconcat (filename, "0.", extension, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
new_filename = g_strconcat (filename, "0", NULL);
|
|
||||||
katze_assign (filename, new_filename);
|
|
||||||
if (extension)
|
|
||||||
{
|
|
||||||
extension = strrchr (filename, '.');
|
|
||||||
length = extension - filename;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
length = strlen (filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (g_access (filename, F_OK) == 0);
|
|
||||||
}
|
|
||||||
g_free (folder);
|
|
||||||
uri = g_filename_to_uri (filename, NULL, NULL);
|
|
||||||
g_free (filename);
|
|
||||||
midori_browser_prepare_download (browser, download, uri);
|
|
||||||
g_free (uri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1488,20 +1516,18 @@ midori_browser_notebook_resize (MidoriBrowser* browser,
|
||||||
GdkRectangle* allocation)
|
GdkRectangle* allocation)
|
||||||
{
|
{
|
||||||
gint new_size = 0;
|
gint new_size = 0;
|
||||||
gint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK(browser->notebook));
|
gint n = MAX (1, gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)));
|
||||||
const gint max_size = 150;
|
const gint max_size = 150;
|
||||||
gint min_size;
|
gint min_size;
|
||||||
gint icon_size = 16;
|
gint icon_size = 16;
|
||||||
GtkAllocation notebook_size;
|
GtkAllocation notebook_size;
|
||||||
GList* children;
|
GList* children;
|
||||||
|
|
||||||
g_return_if_fail (n > 0);
|
|
||||||
|
|
||||||
if (allocation != NULL)
|
if (allocation != NULL)
|
||||||
notebook_size.width = allocation->width;
|
notebook_size.width = allocation->width;
|
||||||
else
|
else
|
||||||
gtk_widget_get_allocation (browser->notebook, ¬ebook_size);
|
gtk_widget_get_allocation (browser->notebook, ¬ebook_size);
|
||||||
new_size = notebook_size.width / n - 7;
|
new_size = notebook_size.width / n;
|
||||||
|
|
||||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (browser->notebook),
|
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (browser->notebook),
|
||||||
GTK_ICON_SIZE_MENU, &icon_size, NULL);
|
GTK_ICON_SIZE_MENU, &icon_size, NULL);
|
||||||
|
@ -1672,14 +1698,14 @@ midori_browser_key_press_event (GtkWidget* widget,
|
||||||
&& event->keyval == GDK_KEY_Tab
|
&& event->keyval == GDK_KEY_Tab
|
||||||
&& (event->state & GDK_CONTROL_MASK))
|
&& (event->state & GDK_CONTROL_MASK))
|
||||||
{
|
{
|
||||||
gtk_action_activate (_action_by_name (browser, "TabNext"));
|
midori_browser_activate_action (browser, "TabNext");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (event->keyval == GDK_KEY_ISO_Left_Tab
|
else if (event->keyval == GDK_KEY_ISO_Left_Tab
|
||||||
&& (event->state & GDK_CONTROL_MASK)
|
&& (event->state & GDK_CONTROL_MASK)
|
||||||
&& (event->state & GDK_SHIFT_MASK))
|
&& (event->state & GDK_SHIFT_MASK))
|
||||||
{
|
{
|
||||||
gtk_action_activate (_action_by_name (browser, "TabPrevious"));
|
midori_browser_activate_action (browser, "TabPrevious");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* Interpret Ctrl+= as Zoom In for compatibility */
|
/* Interpret Ctrl+= as Zoom In for compatibility */
|
||||||
|
@ -1692,7 +1718,7 @@ midori_browser_key_press_event (GtkWidget* widget,
|
||||||
/* Interpret F5 as reloading for compatibility */
|
/* Interpret F5 as reloading for compatibility */
|
||||||
else if (event->keyval == GDK_KEY_F5)
|
else if (event->keyval == GDK_KEY_F5)
|
||||||
{
|
{
|
||||||
gtk_action_activate (_action_by_name (browser, "Reload"));
|
midori_browser_activate_action (browser, "Reload");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1741,12 +1767,12 @@ midori_browser_key_press_event (GtkWidget* widget,
|
||||||
if ((event->keyval == GDK_KEY_BackSpace)
|
if ((event->keyval == GDK_KEY_BackSpace)
|
||||||
&& (event->state & GDK_SHIFT_MASK))
|
&& (event->state & GDK_SHIFT_MASK))
|
||||||
{
|
{
|
||||||
gtk_action_activate (_action_by_name (browser, "Forward"));
|
midori_browser_activate_action (browser, "Forward");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (event->keyval == GDK_KEY_BackSpace)
|
else if (event->keyval == GDK_KEY_BackSpace)
|
||||||
{
|
{
|
||||||
gtk_action_activate (_action_by_name (browser, "Back"));
|
midori_browser_activate_action (browser, "Back");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2246,8 +2272,7 @@ static void
|
||||||
_action_private_browsing_activate (GtkAction* action,
|
_action_private_browsing_activate (GtkAction* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
const gchar* uri = midori_browser_get_current_uri (browser);
|
sokoke_spawn_app ("about:private", TRUE);
|
||||||
sokoke_spawn_app (uri && *uri ? uri : "about:blank", TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2313,7 +2338,8 @@ static void
|
||||||
_action_save_as_activate (GtkAction* action,
|
_action_save_as_activate (GtkAction* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
midori_browser_save_uri (browser, midori_browser_get_current_uri (browser));
|
GtkWidget* view = midori_browser_get_current_tab (browser);
|
||||||
|
midori_browser_save_uri (browser, MIDORI_VIEW (view), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2597,6 +2623,7 @@ _action_copy_activate (GtkAction* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
|
GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
|
||||||
|
#if !WEBKIT_CHECK_VERSION (1, 4, 3)
|
||||||
/* Work around broken clipboard handling for the sake of the user */
|
/* Work around broken clipboard handling for the sake of the user */
|
||||||
if (WEBKIT_IS_WEB_VIEW (widget))
|
if (WEBKIT_IS_WEB_VIEW (widget))
|
||||||
{
|
{
|
||||||
|
@ -2606,6 +2633,7 @@ _action_copy_activate (GtkAction* action,
|
||||||
sokoke_widget_copy_clipboard (widget, selected);
|
sokoke_widget_copy_clipboard (widget, selected);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (G_LIKELY (widget) && g_signal_lookup ("copy-clipboard", G_OBJECT_TYPE (widget)))
|
if (G_LIKELY (widget) && g_signal_lookup ("copy-clipboard", G_OBJECT_TYPE (widget)))
|
||||||
g_signal_emit_by_name (widget, "copy-clipboard");
|
g_signal_emit_by_name (widget, "copy-clipboard");
|
||||||
}
|
}
|
||||||
|
@ -3032,6 +3060,7 @@ _action_compact_menu_populate_popup (GtkAction* action,
|
||||||
{ NULL },
|
{ NULL },
|
||||||
{ "Fullscreen" },
|
{ "Fullscreen" },
|
||||||
{ "Panel" },
|
{ "Panel" },
|
||||||
|
{ "Bookmarkbar" },
|
||||||
{ "-" },
|
{ "-" },
|
||||||
#endif
|
#endif
|
||||||
{ NULL },
|
{ NULL },
|
||||||
|
@ -3103,7 +3132,7 @@ midori_preferences_response_help_cb (GtkWidget* preferences,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
if (response == GTK_RESPONSE_HELP)
|
if (response == GTK_RESPONSE_HELP)
|
||||||
gtk_action_activate (_action_by_name (browser, "HelpFAQ"));
|
midori_browser_activate_action (browser, "HelpFAQ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3129,6 +3158,19 @@ _action_preferences_activate (GtkAction* action,
|
||||||
gtk_window_present (GTK_WINDOW (dialog));
|
gtk_window_present (GTK_WINDOW (dialog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
midori_browser_has_native_menubar (void)
|
||||||
|
{
|
||||||
|
#if HAVE_HILDON
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
static const gchar* ubuntu_menuproxy = NULL;
|
||||||
|
if (ubuntu_menuproxy == NULL)
|
||||||
|
ubuntu_menuproxy = g_getenv ("UBUNTU_MENUPROXY");
|
||||||
|
return ubuntu_menuproxy && strstr (ubuntu_menuproxy, ".so") != NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_action_menubar_activate (GtkToggleAction* menubar_action,
|
_action_menubar_activate (GtkToggleAction* menubar_action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
|
@ -3139,6 +3181,9 @@ _action_menubar_activate (GtkToggleAction* menubar_action,
|
||||||
GList* children;
|
GList* children;
|
||||||
gchar* items;
|
gchar* items;
|
||||||
|
|
||||||
|
if (midori_browser_has_native_menubar ())
|
||||||
|
active = FALSE;
|
||||||
|
|
||||||
toolbar_items = g_string_new (NULL);
|
toolbar_items = g_string_new (NULL);
|
||||||
children = gtk_container_get_children (GTK_CONTAINER (browser->navigationbar));
|
children = gtk_container_get_children (GTK_CONTAINER (browser->navigationbar));
|
||||||
for (; children != NULL; children = g_list_next (children))
|
for (; children != NULL; children = g_list_next (children))
|
||||||
|
@ -3232,13 +3277,14 @@ _action_reload_stop_activate (GtkAction* action,
|
||||||
{
|
{
|
||||||
GdkModifierType state = (GdkModifierType)0;
|
GdkModifierType state = (GdkModifierType)0;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
GdkWindow* window;
|
||||||
gboolean from_cache = TRUE;
|
gboolean from_cache = TRUE;
|
||||||
|
|
||||||
if (!strcmp (gtk_action_get_name (action), "ReloadUncached"))
|
if (!strcmp (gtk_action_get_name (action), "ReloadUncached"))
|
||||||
from_cache = FALSE;
|
from_cache = FALSE;
|
||||||
else
|
else if ((window = gtk_widget_get_window (GTK_WIDGET (browser))))
|
||||||
{
|
{
|
||||||
gdk_window_get_pointer (NULL, &x, &y, &state);
|
gdk_window_get_pointer (window, &x, &y, &state);
|
||||||
if (state & GDK_SHIFT_MASK)
|
if (state & GDK_SHIFT_MASK)
|
||||||
from_cache = FALSE;
|
from_cache = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -3304,112 +3350,19 @@ _action_view_encoding_activate (GtkAction* action,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
|
||||||
midori_browser_get_uri_extension (const gchar* uri)
|
|
||||||
{
|
|
||||||
gchar* slash;
|
|
||||||
gchar* period;
|
|
||||||
gchar* ext_end;
|
|
||||||
|
|
||||||
/* Find the last slash in the URI and search for the last period
|
|
||||||
*after* the last slash. This is not completely accurate
|
|
||||||
but should cover most (simple) URIs */
|
|
||||||
slash = strrchr (uri, '/');
|
|
||||||
/* Huh, URI without slashes? */
|
|
||||||
if (!slash)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ext_end = period = strrchr (slash, '.');
|
|
||||||
if (!period)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Skip the period */
|
|
||||||
ext_end++;
|
|
||||||
/* If *ext_end is 0 here, the URI ended with a period, so skip */
|
|
||||||
if (!*ext_end)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Find the end of the extension */
|
|
||||||
while (*ext_end && g_ascii_isalnum (*ext_end))
|
|
||||||
ext_end++;
|
|
||||||
|
|
||||||
*ext_end = 0;
|
|
||||||
return g_strdup (period);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar*
|
|
||||||
midori_browser_save_source (const gchar* uri,
|
|
||||||
const gchar* data,
|
|
||||||
const size_t len,
|
|
||||||
const gchar* outfile)
|
|
||||||
{
|
|
||||||
gchar* unique_filename;
|
|
||||||
gint fd;
|
|
||||||
FILE* fp;
|
|
||||||
size_t ret;
|
|
||||||
|
|
||||||
if (!outfile)
|
|
||||||
{
|
|
||||||
gchar* filename;
|
|
||||||
gchar* extension;
|
|
||||||
|
|
||||||
extension = midori_browser_get_uri_extension (uri);
|
|
||||||
filename = g_strdup_printf ("%uXXXXXX%s",
|
|
||||||
g_str_hash (uri), extension && *extension ? extension : ".htm");
|
|
||||||
g_free (extension);
|
|
||||||
fd = g_file_open_tmp (filename, &unique_filename, NULL);
|
|
||||||
g_free (filename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unique_filename = g_strdup (outfile);
|
|
||||||
fd = g_open (unique_filename, O_WRONLY|O_CREAT, 0644);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd != -1)
|
|
||||||
{
|
|
||||||
if ((fp = fdopen (fd, "w")))
|
|
||||||
{
|
|
||||||
ret = fwrite (data, 1, len, fp);
|
|
||||||
fclose (fp);
|
|
||||||
if ((ret - len) != 0)
|
|
||||||
{
|
|
||||||
g_warning ("Error writing to file %s "
|
|
||||||
"in midori_browser_source_transfer_cb()", unique_filename);
|
|
||||||
katze_assign (unique_filename, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
return unique_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_action_source_view_activate (GtkAction* action,
|
_action_source_view_activate (GtkAction* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
WebKitWebDataSource *data_source;
|
|
||||||
WebKitWebFrame *frame;
|
|
||||||
const GString *data;
|
|
||||||
GtkWidget* view;
|
GtkWidget* view;
|
||||||
GtkWidget* web_view;
|
|
||||||
gchar* text_editor;
|
gchar* text_editor;
|
||||||
gchar* filename = NULL;
|
gchar* filename = NULL;
|
||||||
const gchar* uri;
|
|
||||||
|
|
||||||
if (!(view = midori_browser_get_current_tab (browser)))
|
if (!(view = midori_browser_get_current_tab (browser)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
filename = midori_view_save_source (MIDORI_VIEW (view), NULL, NULL);
|
||||||
g_object_get (browser->settings, "text-editor", &text_editor, NULL);
|
g_object_get (browser->settings, "text-editor", &text_editor, NULL);
|
||||||
uri = midori_view_get_display_uri (MIDORI_VIEW (view));
|
|
||||||
web_view = midori_view_get_web_view (MIDORI_VIEW (view));
|
|
||||||
frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
|
|
||||||
data_source = webkit_web_frame_get_data_source (frame);
|
|
||||||
data = webkit_web_data_source_get_data (data_source);
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
filename = midori_browser_save_source (uri, data->str, data->len, NULL);
|
|
||||||
if (!(text_editor && *text_editor))
|
if (!(text_editor && *text_editor))
|
||||||
{
|
{
|
||||||
GtkWidget* source;
|
GtkWidget* source;
|
||||||
|
@ -3454,6 +3407,9 @@ _action_fullscreen_activate (GtkAction* action,
|
||||||
state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (browser)));
|
state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (browser)));
|
||||||
if (state & GDK_WINDOW_STATE_FULLSCREEN)
|
if (state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||||
{
|
{
|
||||||
|
if (katze_object_get_boolean (G_OBJECT (browser->settings), "show-menubar"))
|
||||||
|
gtk_widget_show (browser->menubar);
|
||||||
|
|
||||||
if (katze_object_get_boolean (G_OBJECT (browser->settings), "show-panel"))
|
if (katze_object_get_boolean (G_OBJECT (browser->settings), "show-panel"))
|
||||||
gtk_widget_show (browser->panel);
|
gtk_widget_show (browser->panel);
|
||||||
|
|
||||||
|
@ -3471,6 +3427,7 @@ _action_fullscreen_activate (GtkAction* action,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gtk_widget_hide (browser->menubar);
|
||||||
gtk_widget_hide (browser->panel);
|
gtk_widget_hide (browser->panel);
|
||||||
gtk_widget_hide (browser->bookmarkbar);
|
gtk_widget_hide (browser->bookmarkbar);
|
||||||
gtk_widget_hide (browser->navigationbar);
|
gtk_widget_hide (browser->navigationbar);
|
||||||
|
@ -3680,12 +3637,15 @@ static void
|
||||||
_action_location_reset_uri (GtkAction* action,
|
_action_location_reset_uri (GtkAction* action,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
const gchar* uri;
|
GtkWidget* view;
|
||||||
|
if ((view = midori_browser_get_current_tab (browser)))
|
||||||
uri = midori_browser_get_current_uri (browser);
|
{
|
||||||
midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
|
midori_location_action_set_text (MIDORI_LOCATION_ACTION (action),
|
||||||
|
midori_view_get_display_uri (MIDORI_VIEW (view)));
|
||||||
|
midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
|
||||||
|
midori_view_get_icon (MIDORI_VIEW (view)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3694,37 +3654,32 @@ _action_location_submit_uri (GtkAction* action,
|
||||||
gboolean new_tab,
|
gboolean new_tab,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
gchar* stripped_uri;
|
|
||||||
gchar* new_uri;
|
gchar* new_uri;
|
||||||
gint n;
|
gint n;
|
||||||
|
|
||||||
stripped_uri = g_strdup (uri);
|
uri = katze_skip_whitespace (uri);
|
||||||
g_strstrip (stripped_uri);
|
new_uri = sokoke_magic_uri (uri);
|
||||||
new_uri = sokoke_magic_uri (stripped_uri);
|
|
||||||
if (!new_uri)
|
if (!new_uri)
|
||||||
{
|
{
|
||||||
gchar** parts;
|
const gchar* keywords = NULL;
|
||||||
gchar* keywords = NULL;
|
|
||||||
const gchar* search_uri = NULL;
|
const gchar* search_uri = NULL;
|
||||||
|
KatzeItem* item;
|
||||||
|
|
||||||
/* Do we have a keyword and a string? */
|
/* Do we have a keyword and a string? */
|
||||||
parts = g_strsplit (stripped_uri, " ", 2);
|
if (browser->search_engines
|
||||||
if (parts[0] && browser->search_engines)
|
&& (item = katze_array_find_token (browser->search_engines, uri)))
|
||||||
{
|
{
|
||||||
KatzeItem* item;
|
keywords = strchr (uri, ' ');
|
||||||
if ((item = katze_array_find_token (browser->search_engines, parts[0])))
|
if (keywords != NULL)
|
||||||
{
|
keywords++;
|
||||||
keywords = g_strdup (parts[1] ? parts[1] : "");
|
else
|
||||||
|
keywords = "";
|
||||||
search_uri = katze_item_get_uri (item);
|
search_uri = katze_item_get_uri (item);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
g_strfreev (parts);
|
|
||||||
|
|
||||||
if (keywords)
|
if (keywords == NULL)
|
||||||
g_free (stripped_uri);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
keywords = stripped_uri;
|
keywords = uri;
|
||||||
search_uri = browser->location_entry_search;
|
search_uri = browser->location_entry_search;
|
||||||
}
|
}
|
||||||
new_uri = midori_uri_for_search (search_uri, keywords);
|
new_uri = midori_uri_for_search (search_uri, keywords);
|
||||||
|
@ -3753,11 +3708,7 @@ _action_location_submit_uri (GtkAction* action,
|
||||||
if (sqlite3_step (statement) == SQLITE_DONE)
|
if (sqlite3_step (statement) == SQLITE_DONE)
|
||||||
sqlite3_clear_bindings (statement);
|
sqlite3_clear_bindings (statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (keywords);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
g_free (stripped_uri);
|
|
||||||
|
|
||||||
if (new_tab)
|
if (new_tab)
|
||||||
{
|
{
|
||||||
|
@ -4348,7 +4299,6 @@ _action_bookmarks_export_activate (GtkAction* action,
|
||||||
const gchar* format;
|
const gchar* format;
|
||||||
gchar* path = NULL;
|
gchar* path = NULL;
|
||||||
GError* error;
|
GError* error;
|
||||||
sqlite3* db;
|
|
||||||
KatzeArray* bookmarks;
|
KatzeArray* bookmarks;
|
||||||
|
|
||||||
if (!browser->bookmarks || !gtk_widget_get_visible (GTK_WIDGET (browser)))
|
if (!browser->bookmarks || !gtk_widget_get_visible (GTK_WIDGET (browser)))
|
||||||
|
@ -4389,9 +4339,8 @@ wrong_format:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
db = g_object_get_data (G_OBJECT (browser->history), "db");
|
bookmarks = midori_array_query_recursive (browser->bookmarks,
|
||||||
bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
|
"*", "folder='%q'", "", TRUE);
|
||||||
midori_bookmarks_export_array_db (db, bookmarks, "");
|
|
||||||
if (!midori_array_to_file (bookmarks, path, format, &error))
|
if (!midori_array_to_file (bookmarks, path, format, &error))
|
||||||
{
|
{
|
||||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||||
|
@ -4873,7 +4822,7 @@ midori_panel_cycle_child_focus_cb (GtkWidget* hpaned,
|
||||||
|| !gtk_widget_get_ancestor (focus, GTK_TYPE_PANED))
|
|| !gtk_widget_get_ancestor (focus, GTK_TYPE_PANED))
|
||||||
{
|
{
|
||||||
g_signal_stop_emission_by_name (hpaned, "cycle-child-focus");
|
g_signal_stop_emission_by_name (hpaned, "cycle-child-focus");
|
||||||
gtk_action_activate (_action_by_name (browser, "Location"));
|
midori_browser_activate_action (browser, "Location");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -4947,7 +4896,7 @@ midori_panel_close_cb (MidoriPanel* panel,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_notebook_switch_page_cb (GtkWidget* notebook,
|
midori_browser_notebook_switch_page_cb (GtkWidget* notebook,
|
||||||
gpointer page,
|
gpointer page,
|
||||||
guint page_num,
|
guint page_num,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
|
@ -4966,7 +4915,7 @@ gtk_notebook_switch_page_cb (GtkWidget* notebook,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_notebook_switch_page_after_cb (GtkWidget* notebook,
|
midori_browser_notebook_switch_page_after_cb (GtkWidget* notebook,
|
||||||
gpointer page,
|
gpointer page,
|
||||||
guint page_num,
|
guint page_num,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
|
@ -4988,6 +4937,8 @@ gtk_notebook_switch_page_after_cb (GtkWidget* notebook,
|
||||||
midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
|
midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
|
||||||
midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
|
midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
|
||||||
midori_view_get_icon (view));
|
midori_view_get_icon (view));
|
||||||
|
if (sokoke_is_app_or_private ())
|
||||||
|
gtk_window_set_icon (GTK_WINDOW (browser), midori_view_get_icon (view));
|
||||||
|
|
||||||
if (browser->proxy_array)
|
if (browser->proxy_array)
|
||||||
katze_item_set_meta_integer (KATZE_ITEM (browser->proxy_array), "current",
|
katze_item_set_meta_integer (KATZE_ITEM (browser->proxy_array), "current",
|
||||||
|
@ -5031,9 +4982,8 @@ midori_browser_notebook_create_window_cb (GtkNotebook* notebook,
|
||||||
g_signal_emit (browser, signals[NEW_WINDOW], 0, NULL, &new_browser);
|
g_signal_emit (browser, signals[NEW_WINDOW], 0, NULL, &new_browser);
|
||||||
if (new_browser)
|
if (new_browser)
|
||||||
{
|
{
|
||||||
GtkWidget* new_notebook = katze_object_get_object (new_browser, "notebook");
|
GtkWidget* new_notebook = new_browser->notebook;
|
||||||
g_object_unref (new_notebook);
|
gtk_window_move (GTK_WINDOW (new_browser), x, y);
|
||||||
gtk_window_move (GTK_WINDOW (browser), x, y);
|
|
||||||
return new_notebook;
|
return new_notebook;
|
||||||
}
|
}
|
||||||
else /* No MidoriApp, so this is app or private mode */
|
else /* No MidoriApp, so this is app or private mode */
|
||||||
|
@ -5041,7 +4991,7 @@ midori_browser_notebook_create_window_cb (GtkNotebook* notebook,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_browser_switch_tab_cb (GtkWidget* menuitem,
|
midori_browser_menu_item_switch_tab_cb (GtkWidget* menuitem,
|
||||||
MidoriBrowser* browser)
|
MidoriBrowser* browser)
|
||||||
{
|
{
|
||||||
gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "index"));
|
gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "index"));
|
||||||
|
@ -5091,7 +5041,7 @@ midori_browser_notebook_button_press_event_after_cb (GtkNotebook* notebook,
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||||
g_object_set_data (G_OBJECT (menuitem), "index", GINT_TO_POINTER (i));
|
g_object_set_data (G_OBJECT (menuitem), "index", GINT_TO_POINTER (i));
|
||||||
g_signal_connect (menuitem, "activate",
|
g_signal_connect (menuitem, "activate",
|
||||||
G_CALLBACK (midori_browser_switch_tab_cb), browser);
|
G_CALLBACK (midori_browser_menu_item_switch_tab_cb), browser);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
g_list_free (tabs);
|
g_list_free (tabs);
|
||||||
|
@ -5416,19 +5366,6 @@ midori_browser_window_state_event_cb (MidoriBrowser* browser,
|
||||||
else if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
else if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||||
window_state = MIDORI_WINDOW_FULLSCREEN;
|
window_state = MIDORI_WINDOW_FULLSCREEN;
|
||||||
g_object_set (browser->settings, "last-window-state", window_state, NULL);
|
g_object_set (browser->settings, "last-window-state", window_state, NULL);
|
||||||
|
|
||||||
if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
|
|
||||||
{
|
|
||||||
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
|
||||||
{
|
|
||||||
gtk_widget_hide (browser->menubar);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (katze_object_get_boolean (browser->settings, "show-menubar"))
|
|
||||||
gtk_widget_show (browser->menubar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -5857,8 +5794,8 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
GtkSettings* gtk_settings;
|
GtkSettings* gtk_settings;
|
||||||
GtkWidget* hpaned;
|
GtkWidget* hpaned;
|
||||||
GtkWidget* vpaned;
|
GtkWidget* vpaned;
|
||||||
GtkRcStyle* rcstyle;
|
|
||||||
GtkWidget* scrolled;
|
GtkWidget* scrolled;
|
||||||
|
KatzeArray* dummy_array;
|
||||||
|
|
||||||
browser->settings = midori_web_settings_new ();
|
browser->settings = midori_web_settings_new ();
|
||||||
browser->proxy_array = katze_array_new (KATZE_TYPE_ARRAY);
|
browser->proxy_array = katze_array_new (KATZE_TYPE_ARRAY);
|
||||||
|
@ -5878,6 +5815,9 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
G_CALLBACK (midori_browser_destroy_cb), NULL);
|
G_CALLBACK (midori_browser_destroy_cb), NULL);
|
||||||
gtk_window_set_role (GTK_WINDOW (browser), "browser");
|
gtk_window_set_role (GTK_WINDOW (browser), "browser");
|
||||||
gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
|
gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
|
||||||
|
#if GTK_CHECK_VERSION (3, 4, 0)
|
||||||
|
gtk_window_set_hide_titlebar_when_maximized (GTK_WINDOW (browser), TRUE);
|
||||||
|
#endif
|
||||||
vbox = gtk_vbox_new (FALSE, 0);
|
vbox = gtk_vbox_new (FALSE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (browser), vbox);
|
gtk_container_add (GTK_CONTAINER (browser), vbox);
|
||||||
gtk_widget_show (vbox);
|
gtk_widget_show (vbox);
|
||||||
|
@ -5911,7 +5851,7 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide the 'Dummy' which only holds otherwise unused actions */
|
/* Hide the 'Dummy' which only holds otherwise unused actions */
|
||||||
g_object_set (_action_by_name (browser, "Dummy"), "visible", FALSE, NULL);
|
_action_set_visible (browser, "Dummy", FALSE);
|
||||||
|
|
||||||
action = g_object_new (KATZE_TYPE_SEPARATOR_ACTION,
|
action = g_object_new (KATZE_TYPE_SEPARATOR_ACTION,
|
||||||
"name", "Separator",
|
"name", "Separator",
|
||||||
|
@ -5986,12 +5926,14 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
gtk_action_group_add_action_with_accel (browser->action_group, action, "");
|
gtk_action_group_add_action_with_accel (browser->action_group, action, "");
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
|
|
||||||
|
dummy_array = katze_array_new (KATZE_TYPE_ARRAY);
|
||||||
|
katze_array_update (dummy_array);
|
||||||
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
||||||
"name", "Bookmarks",
|
"name", "Bookmarks",
|
||||||
"label", _("_Bookmarks"),
|
"label", _("_Bookmarks"),
|
||||||
"stock-id", STOCK_BOOKMARKS,
|
"stock-id", STOCK_BOOKMARKS,
|
||||||
"tooltip", _("Show the saved bookmarks"),
|
"tooltip", _("Show the saved bookmarks"),
|
||||||
"array", browser->proxy_array, /* Use a non-empty array here */
|
"array", dummy_array /* updated, unique */,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_connect (action,
|
g_object_connect (action,
|
||||||
"signal::populate-folder",
|
"signal::populate-folder",
|
||||||
|
@ -6001,12 +5943,15 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
NULL);
|
NULL);
|
||||||
gtk_action_group_add_action_with_accel (browser->action_group, action, "");
|
gtk_action_group_add_action_with_accel (browser->action_group, action, "");
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
|
g_object_unref (dummy_array);
|
||||||
|
|
||||||
|
dummy_array = katze_array_new (KATZE_TYPE_ITEM);
|
||||||
|
katze_array_update (dummy_array);
|
||||||
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
||||||
"name", "Tools",
|
"name", "Tools",
|
||||||
"label", _("_Tools"),
|
"label", _("_Tools"),
|
||||||
"stock-id", GTK_STOCK_PREFERENCES,
|
"stock-id", GTK_STOCK_PREFERENCES,
|
||||||
"array", katze_array_new (KATZE_TYPE_ITEM),
|
"array", dummy_array /* updated, unique */,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_connect (action,
|
g_object_connect (action,
|
||||||
"signal::populate-popup",
|
"signal::populate-popup",
|
||||||
|
@ -6016,6 +5961,7 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
NULL);
|
NULL);
|
||||||
gtk_action_group_add_action (browser->action_group, action);
|
gtk_action_group_add_action (browser->action_group, action);
|
||||||
g_object_unref (action);
|
g_object_unref (action);
|
||||||
|
g_object_unref (dummy_array);
|
||||||
|
|
||||||
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
action = g_object_new (KATZE_TYPE_ARRAY_ACTION,
|
||||||
"name", "Window",
|
"name", "Window",
|
||||||
|
@ -6051,6 +5997,7 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
browser->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
|
browser->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), browser->menubar, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), browser->menubar, FALSE, FALSE, 0);
|
||||||
gtk_widget_hide (browser->menubar);
|
gtk_widget_hide (browser->menubar);
|
||||||
|
_action_set_visible (browser, "Menubar", !midori_browser_has_native_menubar ());
|
||||||
#if HAVE_HILDON
|
#if HAVE_HILDON
|
||||||
#if HILDON_CHECK_VERSION (2, 2, 0)
|
#if HILDON_CHECK_VERSION (2, 2, 0)
|
||||||
browser->menubar = hildon_app_menu_new ();
|
browser->menubar = hildon_app_menu_new ();
|
||||||
|
@ -6082,7 +6029,6 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
#endif
|
#endif
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (browser->menubar), menuitem);
|
gtk_menu_shell_append (GTK_MENU_SHELL (browser->menubar), menuitem);
|
||||||
#endif
|
#endif
|
||||||
browser->menu_tools = gtk_menu_new ();
|
|
||||||
|
|
||||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (
|
||||||
gtk_ui_manager_get_widget (ui_manager, "/menubar/File/WindowNew")), NULL);
|
gtk_ui_manager_get_widget (ui_manager, "/menubar/File/WindowNew")), NULL);
|
||||||
|
@ -6105,9 +6051,6 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
g_signal_connect (forward, "button-press-event",
|
g_signal_connect (forward, "button-press-event",
|
||||||
G_CALLBACK (midori_browser_menu_item_middle_click_event_cb), browser);
|
G_CALLBACK (midori_browser_menu_item_middle_click_event_cb), browser);
|
||||||
|
|
||||||
#if HAVE_HILDON
|
|
||||||
_action_set_visible (browser, "Menubar", FALSE);
|
|
||||||
#endif
|
|
||||||
_action_set_sensitive (browser, "EncodingCustom", FALSE);
|
_action_set_sensitive (browser, "EncodingCustom", FALSE);
|
||||||
_action_set_visible (browser, "LastSession", FALSE);
|
_action_set_visible (browser, "LastSession", FALSE);
|
||||||
#if !HAVE_HILDON && !defined (GDK_WINDOWING_X11)
|
#if !HAVE_HILDON && !defined (GDK_WINDOWING_X11)
|
||||||
|
@ -6207,18 +6150,22 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, FALSE);
|
gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, FALSE);
|
||||||
gtk_widget_show (vpaned);
|
gtk_widget_show (vpaned);
|
||||||
browser->notebook = gtk_notebook_new ();
|
browser->notebook = gtk_notebook_new ();
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
{
|
||||||
/* Remove the inner border between scrollbars and the window border */
|
/* Remove the inner border between scrollbars and the window border */
|
||||||
rcstyle = gtk_rc_style_new ();
|
GtkRcStyle* rcstyle = gtk_rc_style_new ();
|
||||||
rcstyle->xthickness = 0;
|
rcstyle->xthickness = 0;
|
||||||
gtk_widget_modify_style (browser->notebook, rcstyle);
|
gtk_widget_modify_style (browser->notebook, rcstyle);
|
||||||
g_object_unref (rcstyle);
|
g_object_unref (rcstyle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
|
gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
|
||||||
gtk_paned_pack1 (GTK_PANED (vpaned), browser->notebook, FALSE, FALSE);
|
gtk_paned_pack1 (GTK_PANED (vpaned), browser->notebook, FALSE, FALSE);
|
||||||
g_signal_connect (browser->notebook, "switch-page",
|
g_signal_connect (browser->notebook, "switch-page",
|
||||||
G_CALLBACK (gtk_notebook_switch_page_cb),
|
G_CALLBACK (midori_browser_notebook_switch_page_cb),
|
||||||
browser);
|
browser);
|
||||||
g_signal_connect_after (browser->notebook, "switch-page",
|
g_signal_connect_after (browser->notebook, "switch-page",
|
||||||
G_CALLBACK (gtk_notebook_switch_page_after_cb),
|
G_CALLBACK (midori_browser_notebook_switch_page_after_cb),
|
||||||
browser);
|
browser);
|
||||||
g_signal_connect (browser->notebook, "page-reordered",
|
g_signal_connect (browser->notebook, "page-reordered",
|
||||||
G_CALLBACK (midori_browser_notebook_page_reordered_cb),
|
G_CALLBACK (midori_browser_notebook_page_reordered_cb),
|
||||||
|
@ -6285,7 +6232,12 @@ midori_browser_init (MidoriBrowser* browser)
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), browser->statusbar, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), browser->statusbar, FALSE, FALSE, 0);
|
||||||
|
|
||||||
browser->transferbar = g_object_new (MIDORI_TYPE_TRANSFERBAR, NULL);
|
browser->transferbar = g_object_new (MIDORI_TYPE_TRANSFERBAR, NULL);
|
||||||
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
/* FIXME: Transfers should go between text and statusbar features like GTK+2 */
|
||||||
|
gtk_box_pack_end (GTK_BOX (browser->statusbar_contents), browser->transferbar, FALSE, FALSE, 3);
|
||||||
|
#else
|
||||||
gtk_box_pack_start (GTK_BOX (browser->statusbar_contents), browser->transferbar, FALSE, FALSE, 3);
|
gtk_box_pack_start (GTK_BOX (browser->statusbar_contents), browser->transferbar, FALSE, FALSE, 3);
|
||||||
|
#endif
|
||||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (browser->transferbar), FALSE);
|
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (browser->transferbar), FALSE);
|
||||||
gtk_widget_show (browser->transferbar);
|
gtk_widget_show (browser->transferbar);
|
||||||
|
|
||||||
|
@ -6676,29 +6628,21 @@ midori_browser_settings_notify (MidoriWebSettings* web_settings,
|
||||||
_toggle_tabbar_smartly (browser, FALSE);
|
_toggle_tabbar_smartly (browser, FALSE);
|
||||||
else if (name == g_intern_string ("show-menubar"))
|
else if (name == g_intern_string ("show-menubar"))
|
||||||
{
|
{
|
||||||
gtk_toggle_action_set_active (
|
_action_set_active (browser, "Menubar", g_value_get_boolean (&value));
|
||||||
GTK_TOGGLE_ACTION (_action_by_name (browser, "Menubar")),
|
|
||||||
g_value_get_boolean (&value));
|
|
||||||
}
|
}
|
||||||
else if (name == g_intern_string ("show-navigationbar"))
|
else if (name == g_intern_string ("show-navigationbar"))
|
||||||
{
|
{
|
||||||
browser->show_navigationbar = g_value_get_boolean (&value);
|
browser->show_navigationbar = g_value_get_boolean (&value);
|
||||||
gtk_toggle_action_set_active (
|
_action_set_active (browser, "Navigationbar", g_value_get_boolean (&value));
|
||||||
GTK_TOGGLE_ACTION (_action_by_name (browser, "Navigationbar")),
|
|
||||||
g_value_get_boolean (&value));
|
|
||||||
}
|
}
|
||||||
else if (name == g_intern_string ("show-bookmarkbar"))
|
else if (name == g_intern_string ("show-bookmarkbar"))
|
||||||
{
|
{
|
||||||
gtk_toggle_action_set_active (
|
_action_set_active (browser, "Bookmarkbar", g_value_get_boolean (&value));
|
||||||
GTK_TOGGLE_ACTION (_action_by_name (browser, "Bookmarkbar")),
|
|
||||||
g_value_get_boolean (&value));
|
|
||||||
}
|
}
|
||||||
else if (name == g_intern_string ("show-statusbar"))
|
else if (name == g_intern_string ("show-statusbar"))
|
||||||
{
|
{
|
||||||
browser->show_statusbar = g_value_get_boolean (&value);
|
browser->show_statusbar = g_value_get_boolean (&value);
|
||||||
gtk_toggle_action_set_active (
|
_action_set_active (browser, "Statusbar", g_value_get_boolean (&value));
|
||||||
GTK_TOGGLE_ACTION (_action_by_name (browser, "Statusbar")),
|
|
||||||
g_value_get_boolean (&value));
|
|
||||||
}
|
}
|
||||||
else if (name == g_intern_string ("location-entry-search"))
|
else if (name == g_intern_string ("location-entry-search"))
|
||||||
{
|
{
|
||||||
|
@ -7336,7 +7280,7 @@ midori_browser_set_current_page (MidoriBrowser* browser,
|
||||||
|
|
||||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
|
||||||
if (midori_view_is_blank (MIDORI_VIEW (view)))
|
if (midori_view_is_blank (MIDORI_VIEW (view)))
|
||||||
gtk_action_activate (_action_by_name (browser, "Location"));
|
midori_browser_activate_action (browser, "Location");
|
||||||
else
|
else
|
||||||
gtk_widget_grab_focus (view);
|
gtk_widget_grab_focus (view);
|
||||||
|
|
||||||
|
|
|
@ -277,43 +277,96 @@ midori_location_action_create_model (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_location_action_popup_position (GtkWidget* popup,
|
midori_location_action_popup_position (MidoriLocationAction* action,
|
||||||
GtkWidget* widget)
|
gint matches)
|
||||||
{
|
{
|
||||||
|
GtkWidget* popup = action->popup;
|
||||||
|
GtkWidget* widget = action->entry;
|
||||||
GdkWindow* window = gtk_widget_get_window (widget);
|
GdkWindow* window = gtk_widget_get_window (widget);
|
||||||
gint wx, wy;
|
gint wx, wy, x_border, y_border, items;
|
||||||
GtkRequisition menu_req;
|
GtkRequisition menu_req;
|
||||||
GtkRequisition widget_req;
|
GtkRequisition widget_req;
|
||||||
GdkScreen* screen;
|
GdkScreen* screen;
|
||||||
gint monitor_num;
|
gint monitor_num;
|
||||||
GdkRectangle monitor;
|
GdkRectangle monitor;
|
||||||
GtkAllocation allocation;
|
GtkAllocation alloc;
|
||||||
|
gint height, sep, width, toplevel_height;
|
||||||
|
gboolean above;
|
||||||
|
GtkWidget* scrolled = gtk_widget_get_parent (action->treeview);
|
||||||
|
GtkWidget* toplevel;
|
||||||
|
GtkTreePath* path;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &alloc);
|
||||||
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
gtk_widget_get_preferred_size (widget, &widget_req, NULL);
|
||||||
|
#else
|
||||||
|
gtk_widget_size_request (widget, &widget_req);
|
||||||
|
#endif
|
||||||
gdk_window_get_origin (window, &wx, &wy);
|
gdk_window_get_origin (window, &wx, &wy);
|
||||||
|
|
||||||
if (!gtk_widget_get_has_window (widget))
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
{
|
|
||||||
GtkAllocation alloc;
|
|
||||||
gtk_widget_get_allocation (widget, &alloc);
|
|
||||||
wx += alloc.x;
|
wx += alloc.x;
|
||||||
wy += alloc.y;
|
wy += alloc.y + (alloc.height - widget_req.height) / 2;
|
||||||
}
|
#endif
|
||||||
|
/* _gtk_entry_get_borders (GTK_ENTRY (widget), &x_border, &y_border); */
|
||||||
|
x_border = y_border = 0;
|
||||||
|
|
||||||
gtk_widget_size_request (popup, &menu_req);
|
gtk_tree_view_column_cell_get_size (
|
||||||
gtk_widget_size_request (widget, &widget_req);
|
gtk_tree_view_get_column (GTK_TREE_VIEW (action->treeview), 0),
|
||||||
|
NULL, NULL, NULL, NULL, &height);
|
||||||
|
gtk_widget_style_get (action->treeview, "vertical-separator", &sep, NULL);
|
||||||
|
height += sep;
|
||||||
|
|
||||||
|
/* Constrain to screen/ window size */
|
||||||
screen = gtk_widget_get_screen (widget);
|
screen = gtk_widget_get_screen (widget);
|
||||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||||
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
|
||||||
|
toplevel = gtk_widget_get_toplevel (widget);
|
||||||
if (wy + widget_req.height + menu_req.height <= monitor.y + monitor.height
|
gtk_window_get_size (GTK_WINDOW (toplevel), NULL, &toplevel_height);
|
||||||
|| wy - monitor.y < (monitor.y + monitor.height) - (wy + widget_req.height))
|
toplevel_height = MIN (toplevel_height, monitor.height);
|
||||||
wy += widget_req.height;
|
if (wy > toplevel_height / 2)
|
||||||
|
items = MIN (matches, ((monitor.y + wy) / height) - 1);
|
||||||
else
|
else
|
||||||
|
items = MIN (matches, ((toplevel_height - wy) / height) - 1);
|
||||||
|
width = MIN (alloc.width, monitor.width) - 2 * x_border;
|
||||||
|
|
||||||
|
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (action->treeview));
|
||||||
|
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
gtk_widget_set_size_request (scrolled, width, -1);
|
||||||
|
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (scrolled), width);
|
||||||
|
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled), items * height);
|
||||||
|
gtk_widget_get_preferred_size (popup, &menu_req, NULL);
|
||||||
|
#else
|
||||||
|
gtk_widget_set_size_request (scrolled, width, items * height);
|
||||||
|
gtk_widget_size_request (popup, &menu_req);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wx < monitor.x)
|
||||||
|
wx = monitor.x;
|
||||||
|
else if (wx + menu_req.width > monitor.x + monitor.width)
|
||||||
|
wx = monitor.x + monitor.width - menu_req.width;
|
||||||
|
|
||||||
|
if (wy + widget_req.height + menu_req.height <= monitor.y + monitor.height ||
|
||||||
|
wy - monitor.y < (monitor.y + monitor.height) - (wy + widget_req.height))
|
||||||
|
{
|
||||||
|
wy += widget_req.height;
|
||||||
|
above = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
wy -= menu_req.height;
|
wy -= menu_req.height;
|
||||||
|
above = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = gtk_tree_path_new_from_indices (above ? matches - 1 : 0, -1);
|
||||||
|
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (action->treeview), path,
|
||||||
|
NULL, FALSE, 0.0, 0.0);
|
||||||
|
gtk_tree_path_free (path);
|
||||||
|
|
||||||
gtk_window_move (GTK_WINDOW (popup), wx, wy);
|
gtk_window_move (GTK_WINDOW (popup), wx, wy);
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
|
||||||
gtk_window_resize (GTK_WINDOW (popup), allocation.width, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -357,28 +410,21 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
gint result;
|
gint result;
|
||||||
static sqlite3_stmt* stmt;
|
static sqlite3_stmt* stmt;
|
||||||
const gchar* sqlcmd;
|
const gchar* sqlcmd;
|
||||||
gint matches, searches, height, screen_height, browser_height, sep;
|
gint matches, searches;
|
||||||
MidoriBrowser* browser;
|
|
||||||
GtkStyle* style;
|
GtkStyle* style;
|
||||||
|
|
||||||
if (!action->entry || !gtk_widget_has_focus (action->entry) || !action->history)
|
if (!action->entry || !gtk_widget_has_focus (action->entry) || !action->history)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* No completion when typing a search token */
|
/* No completion when typing a search token */
|
||||||
if (action->search_engines != NULL)
|
if (action->search_engines
|
||||||
|
&& katze_array_find_token (action->search_engines, action->key))
|
||||||
{
|
{
|
||||||
gchar** parts = g_strsplit (action->key, " ", 2);
|
|
||||||
if (parts && *parts && parts[1]
|
|
||||||
&& katze_array_find_token (action->search_engines, *parts))
|
|
||||||
{
|
|
||||||
g_strfreev (parts);
|
|
||||||
midori_location_action_popdown_completion (action);
|
midori_location_action_popdown_completion (action);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
g_strfreev (parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Empaty string or starting with a space means: no completion */
|
/* Empty string or starting with a space means: no completion */
|
||||||
if (!(action->key && *action->key && *action->key != ' '))
|
if (!(action->key && *action->key && *action->key != ' '))
|
||||||
{
|
{
|
||||||
midori_location_action_popdown_completion (action);
|
midori_location_action_popdown_completion (action);
|
||||||
|
@ -443,6 +489,8 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
|
|
||||||
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||||
gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
|
gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
|
||||||
|
/* Window managers may ignore programmatic resize without this */
|
||||||
|
gtk_window_set_resizable (GTK_WINDOW (popup), FALSE);
|
||||||
popup_frame = gtk_frame_new (NULL);
|
popup_frame = gtk_frame_new (NULL);
|
||||||
gtk_frame_set_shadow_type (GTK_FRAME (popup_frame), GTK_SHADOW_ETCHED_IN);
|
gtk_frame_set_shadow_type (GTK_FRAME (popup_frame), GTK_SHADOW_ETCHED_IN);
|
||||||
gtk_container_add (GTK_CONTAINER (popup), popup_frame);
|
gtk_container_add (GTK_CONTAINER (popup), popup_frame);
|
||||||
|
@ -489,6 +537,7 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
gtk_list_store_clear (store);
|
gtk_list_store_clear (store);
|
||||||
|
|
||||||
matches = searches = 0;
|
matches = searches = 0;
|
||||||
|
gtk_widget_realize (action->treeview);
|
||||||
style = gtk_widget_get_style (action->treeview);
|
style = gtk_widget_get_style (action->treeview);
|
||||||
while (result == SQLITE_ROW)
|
while (result == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
|
@ -507,9 +556,11 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
else if (type == 2 /* search_view */)
|
else if (type == 2 /* search_view */)
|
||||||
{
|
{
|
||||||
gchar* search_title = g_strdup_printf (_("Search for %s"), title);
|
gchar* search_title = g_strdup_printf (_("Search for %s"), title);
|
||||||
|
gchar* search_desc = g_strdup_printf ("%s\n%s", search_title, uri);
|
||||||
gtk_list_store_insert_with_values (store, NULL, matches,
|
gtk_list_store_insert_with_values (store, NULL, matches,
|
||||||
URI_COL, uri, TITLE_COL, search_title, YALIGN_COL, 0.25,
|
URI_COL, uri, TITLE_COL, search_desc, YALIGN_COL, 0.25,
|
||||||
STYLE_COL, 1, FAVICON_COL, icon, -1);
|
STYLE_COL, 1, FAVICON_COL, icon, -1);
|
||||||
|
g_free (search_desc);
|
||||||
g_free (search_title);
|
g_free (search_title);
|
||||||
}
|
}
|
||||||
if (icon != NULL)
|
if (icon != NULL)
|
||||||
|
@ -518,8 +569,12 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
matches++;
|
matches++;
|
||||||
result = sqlite3_step (stmt);
|
result = sqlite3_step (stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stmt)
|
||||||
|
{
|
||||||
sqlite3_reset (stmt);
|
sqlite3_reset (stmt);
|
||||||
sqlite3_clear_bindings (stmt);
|
sqlite3_clear_bindings (stmt);
|
||||||
|
}
|
||||||
|
|
||||||
if (action->search_engines)
|
if (action->search_engines)
|
||||||
{
|
{
|
||||||
|
@ -529,17 +584,22 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
{
|
{
|
||||||
gchar* uri;
|
gchar* uri;
|
||||||
gchar* title;
|
gchar* title;
|
||||||
|
const gchar* text;
|
||||||
|
gchar* desc;
|
||||||
GdkPixbuf* icon;
|
GdkPixbuf* icon;
|
||||||
|
|
||||||
uri = midori_uri_for_search (katze_item_get_uri (item), action->key);
|
uri = midori_uri_for_search (katze_item_get_uri (item), action->key);
|
||||||
title = g_strdup_printf (_("Search with %s"), katze_item_get_name (item));
|
title = g_strdup_printf (_("Search with %s"), katze_item_get_name (item));
|
||||||
|
text = katze_item_get_text (item);
|
||||||
|
desc = g_strdup_printf ("%s\n%s", title, text ? text : uri);
|
||||||
icon = midori_search_action_get_icon (item, action->treeview, NULL, FALSE);
|
icon = midori_search_action_get_icon (item, action->treeview, NULL, FALSE);
|
||||||
gtk_list_store_insert_with_values (store, NULL, matches + i,
|
gtk_list_store_insert_with_values (store, NULL, matches + i,
|
||||||
URI_COL, uri, TITLE_COL, title, YALIGN_COL, 0.25,
|
URI_COL, uri, TITLE_COL, desc, YALIGN_COL, 0.25,
|
||||||
BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
|
BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
|
||||||
STYLE_COL, 1, FAVICON_COL, icon, -1);
|
STYLE_COL, 1, FAVICON_COL, icon, -1);
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
g_free (title);
|
g_free (title);
|
||||||
|
g_free (desc);
|
||||||
if (icon != NULL)
|
if (icon != NULL)
|
||||||
g_object_unref (icon);
|
g_object_unref (icon);
|
||||||
i++;
|
i++;
|
||||||
|
@ -553,22 +613,10 @@ midori_location_action_popup_timeout_cb (gpointer data)
|
||||||
gtk_window_set_screen (GTK_WINDOW (action->popup),
|
gtk_window_set_screen (GTK_WINDOW (action->popup),
|
||||||
gtk_widget_get_screen (action->entry));
|
gtk_widget_get_screen (action->entry));
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (action->popup), GTK_WINDOW (toplevel));
|
gtk_window_set_transient_for (GTK_WINDOW (action->popup), GTK_WINDOW (toplevel));
|
||||||
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (action->treeview));
|
gtk_widget_show_all (action->popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
browser = midori_browser_get_for_widget (action->entry);
|
midori_location_action_popup_position (action, matches + searches);
|
||||||
column = gtk_tree_view_get_column (GTK_TREE_VIEW (action->treeview), 0);
|
|
||||||
gtk_tree_view_column_cell_get_size (column, NULL, NULL, NULL, NULL, &height);
|
|
||||||
screen_height = gdk_screen_get_height (gtk_widget_get_screen (action->popup));
|
|
||||||
gtk_window_get_size (GTK_WINDOW (browser), NULL, &browser_height);
|
|
||||||
screen_height = MIN (MIN (browser_height, screen_height / 1.5), screen_height / 1.5);
|
|
||||||
gtk_widget_style_get (action->treeview, "vertical-separator", &sep, NULL);
|
|
||||||
/* FIXME: Instead of 1.5 we should relate to the height of one line */
|
|
||||||
height = MIN (matches * height + (matches + searches) * sep
|
|
||||||
+ searches * height / 1.5, screen_height);
|
|
||||||
gtk_widget_set_size_request (action->treeview, -1, height);
|
|
||||||
midori_location_action_popup_position (action->popup, action->entry);
|
|
||||||
gtk_widget_show_all (action->popup);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1532,30 +1580,22 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* midori_location_action_set_icon_for_uri:
|
||||||
|
* @location_action: a #MidoriLocationAction
|
||||||
|
* @icon: a #GdkPixbuf
|
||||||
|
* @uri: an URI string
|
||||||
|
*
|
||||||
|
* Sets the icon for the specified URI.
|
||||||
|
*
|
||||||
|
* Deprecated: 0.4.4
|
||||||
|
**/
|
||||||
void
|
void
|
||||||
midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
|
midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
|
||||||
GdkPixbuf* icon,
|
GdkPixbuf* icon,
|
||||||
const gchar* uri)
|
const gchar* uri)
|
||||||
{
|
{
|
||||||
#if !HAVE_HILDON
|
midori_location_action_set_icon (location_action, icon);
|
||||||
GSList* proxies;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
|
|
||||||
g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
|
|
||||||
g_return_if_fail (uri != NULL);
|
|
||||||
|
|
||||||
#if !HAVE_HILDON
|
|
||||||
proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
|
|
||||||
|
|
||||||
for (; proxies != NULL; proxies = g_slist_next (proxies))
|
|
||||||
if (GTK_IS_TOOL_ITEM (proxies->data))
|
|
||||||
{
|
|
||||||
GtkWidget* entry = midori_location_action_entry_for_proxy (proxies->data);
|
|
||||||
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
|
|
||||||
GTK_ICON_ENTRY_PRIMARY, icon);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1659,16 +1699,20 @@ midori_location_action_set_security_hint (MidoriLocationAction* location_action,
|
||||||
for (; proxies != NULL; proxies = g_slist_next (proxies))
|
for (; proxies != NULL; proxies = g_slist_next (proxies))
|
||||||
if (GTK_IS_TOOL_ITEM (proxies->data))
|
if (GTK_IS_TOOL_ITEM (proxies->data))
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
const gchar* bg_color = NULL;
|
const gchar* bg_color = NULL;
|
||||||
const gchar* fg_color = NULL;
|
const gchar* fg_color = NULL;
|
||||||
|
#endif
|
||||||
GtkWidget* entry = midori_location_action_entry_for_proxy (proxies->data);
|
GtkWidget* entry = midori_location_action_entry_for_proxy (proxies->data);
|
||||||
GdkScreen* screen = gtk_widget_get_screen (entry);
|
GdkScreen* screen = gtk_widget_get_screen (entry);
|
||||||
GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
|
GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||||
|
|
||||||
if (hint == MIDORI_SECURITY_UNKNOWN)
|
if (hint == MIDORI_SECURITY_UNKNOWN)
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
bg_color = "#ef7070";
|
bg_color = "#ef7070";
|
||||||
fg_color = "#000";
|
fg_color = "#000";
|
||||||
|
#endif
|
||||||
#if !HAVE_HILDON
|
#if !HAVE_HILDON
|
||||||
if (gtk_icon_theme_has_icon (icon_theme, "channel-insecure-symbolic"))
|
if (gtk_icon_theme_has_icon (icon_theme, "channel-insecure-symbolic"))
|
||||||
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
||||||
|
@ -1685,8 +1729,10 @@ midori_location_action_set_security_hint (MidoriLocationAction* location_action,
|
||||||
}
|
}
|
||||||
else if (hint == MIDORI_SECURITY_TRUSTED)
|
else if (hint == MIDORI_SECURITY_TRUSTED)
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
bg_color = "#d1eeb9";
|
bg_color = "#d1eeb9";
|
||||||
fg_color = "#000";
|
fg_color = "#000";
|
||||||
|
#endif
|
||||||
#if !HAVE_HILDON
|
#if !HAVE_HILDON
|
||||||
if (gtk_icon_theme_has_icon (icon_theme, "channel-secure-symbolic"))
|
if (gtk_icon_theme_has_icon (icon_theme, "channel-secure-symbolic"))
|
||||||
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
||||||
|
|
|
@ -393,6 +393,13 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
||||||
INDENTED_ADD (button);
|
INDENTED_ADD (button);
|
||||||
button = katze_property_proxy (settings, "flash-window-on-new-bg-tabs", NULL);
|
button = katze_property_proxy (settings, "flash-window-on-new-bg-tabs", NULL);
|
||||||
SPANNED_ADD (button);
|
SPANNED_ADD (button);
|
||||||
|
|
||||||
|
if (katze_object_has_property (settings, "enable-webgl"))
|
||||||
|
{
|
||||||
|
button = katze_property_proxy (settings, "enable-webgl", NULL);
|
||||||
|
INDENTED_ADD (button);
|
||||||
|
}
|
||||||
|
|
||||||
FRAME_NEW (NULL);
|
FRAME_NEW (NULL);
|
||||||
button = katze_property_label (settings, "preferred-languages");
|
button = katze_property_label (settings, "preferred-languages");
|
||||||
INDENTED_ADD (button);
|
INDENTED_ADD (button);
|
||||||
|
|
|
@ -312,6 +312,7 @@ midori_search_action_create_tool_item (GtkAction* action)
|
||||||
|
|
||||||
toolitem = GTK_WIDGET (gtk_tool_item_new ());
|
toolitem = GTK_WIDGET (gtk_tool_item_new ());
|
||||||
entry = gtk_icon_entry_new ();
|
entry = gtk_icon_entry_new ();
|
||||||
|
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
|
||||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||||
GTK_ICON_ENTRY_PRIMARY, TRUE);
|
GTK_ICON_ENTRY_PRIMARY, TRUE);
|
||||||
alignment = gtk_alignment_new (0, 0.5, 1, 0.1);
|
alignment = gtk_alignment_new (0, 0.5, 1, 0.1);
|
||||||
|
@ -876,12 +877,6 @@ midori_search_action_editor_name_changed_cb (GtkWidget* entry,
|
||||||
GTK_RESPONSE_ACCEPT, text && *text);
|
GTK_RESPONSE_ACCEPT, text && *text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const gchar*
|
|
||||||
STR_NON_NULL (const gchar* string)
|
|
||||||
{
|
|
||||||
return string ? string : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_search_action_get_editor (MidoriSearchAction* search_action,
|
midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
gboolean new_engine)
|
gboolean new_engine)
|
||||||
|
@ -942,7 +937,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_name), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry_name), TRUE);
|
||||||
if (!new_engine)
|
if (!new_engine)
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry_name),
|
gtk_entry_set_text (GTK_ENTRY (entry_name),
|
||||||
STR_NON_NULL (katze_item_get_name (item)));
|
katze_str_non_null (katze_item_get_name (item)));
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), entry_name, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), entry_name, TRUE, TRUE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
gtk_widget_show_all (hbox);
|
gtk_widget_show_all (hbox);
|
||||||
|
@ -956,7 +951,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_description), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry_description), TRUE);
|
||||||
if (!new_engine)
|
if (!new_engine)
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry_description)
|
gtk_entry_set_text (GTK_ENTRY (entry_description)
|
||||||
, STR_NON_NULL (katze_item_get_text (item)));
|
, katze_str_non_null (katze_item_get_text (item)));
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), entry_description, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), entry_description, TRUE, TRUE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
gtk_widget_show_all (hbox);
|
gtk_widget_show_all (hbox);
|
||||||
|
@ -972,10 +967,11 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
#else
|
#else
|
||||||
NULL);
|
NULL);
|
||||||
#endif
|
#endif
|
||||||
|
g_object_set_data (G_OBJECT (entry_uri), "allow_%s", (void*)1);
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
|
||||||
if (!new_engine)
|
if (!new_engine)
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry_uri)
|
gtk_entry_set_text (GTK_ENTRY (entry_uri)
|
||||||
, STR_NON_NULL (katze_item_get_uri (item)));
|
, katze_str_non_null (katze_item_get_uri (item)));
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), entry_uri, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), entry_uri, TRUE, TRUE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
gtk_widget_show_all (hbox);
|
gtk_widget_show_all (hbox);
|
||||||
|
@ -989,7 +985,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_icon), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry_icon), TRUE);
|
||||||
if (!new_engine)
|
if (!new_engine)
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry_icon)
|
gtk_entry_set_text (GTK_ENTRY (entry_icon)
|
||||||
, STR_NON_NULL (katze_item_get_icon (item)));
|
, katze_str_non_null (katze_item_get_icon (item)));
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), entry_icon, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), entry_icon, TRUE, TRUE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
gtk_widget_show_all (hbox);
|
gtk_widget_show_all (hbox);
|
||||||
|
@ -1003,7 +999,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_token), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry_token), TRUE);
|
||||||
if (!new_engine)
|
if (!new_engine)
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry_token)
|
gtk_entry_set_text (GTK_ENTRY (entry_token)
|
||||||
, STR_NON_NULL (katze_item_get_token (item)));
|
, katze_str_non_null (katze_item_get_token (item)));
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), entry_token, TRUE, TRUE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), entry_token, TRUE, TRUE, 0);
|
||||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||||
gtk_widget_show_all (hbox);
|
gtk_widget_show_all (hbox);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -197,6 +197,11 @@ midori_view_can_view_source (MidoriView* view);
|
||||||
gboolean
|
gboolean
|
||||||
midori_view_can_save (MidoriView* view);
|
midori_view_can_save (MidoriView* view);
|
||||||
|
|
||||||
|
gchar*
|
||||||
|
midori_view_save_source (MidoriView* view,
|
||||||
|
const gchar* uri,
|
||||||
|
const gchar* outfile);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
midori_view_can_find (MidoriView* view);
|
midori_view_can_find (MidoriView* view);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "midori-websettings.h"
|
#include "midori-websettings.h"
|
||||||
|
|
||||||
#include "sokoke.h"
|
#include "sokoke.h"
|
||||||
|
#include <midori/midori-core.h> /* Vala API */
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
|
@ -85,6 +86,7 @@ struct _MidoriWebSettings
|
||||||
|
|
||||||
gint clear_private_data;
|
gint clear_private_data;
|
||||||
gchar* clear_data;
|
gchar* clear_data;
|
||||||
|
gchar* site_data_rules;
|
||||||
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
||||||
gboolean enable_dns_prefetching;
|
gboolean enable_dns_prefetching;
|
||||||
#endif
|
#endif
|
||||||
|
@ -145,6 +147,8 @@ enum
|
||||||
PROP_OPEN_TABS_NEXT_TO_CURRENT,
|
PROP_OPEN_TABS_NEXT_TO_CURRENT,
|
||||||
PROP_OPEN_POPUPS_IN_TABS,
|
PROP_OPEN_POPUPS_IN_TABS,
|
||||||
PROP_FLASH_WINDOW_ON_BG_TABS,
|
PROP_FLASH_WINDOW_ON_BG_TABS,
|
||||||
|
PROP_ENABLE_WEBGL,
|
||||||
|
PROP_ENABLE_FULLSCREEN,
|
||||||
|
|
||||||
PROP_AUTO_LOAD_IMAGES,
|
PROP_AUTO_LOAD_IMAGES,
|
||||||
PROP_ENABLE_SCRIPTS,
|
PROP_ENABLE_SCRIPTS,
|
||||||
|
@ -173,6 +177,7 @@ enum
|
||||||
|
|
||||||
PROP_CLEAR_PRIVATE_DATA,
|
PROP_CLEAR_PRIVATE_DATA,
|
||||||
PROP_CLEAR_DATA,
|
PROP_CLEAR_DATA,
|
||||||
|
PROP_SITE_DATA_RULES,
|
||||||
PROP_ENABLE_DNS_PREFETCHING,
|
PROP_ENABLE_DNS_PREFETCHING,
|
||||||
PROP_STRIP_REFERER,
|
PROP_STRIP_REFERER,
|
||||||
PROP_ENFORCE_FONT_FAMILY,
|
PROP_ENFORCE_FONT_FAMILY,
|
||||||
|
@ -339,6 +344,21 @@ midori_get_download_dir (void)
|
||||||
}
|
}
|
||||||
return g_get_home_dir ();
|
return g_get_home_dir ();
|
||||||
}
|
}
|
||||||
|
static gboolean
|
||||||
|
midori_web_settings_low_memory_profile ()
|
||||||
|
{
|
||||||
|
gchar* contents;
|
||||||
|
const gchar* total;
|
||||||
|
if (!g_file_get_contents ("/proc/meminfo", &contents, NULL, NULL))
|
||||||
|
return FALSE;
|
||||||
|
if (contents && (total = strstr (contents, "MemTotal:")) && *total)
|
||||||
|
{
|
||||||
|
const gchar* value = katze_skip_whitespace (total + 9);
|
||||||
|
gdouble mem_total = g_ascii_strtoll (value, NULL, 0);
|
||||||
|
return mem_total / 1024.0 < 352 + 1;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
|
@ -727,13 +747,8 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
"enable-plugins",
|
"enable-plugins",
|
||||||
_("Enable Netscape plugins"),
|
_("Enable Netscape plugins"),
|
||||||
_("Enable embedded Netscape plugin objects"),
|
_("Enable embedded Netscape plugin objects"),
|
||||||
#ifdef G_OS_WIN32
|
midori_web_settings_has_plugin_support (),
|
||||||
FALSE,
|
midori_web_settings_has_plugin_support () ? flags : G_PARAM_READABLE));
|
||||||
G_PARAM_READABLE));
|
|
||||||
#else
|
|
||||||
TRUE,
|
|
||||||
flags));
|
|
||||||
#endif
|
|
||||||
/* Override properties to override defaults */
|
/* Override properties to override defaults */
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_ENABLE_DEVELOPER_EXTRAS,
|
PROP_ENABLE_DEVELOPER_EXTRAS,
|
||||||
|
@ -777,7 +792,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
g_param_spec_boolean ("enable-page-cache",
|
g_param_spec_boolean ("enable-page-cache",
|
||||||
"Enable page cache",
|
"Enable page cache",
|
||||||
"Whether the page cache should be used",
|
"Whether the page cache should be used",
|
||||||
TRUE,
|
!midori_web_settings_low_memory_profile (),
|
||||||
flags));
|
flags));
|
||||||
#endif
|
#endif
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
|
@ -788,6 +803,26 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
_("Flash the browser window if a new tab was opened in the background"),
|
_("Flash the browser window if a new tab was opened in the background"),
|
||||||
FALSE,
|
FALSE,
|
||||||
flags));
|
flags));
|
||||||
|
if (g_object_class_find_property (gobject_class, "enable-webgl"))
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_ENABLE_WEBGL,
|
||||||
|
g_param_spec_boolean (
|
||||||
|
"enable-webgl",
|
||||||
|
_("Enable WebGL support"),
|
||||||
|
_("Allow websites to use OpenGL rendering"),
|
||||||
|
/* Enable by default for git builds */
|
||||||
|
!g_str_equal (PACKAGE_VERSION, MIDORI_VERSION),
|
||||||
|
flags));
|
||||||
|
if (g_object_class_find_property (gobject_class, "enable-fullscreen"))
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_ENABLE_FULLSCREEN,
|
||||||
|
g_param_spec_boolean (
|
||||||
|
"enable-fullscreen",
|
||||||
|
"Enable Fullscreen",
|
||||||
|
"Allow experimental fullscreen API",
|
||||||
|
TRUE,
|
||||||
|
flags));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MidoriWebSettings:zoom-text-and-images:
|
* MidoriWebSettings:zoom-text-and-images:
|
||||||
|
@ -1021,6 +1056,22 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
||||||
_("The data selected for deletion"),
|
_("The data selected for deletion"),
|
||||||
NULL,
|
NULL,
|
||||||
flags));
|
flags));
|
||||||
|
/**
|
||||||
|
* MidoriWebSettings:site-data-rules:
|
||||||
|
*
|
||||||
|
* Rules for accepting, denying and preserving cookies and other data.
|
||||||
|
* See midori_web_settings_get_site_data_policy() for details.
|
||||||
|
*
|
||||||
|
* Since: 0.4.4
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_SITE_DATA_RULES,
|
||||||
|
g_param_spec_string (
|
||||||
|
"site-data-rules",
|
||||||
|
"Rules for accepting, denying and preserving cookies and other data",
|
||||||
|
"Cookies, HTML5 databases, local storage and application cache blocking",
|
||||||
|
NULL,
|
||||||
|
flags));
|
||||||
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
||||||
/**
|
/**
|
||||||
* MidoriWebSettings:enable-dns-prefetching:
|
* MidoriWebSettings:enable-dns-prefetching:
|
||||||
|
@ -1180,6 +1231,74 @@ midori_web_settings_finalize (GObject* object)
|
||||||
G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
|
G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* midori_web_settings_has_plugin_support:
|
||||||
|
*
|
||||||
|
* Determines if Netscape plugins are supported.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if Netscape plugins can be used
|
||||||
|
*
|
||||||
|
* Since: 0.4.4
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
midori_web_settings_has_plugin_support (void)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
|
return g_getenv ("MIDORI_UNARMED") == NULL
|
||||||
|
&& g_strcmp0 (g_getenv ("MOZ_PLUGIN_PATH"), "/");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* midori_web_settings_get_site_data_policy:
|
||||||
|
*
|
||||||
|
* Tests if @uri may store site data.
|
||||||
|
*
|
||||||
|
* Returns: a #MidoriSiteDataPolicy
|
||||||
|
*
|
||||||
|
* Since: 0.4.4
|
||||||
|
**/
|
||||||
|
MidoriSiteDataPolicy
|
||||||
|
midori_web_settings_get_site_data_policy (MidoriWebSettings* settings,
|
||||||
|
const gchar* uri)
|
||||||
|
{
|
||||||
|
MidoriSiteDataPolicy policy = MIDORI_SITE_DATA_UNDETERMINED;
|
||||||
|
gchar* hostname;
|
||||||
|
const gchar* match;
|
||||||
|
|
||||||
|
g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), policy);
|
||||||
|
|
||||||
|
if (!(settings->site_data_rules && *settings->site_data_rules))
|
||||||
|
return policy;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values prefixed with "-" are always blocked
|
||||||
|
* Values prefixed with "+" are always accepted
|
||||||
|
* Values prefixed with "!" are not cleared in Clear Private Data
|
||||||
|
* FIXME: "*" is a wildcard
|
||||||
|
* FIXME: indicate type of storage the rule applies to
|
||||||
|
* FIXME: support matching of the whole URI
|
||||||
|
**/
|
||||||
|
hostname = midori_uri_parse_hostname (uri, NULL);
|
||||||
|
match = strstr (settings->site_data_rules, hostname ? hostname : uri);
|
||||||
|
if (match != NULL && match != settings->site_data_rules)
|
||||||
|
{
|
||||||
|
const gchar* prefix = match - 1;
|
||||||
|
if (*prefix == '-')
|
||||||
|
policy = MIDORI_SITE_DATA_BLOCK;
|
||||||
|
else if (*prefix == '+')
|
||||||
|
policy = MIDORI_SITE_DATA_ACCEPT;
|
||||||
|
else if (*prefix == '!')
|
||||||
|
policy = MIDORI_SITE_DATA_PRESERVE;
|
||||||
|
else
|
||||||
|
g_warning ("%s: Matched with no prefix '%s'", G_STRFUNC, match);
|
||||||
|
}
|
||||||
|
g_free (hostname);
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
#if (!HAVE_OSX && defined (G_OS_UNIX)) || defined (G_OS_WIN32)
|
#if (!HAVE_OSX && defined (G_OS_UNIX)) || defined (G_OS_WIN32)
|
||||||
static gchar*
|
static gchar*
|
||||||
get_sys_name (gchar** architecture)
|
get_sys_name (gchar** architecture)
|
||||||
|
@ -1544,6 +1663,9 @@ midori_web_settings_set_property (GObject* object,
|
||||||
case PROP_CLEAR_DATA:
|
case PROP_CLEAR_DATA:
|
||||||
katze_assign (web_settings->clear_data, g_value_dup_string (value));
|
katze_assign (web_settings->clear_data, g_value_dup_string (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_SITE_DATA_RULES:
|
||||||
|
katze_assign (web_settings->site_data_rules, g_value_dup_string (value));
|
||||||
|
break;
|
||||||
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
||||||
case PROP_ENABLE_DNS_PREFETCHING:
|
case PROP_ENABLE_DNS_PREFETCHING:
|
||||||
web_settings->enable_dns_prefetching = g_value_get_boolean (value);
|
web_settings->enable_dns_prefetching = g_value_get_boolean (value);
|
||||||
|
@ -1574,6 +1696,14 @@ midori_web_settings_set_property (GObject* object,
|
||||||
case PROP_FLASH_WINDOW_ON_BG_TABS:
|
case PROP_FLASH_WINDOW_ON_BG_TABS:
|
||||||
web_settings->flash_window_on_bg_tabs = g_value_get_boolean (value);
|
web_settings->flash_window_on_bg_tabs = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLE_WEBGL:
|
||||||
|
g_object_set (web_settings, "WebKitWebSettings::enable-webgl",
|
||||||
|
g_value_get_boolean (value), NULL);
|
||||||
|
break;
|
||||||
|
case PROP_ENABLE_FULLSCREEN:
|
||||||
|
g_object_set (web_settings, "WebKitWebSettings::enable-fullscreen",
|
||||||
|
g_value_get_boolean (value), NULL);
|
||||||
|
break;
|
||||||
case PROP_USER_STYLESHEET_URI:
|
case PROP_USER_STYLESHEET_URI:
|
||||||
{
|
{
|
||||||
gint old_len = web_settings->user_stylesheet_uri_cached
|
gint old_len = web_settings->user_stylesheet_uri_cached
|
||||||
|
@ -1845,6 +1975,9 @@ midori_web_settings_get_property (GObject* object,
|
||||||
case PROP_CLEAR_DATA:
|
case PROP_CLEAR_DATA:
|
||||||
g_value_set_string (value, web_settings->clear_data);
|
g_value_set_string (value, web_settings->clear_data);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SITE_DATA_RULES:
|
||||||
|
g_value_set_string (value, web_settings->site_data_rules);
|
||||||
|
break;
|
||||||
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
#if !WEBKIT_CHECK_VERSION (1, 3, 13)
|
||||||
case PROP_ENABLE_DNS_PREFETCHING:
|
case PROP_ENABLE_DNS_PREFETCHING:
|
||||||
g_value_set_boolean (value, web_settings->enable_dns_prefetching);
|
g_value_set_boolean (value, web_settings->enable_dns_prefetching);
|
||||||
|
@ -1859,6 +1992,14 @@ midori_web_settings_get_property (GObject* object,
|
||||||
case PROP_FLASH_WINDOW_ON_BG_TABS:
|
case PROP_FLASH_WINDOW_ON_BG_TABS:
|
||||||
g_value_set_boolean (value, web_settings->flash_window_on_bg_tabs);
|
g_value_set_boolean (value, web_settings->flash_window_on_bg_tabs);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ENABLE_WEBGL:
|
||||||
|
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||||
|
"WebKitWebSettings::enable-webgl"));
|
||||||
|
break;
|
||||||
|
case PROP_ENABLE_FULLSCREEN:
|
||||||
|
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||||
|
"WebKitWebSettings::enable-fullscreen"));
|
||||||
|
break;
|
||||||
case PROP_USER_STYLESHEET_URI:
|
case PROP_USER_STYLESHEET_URI:
|
||||||
g_value_take_string (value, katze_object_get_string (web_settings,
|
g_value_take_string (value, katze_object_get_string (web_settings,
|
||||||
"WebKitWebSettings::user-stylesheet-uri"));
|
"WebKitWebSettings::user-stylesheet-uri"));
|
||||||
|
|
|
@ -173,6 +173,21 @@ const gchar*
|
||||||
midori_web_settings_get_system_name (gchar** architecture,
|
midori_web_settings_get_system_name (gchar** architecture,
|
||||||
gchar** platform);
|
gchar** platform);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
midori_web_settings_has_plugin_support (void);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MIDORI_SITE_DATA_UNDETERMINED,
|
||||||
|
MIDORI_SITE_DATA_BLOCK,
|
||||||
|
MIDORI_SITE_DATA_ACCEPT,
|
||||||
|
MIDORI_SITE_DATA_PRESERVE,
|
||||||
|
} MidoriSiteDataPolicy;
|
||||||
|
|
||||||
|
MidoriSiteDataPolicy
|
||||||
|
midori_web_settings_get_site_data_policy (MidoriWebSettings* settings,
|
||||||
|
const gchar* uri);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __MIDORI_WEB_SETTINGS_H__ */
|
#endif /* __MIDORI_WEB_SETTINGS_H__ */
|
||||||
|
|
223
midori/socket.c
223
midori/socket.c
|
@ -54,9 +54,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#if USE_SSL
|
|
||||||
# include <openssl/ssl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
# define debug_print g_debug
|
# define debug_print g_debug
|
||||||
|
@ -562,10 +559,6 @@ gboolean sock_has_read_data(SockInfo *sock)
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
gulong val;
|
gulong val;
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return TRUE;
|
|
||||||
#endif
|
|
||||||
if (ioctlsocket(sock->sock, FIONREAD, &val) < 0) {
|
if (ioctlsocket(sock->sock, FIONREAD, &val) < 0) {
|
||||||
g_warning("sock_has_read_data(): ioctlsocket() failed: %d\n",
|
g_warning("sock_has_read_data(): ioctlsocket() failed: %d\n",
|
||||||
WSAGetLastError());
|
WSAGetLastError());
|
||||||
|
@ -595,22 +588,6 @@ static gboolean sock_check(GSource *source)
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
GIOCondition condition = sock->condition;
|
GIOCondition condition = sock->condition;
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl) {
|
|
||||||
if (condition & G_IO_IN) {
|
|
||||||
if (SSL_pending(sock->ssl) > 0)
|
|
||||||
return TRUE;
|
|
||||||
if (SSL_want_write(sock->ssl))
|
|
||||||
condition |= G_IO_OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (condition & G_IO_OUT) {
|
|
||||||
if (SSL_want_read(sock->ssl))
|
|
||||||
condition |= G_IO_IN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(sock->sock, &fds);
|
FD_SET(sock->sock, &fds);
|
||||||
|
|
||||||
|
@ -647,19 +624,6 @@ guint sock_add_watch(SockInfo *sock, GIOCondition condition, SockFunc func,
|
||||||
sock->callback = func;
|
sock->callback = func;
|
||||||
sock->condition = condition;
|
sock->condition = condition;
|
||||||
sock->data = data;
|
sock->data = data;
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl) {
|
|
||||||
GSource *source;
|
|
||||||
|
|
||||||
source = g_source_new(&sock_watch_funcs, sizeof(SockSource));
|
|
||||||
((SockSource *)source)->sock = sock;
|
|
||||||
g_source_set_priority(source, G_PRIORITY_DEFAULT);
|
|
||||||
g_source_set_can_recurse(source, FALSE);
|
|
||||||
return g_source_attach(source, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return g_io_add_watch(sock->sock_ch, condition, sock_watch_cb, sock);
|
return g_io_add_watch(sock->sock_ch, condition, sock_watch_cb, sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1375,10 +1339,6 @@ gint sock_read(SockInfo *sock, gchar *buf, gint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_read(sock->ssl, buf, len);
|
|
||||||
#endif
|
|
||||||
return fd_read(sock->sock, buf, len);
|
return fd_read(sock->sock, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1394,44 +1354,10 @@ gint fd_read(gint fd, gchar *buf, gint len)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_read(SSL *ssl, gchar *buf, gint len)
|
|
||||||
{
|
|
||||||
gint err, ret;
|
|
||||||
|
|
||||||
if (SSL_pending(ssl) == 0) {
|
|
||||||
if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = SSL_read(ssl, buf, len);
|
|
||||||
|
|
||||||
switch ((err = SSL_get_error(ssl, ret))) {
|
|
||||||
case SSL_ERROR_NONE:
|
|
||||||
return ret;
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
errno = EAGAIN;
|
|
||||||
return -1;
|
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
g_warning("SSL_read() returned error %d, ret = %d\n", err, ret);
|
|
||||||
if (ret == 0)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint sock_write(SockInfo *sock, const gchar *buf, gint len)
|
gint sock_write(SockInfo *sock, const gchar *buf, gint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_write(sock->ssl, buf, len);
|
|
||||||
#endif
|
|
||||||
return fd_write(sock->sock, buf, len);
|
return fd_write(sock->sock, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,34 +1385,10 @@ gint fd_write(gint fd, const gchar *buf, gint len)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_write(SSL *ssl, const gchar *buf, gint len)
|
|
||||||
{
|
|
||||||
gint ret;
|
|
||||||
|
|
||||||
ret = SSL_write(ssl, buf, len);
|
|
||||||
|
|
||||||
switch (SSL_get_error(ssl, ret)) {
|
|
||||||
case SSL_ERROR_NONE:
|
|
||||||
return ret;
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
errno = EAGAIN;
|
|
||||||
return -1;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint sock_write_all(SockInfo *sock, const gchar *buf, gint len)
|
gint sock_write_all(SockInfo *sock, const gchar *buf, gint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_write_all(sock->ssl, buf, len);
|
|
||||||
#endif
|
|
||||||
return fd_write_all(sock->sock, buf, len);
|
return fd_write_all(sock->sock, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1506,24 +1408,6 @@ gint fd_write_all(gint fd, const gchar *buf, gint len)
|
||||||
return wrlen;
|
return wrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_write_all(SSL *ssl, const gchar *buf, gint len)
|
|
||||||
{
|
|
||||||
gint n, wrlen = 0;
|
|
||||||
|
|
||||||
while (len) {
|
|
||||||
n = ssl_write(ssl, buf, len);
|
|
||||||
if (n <= 0)
|
|
||||||
return -1;
|
|
||||||
len -= n;
|
|
||||||
wrlen += n;
|
|
||||||
buf += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrlen;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint fd_recv(gint fd, gchar *buf, gint len, gint flags)
|
gint fd_recv(gint fd, gchar *buf, gint len, gint flags)
|
||||||
{
|
{
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
@ -1570,38 +1454,10 @@ gint fd_gets(gint fd, gchar *buf, gint len)
|
||||||
return bp - buf;
|
return bp - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_gets(SSL *ssl, gchar *buf, gint len)
|
|
||||||
{
|
|
||||||
gchar *newline, *bp = buf;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
if (--len < 1)
|
|
||||||
return -1;
|
|
||||||
do {
|
|
||||||
if ((n = ssl_peek(ssl, bp, len)) <= 0)
|
|
||||||
return -1;
|
|
||||||
if ((newline = memchr(bp, '\n', n)) != NULL)
|
|
||||||
n = newline - bp + 1;
|
|
||||||
if ((n = ssl_read(ssl, bp, n)) < 0)
|
|
||||||
return -1;
|
|
||||||
bp += n;
|
|
||||||
len -= n;
|
|
||||||
} while (!newline && len);
|
|
||||||
|
|
||||||
*bp = '\0';
|
|
||||||
return bp - buf;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint sock_gets(SockInfo *sock, gchar *buf, gint len)
|
gint sock_gets(SockInfo *sock, gchar *buf, gint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_gets(sock->ssl, buf, len);
|
|
||||||
#endif
|
|
||||||
return fd_gets(sock->sock, buf, len);
|
return fd_gets(sock->sock, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1630,42 +1486,11 @@ gint fd_getline(gint fd, gchar **line)
|
||||||
return (gint)size;
|
return (gint)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_getline(SSL *ssl, gchar **line)
|
|
||||||
{
|
|
||||||
gchar buf[BUFFSIZE];
|
|
||||||
gchar *str = NULL;
|
|
||||||
gint len;
|
|
||||||
gulong size = 0;
|
|
||||||
gulong cur_offset = 0;
|
|
||||||
|
|
||||||
while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) {
|
|
||||||
size += len;
|
|
||||||
str = g_realloc(str, size + 1);
|
|
||||||
memcpy(str + cur_offset, buf, len + 1);
|
|
||||||
cur_offset += len;
|
|
||||||
if (buf[len - 1] == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*line = str;
|
|
||||||
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return (gint)size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint sock_getline(SockInfo *sock, gchar **line)
|
gint sock_getline(SockInfo *sock, gchar **line)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
g_return_val_if_fail(line != NULL, -1);
|
g_return_val_if_fail(line != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_getline(sock->ssl, line);
|
|
||||||
#endif
|
|
||||||
return fd_getline(sock->sock, line);
|
return fd_getline(sock->sock, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1679,44 +1504,10 @@ gint sock_puts(SockInfo *sock, const gchar *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* peek at the socket data without actually reading it */
|
/* peek at the socket data without actually reading it */
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_peek(SSL *ssl, gchar *buf, gint len)
|
|
||||||
{
|
|
||||||
gint err, ret;
|
|
||||||
|
|
||||||
if (SSL_pending(ssl) == 0) {
|
|
||||||
if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = SSL_peek(ssl, buf, len);
|
|
||||||
|
|
||||||
switch ((err = SSL_get_error(ssl, ret))) {
|
|
||||||
case SSL_ERROR_NONE:
|
|
||||||
return ret;
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
errno = EAGAIN;
|
|
||||||
return -1;
|
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret);
|
|
||||||
if (ret == 0)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint sock_peek(SockInfo *sock, gchar *buf, gint len)
|
gint sock_peek(SockInfo *sock, gchar *buf, gint len)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail(sock != NULL, -1);
|
g_return_val_if_fail(sock != NULL, -1);
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
return ssl_peek(sock->ssl, buf, len);
|
|
||||||
#endif
|
|
||||||
return fd_recv(sock->sock, buf, len, MSG_PEEK);
|
return fd_recv(sock->sock, buf, len, MSG_PEEK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1727,11 +1518,6 @@ gint sock_close(SockInfo *sock)
|
||||||
if (!sock)
|
if (!sock)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
if (sock->ssl)
|
|
||||||
ssl_done_socket(sock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sock->sock_ch) {
|
if (sock->sock_ch) {
|
||||||
g_io_channel_shutdown(sock->sock_ch, FALSE, NULL);
|
g_io_channel_shutdown(sock->sock_ch, FALSE, NULL);
|
||||||
g_io_channel_unref(sock->sock_ch);
|
g_io_channel_unref(sock->sock_ch);
|
||||||
|
@ -1759,13 +1545,4 @@ gint fd_close(gint fd)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
void ssl_done_socket(SockInfo *sockinfo)
|
|
||||||
{
|
|
||||||
if (sockinfo->ssl) {
|
|
||||||
SSL_free(sockinfo->ssl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,10 +20,6 @@
|
||||||
|
|
||||||
typedef struct _SockInfo SockInfo;
|
typedef struct _SockInfo SockInfo;
|
||||||
|
|
||||||
#if USE_SSL
|
|
||||||
# include <openssl/ssl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CONN_READY,
|
CONN_READY,
|
||||||
|
@ -42,11 +38,6 @@ typedef gboolean (*SockFunc) (SockInfo *sock,
|
||||||
struct _SockInfo
|
struct _SockInfo
|
||||||
{
|
{
|
||||||
gint sock;
|
gint sock;
|
||||||
#if USE_SSL
|
|
||||||
SSL *ssl;
|
|
||||||
#else
|
|
||||||
gpointer ssl;
|
|
||||||
#endif
|
|
||||||
GIOChannel *sock_ch;
|
GIOChannel *sock_ch;
|
||||||
|
|
||||||
gchar *hostname;
|
gchar *hostname;
|
||||||
|
@ -111,15 +102,4 @@ gint fd_gets (gint sock, gchar *buf, gint len);
|
||||||
gint fd_getline (gint sock, gchar **line);
|
gint fd_getline (gint sock, gchar **line);
|
||||||
gint fd_close (gint sock);
|
gint fd_close (gint sock);
|
||||||
|
|
||||||
/* Functions for SSL */
|
|
||||||
#if USE_SSL
|
|
||||||
gint ssl_read (SSL *ssl, gchar *buf, gint len);
|
|
||||||
gint ssl_write (SSL *ssl, const gchar *buf, gint len);
|
|
||||||
gint ssl_write_all (SSL *ssl, const gchar *buf, gint len);
|
|
||||||
gint ssl_gets (SSL *ssl, gchar *buf, gint len);
|
|
||||||
gint ssl_getline (SSL *ssl, gchar **line);
|
|
||||||
gint ssl_peek (SSL *ssl, gchar *buf, gint len);
|
|
||||||
void ssl_done_socket (SockInfo *sockinfo);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __SYLPH_SOCKET_H__ */
|
#endif /* __SYLPH_SOCKET_H__ */
|
||||||
|
|
144
midori/sokoke.c
144
midori/sokoke.c
|
@ -64,13 +64,15 @@ sokoke_js_script_eval (JSContextRef js_context,
|
||||||
{
|
{
|
||||||
gchar* value;
|
gchar* value;
|
||||||
JSStringRef js_value_string;
|
JSStringRef js_value_string;
|
||||||
|
JSStringRef js_script;
|
||||||
|
JSValueRef js_exception = NULL;
|
||||||
|
JSValueRef js_value;
|
||||||
|
|
||||||
g_return_val_if_fail (js_context, FALSE);
|
g_return_val_if_fail (js_context, FALSE);
|
||||||
g_return_val_if_fail (script, FALSE);
|
g_return_val_if_fail (script, FALSE);
|
||||||
|
|
||||||
JSStringRef js_script = JSStringCreateWithUTF8CString (script);
|
js_script = JSStringCreateWithUTF8CString (script);
|
||||||
JSValueRef js_exception = NULL;
|
js_value = JSEvaluateScript (js_context, js_script,
|
||||||
JSValueRef js_value = JSEvaluateScript (js_context, js_script,
|
|
||||||
JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
|
JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
|
||||||
JSStringRelease (js_script);
|
JSStringRelease (js_script);
|
||||||
|
|
||||||
|
@ -649,7 +651,7 @@ sokoke_magic_uri (const gchar* uri)
|
||||||
|
|
||||||
/* Add file:// if we have a local path */
|
/* Add file:// if we have a local path */
|
||||||
if (g_path_is_absolute (uri))
|
if (g_path_is_absolute (uri))
|
||||||
return g_strconcat ("file://", uri, NULL);
|
return g_filename_to_uri (uri, NULL, NULL);
|
||||||
/* Parse geo URI geo:48.202778,16.368472;crs=wgs84;u=40 as a location */
|
/* Parse geo URI geo:48.202778,16.368472;crs=wgs84;u=40 as a location */
|
||||||
if (!strncmp (uri, "geo:", 4))
|
if (!strncmp (uri, "geo:", 4))
|
||||||
{
|
{
|
||||||
|
@ -684,7 +686,7 @@ sokoke_magic_uri (const gchar* uri)
|
||||||
search = NULL;
|
search = NULL;
|
||||||
if (!strchr (uri, ' ') &&
|
if (!strchr (uri, ' ') &&
|
||||||
((search = strchr (uri, ':')) || (search = strchr (uri, '@'))) &&
|
((search = strchr (uri, ':')) || (search = strchr (uri, '@'))) &&
|
||||||
search[0] && !g_ascii_isalpha (search[1]))
|
search[0] && g_ascii_isdigit (search[1]))
|
||||||
return g_strconcat ("http://", uri, NULL);
|
return g_strconcat ("http://", uri, NULL);
|
||||||
if ((!strcmp (uri, "localhost") || strchr (uri, '/'))
|
if ((!strcmp (uri, "localhost") || strchr (uri, '/'))
|
||||||
&& sokoke_resolve_hostname (uri))
|
&& sokoke_resolve_hostname (uri))
|
||||||
|
@ -793,7 +795,6 @@ sokoke_xfce_header_new (const gchar* icon,
|
||||||
if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
|
if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
|
||||||
{
|
{
|
||||||
GtkWidget* entry;
|
GtkWidget* entry;
|
||||||
GtkStyle* style;
|
|
||||||
gchar* markup;
|
gchar* markup;
|
||||||
GtkWidget* xfce_heading;
|
GtkWidget* xfce_heading;
|
||||||
GtkWidget* hbox;
|
GtkWidget* hbox;
|
||||||
|
@ -804,9 +805,7 @@ sokoke_xfce_header_new (const gchar* icon,
|
||||||
|
|
||||||
xfce_heading = gtk_event_box_new ();
|
xfce_heading = gtk_event_box_new ();
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
style = gtk_widget_get_style (entry);
|
|
||||||
gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
|
|
||||||
&style->base[GTK_STATE_NORMAL]);
|
|
||||||
hbox = gtk_hbox_new (FALSE, 12);
|
hbox = gtk_hbox_new (FALSE, 12);
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
|
||||||
if (icon)
|
if (icon)
|
||||||
|
@ -816,8 +815,6 @@ sokoke_xfce_header_new (const gchar* icon,
|
||||||
GTK_ICON_SIZE_DIALOG);
|
GTK_ICON_SIZE_DIALOG);
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
||||||
label = gtk_label_new (NULL);
|
label = gtk_label_new (NULL);
|
||||||
gtk_widget_modify_fg (label, GTK_STATE_NORMAL
|
|
||||||
, &style->text[GTK_STATE_NORMAL]);
|
|
||||||
markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
|
markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
|
||||||
title);
|
title);
|
||||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||||
|
@ -826,6 +823,16 @@ sokoke_xfce_header_new (const gchar* icon,
|
||||||
g_free (markup);
|
g_free (markup);
|
||||||
gtk_widget_destroy (entry);
|
gtk_widget_destroy (entry);
|
||||||
|
|
||||||
|
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||||
|
{
|
||||||
|
GtkStyle* style = gtk_widget_get_style (entry);
|
||||||
|
gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
|
||||||
|
&style->base[GTK_STATE_NORMAL]);
|
||||||
|
gtk_widget_modify_fg (label, GTK_STATE_NORMAL
|
||||||
|
, &style->text[GTK_STATE_NORMAL]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vbox = gtk_vbox_new (FALSE, 0);
|
vbox = gtk_vbox_new (FALSE, 0);
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), xfce_heading, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), xfce_heading, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
@ -1029,37 +1036,6 @@ sokoke_time_t_to_julian (const time_t* timestamp)
|
||||||
return julian;
|
return julian;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* sokoke_days_between:
|
|
||||||
* @day1: a time_t timestamp value
|
|
||||||
* @day2: a time_t timestamp value
|
|
||||||
*
|
|
||||||
* Calculates the number of days between two timestamps.
|
|
||||||
*
|
|
||||||
* Return value: an integer.
|
|
||||||
**/
|
|
||||||
gint
|
|
||||||
sokoke_days_between (const time_t* day1,
|
|
||||||
const time_t* day2)
|
|
||||||
{
|
|
||||||
GDate* date1;
|
|
||||||
GDate* date2;
|
|
||||||
gint age;
|
|
||||||
|
|
||||||
date1 = g_date_new ();
|
|
||||||
date2 = g_date_new ();
|
|
||||||
|
|
||||||
g_date_set_time_t (date1, *day1);
|
|
||||||
g_date_set_time_t (date2, *day2);
|
|
||||||
|
|
||||||
age = g_date_days_between (date1, date2);
|
|
||||||
|
|
||||||
g_date_free (date1);
|
|
||||||
g_date_free (date2);
|
|
||||||
|
|
||||||
return age;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sokoke_set_config_dir:
|
* sokoke_set_config_dir:
|
||||||
* @new_config_dir: an absolute path, or %NULL
|
* @new_config_dir: an absolute path, or %NULL
|
||||||
|
@ -1731,3 +1707,87 @@ midori_download_prepare_tooltip_text (WebKitDownload* download)
|
||||||
return g_string_free (tooltip, FALSE);
|
return g_string_free (tooltip, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sokoke_entry_has_placeholder_text (GtkEntry* entry)
|
||||||
|
{
|
||||||
|
const gchar* text = gtk_entry_get_text (entry);
|
||||||
|
const gchar* hint = gtk_entry_get_placeholder_text (entry);
|
||||||
|
if (!gtk_widget_has_focus (GTK_WIDGET (entry))
|
||||||
|
&& hint != NULL
|
||||||
|
&& (text == NULL || !strcmp (text, hint)))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sokoke_entry_changed_cb (GtkEditable* editable,
|
||||||
|
GtkEntry* entry)
|
||||||
|
{
|
||||||
|
const gchar* text = gtk_entry_get_text (entry);
|
||||||
|
gboolean visible = text && *text
|
||||||
|
&& ! sokoke_entry_has_placeholder_text (entry);
|
||||||
|
gtk_icon_entry_set_icon_from_stock (
|
||||||
|
GTK_ICON_ENTRY (entry),
|
||||||
|
GTK_ICON_ENTRY_SECONDARY,
|
||||||
|
visible ? GTK_STOCK_CLEAR : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sokoke_entry_focus_out_event_cb (GtkEditable* editable,
|
||||||
|
GdkEventFocus* event,
|
||||||
|
GtkEntry* entry)
|
||||||
|
{
|
||||||
|
sokoke_entry_changed_cb (editable, entry);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sokoke_entry_icon_released_cb (GtkEntry* entry,
|
||||||
|
GtkIconEntryPosition icon_pos,
|
||||||
|
GdkEvent* event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (icon_pos != GTK_ICON_ENTRY_SECONDARY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_entry_set_text (entry, "");
|
||||||
|
gtk_widget_grab_focus (GTK_WIDGET (entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sokoke_entry_set_clear_button_visible (GtkEntry* entry,
|
||||||
|
gboolean visible)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||||
|
|
||||||
|
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||||
|
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
g_object_connect (entry,
|
||||||
|
"signal::icon-release",
|
||||||
|
G_CALLBACK (sokoke_entry_icon_released_cb), NULL,
|
||||||
|
"signal::focus-in-event",
|
||||||
|
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
|
||||||
|
"signal::focus-out-event",
|
||||||
|
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
|
||||||
|
"signal::changed",
|
||||||
|
G_CALLBACK (sokoke_entry_changed_cb), entry, NULL);
|
||||||
|
sokoke_entry_changed_cb ((GtkEditable*)entry, entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_object_disconnect (entry,
|
||||||
|
"any_signal::icon-release",
|
||||||
|
G_CALLBACK (sokoke_entry_icon_released_cb), NULL,
|
||||||
|
"any_signal::focus-in-event",
|
||||||
|
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
|
||||||
|
"any_signal::focus-out-event",
|
||||||
|
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
|
||||||
|
"any_signal::changed",
|
||||||
|
G_CALLBACK (sokoke_entry_changed_cb), entry, NULL);
|
||||||
|
gtk_icon_entry_set_icon_from_stock (
|
||||||
|
GTK_ICON_ENTRY (entry), GTK_ICON_ENTRY_SECONDARY, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,10 +121,6 @@ sokoke_action_create_popup_menu_item (GtkAction* action);
|
||||||
gint64
|
gint64
|
||||||
sokoke_time_t_to_julian (const time_t* timestamp);
|
sokoke_time_t_to_julian (const time_t* timestamp);
|
||||||
|
|
||||||
gint
|
|
||||||
sokoke_days_between (const time_t* day1,
|
|
||||||
const time_t* day2);
|
|
||||||
|
|
||||||
const gchar*
|
const gchar*
|
||||||
sokoke_set_config_dir (const gchar* new_config_dir);
|
sokoke_set_config_dir (const gchar* new_config_dir);
|
||||||
|
|
||||||
|
@ -202,4 +198,8 @@ sokoke_build_thumbnail_path (const gchar* name);
|
||||||
gchar*
|
gchar*
|
||||||
midori_download_prepare_tooltip_text (WebKitDownload* download);
|
midori_download_prepare_tooltip_text (WebKitDownload* download);
|
||||||
|
|
||||||
|
void
|
||||||
|
sokoke_entry_set_clear_button_visible (GtkEntry* entry,
|
||||||
|
gboolean visible);
|
||||||
|
|
||||||
#endif /* !__SOKOKE_H__ */
|
#endif /* !__SOKOKE_H__ */
|
||||||
|
|
|
@ -7,7 +7,7 @@ import platform
|
||||||
|
|
||||||
progressive = True
|
progressive = True
|
||||||
libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \
|
libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \
|
||||||
'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 OPENSSL HILDON' \
|
'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 HILDON' \
|
||||||
'HILDON_FM'
|
'HILDON_FM'
|
||||||
|
|
||||||
if progressive or Options.commands['check']:
|
if progressive or Options.commands['check']:
|
||||||
|
|
|
@ -925,11 +925,7 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks)
|
||||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||||
GTK_ICON_ENTRY_PRIMARY,
|
GTK_ICON_ENTRY_PRIMARY,
|
||||||
GTK_STOCK_FIND);
|
GTK_STOCK_FIND);
|
||||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
|
||||||
GTK_ICON_ENTRY_SECONDARY,
|
|
||||||
GTK_STOCK_CLEAR);
|
|
||||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
|
||||||
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
|
||||||
g_signal_connect (entry, "icon-release",
|
g_signal_connect (entry, "icon-release",
|
||||||
G_CALLBACK (midori_bookmarks_filter_entry_clear_cb), bookmarks);
|
G_CALLBACK (midori_bookmarks_filter_entry_clear_cb), bookmarks);
|
||||||
g_signal_connect (entry, "changed",
|
g_signal_connect (entry, "changed",
|
||||||
|
|
|
@ -116,18 +116,59 @@ midori_history_get_stock_id (MidoriViewable* viewable)
|
||||||
return STOCK_HISTORY;
|
return STOCK_HISTORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 26, 0)
|
||||||
|
static gint
|
||||||
|
sokoke_days_between (const time_t* day1,
|
||||||
|
const time_t* day2)
|
||||||
|
{
|
||||||
|
GDate* date1;
|
||||||
|
GDate* date2;
|
||||||
|
gint age;
|
||||||
|
|
||||||
|
date1 = g_date_new ();
|
||||||
|
date2 = g_date_new ();
|
||||||
|
|
||||||
|
g_date_set_time_t (date1, *day1);
|
||||||
|
g_date_set_time_t (date2, *day2);
|
||||||
|
|
||||||
|
age = g_date_days_between (date1, date2);
|
||||||
|
|
||||||
|
g_date_free (date1);
|
||||||
|
g_date_free (date2);
|
||||||
|
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gchar*
|
static gchar*
|
||||||
midori_history_format_date (KatzeItem *item)
|
midori_history_format_date (KatzeItem *item)
|
||||||
{
|
{
|
||||||
gint age;
|
gint64 day = katze_item_get_added (item);
|
||||||
gint64 day;
|
|
||||||
gchar token[50];
|
|
||||||
gchar* sdate;
|
gchar* sdate;
|
||||||
|
gint age;
|
||||||
|
#if GLIB_CHECK_VERSION (2, 26, 0)
|
||||||
|
GDateTime* now = g_date_time_new_now_local ();
|
||||||
|
GDateTime* then = g_date_time_new_from_unix_local (day);
|
||||||
|
age = g_date_time_get_day_of_year (now) - g_date_time_get_day_of_year (then);
|
||||||
|
if (g_date_time_get_year (now) != g_date_time_get_year (then))
|
||||||
|
age = 999;
|
||||||
|
|
||||||
|
if (age == 0)
|
||||||
|
sdate = g_strdup (_("Today"));
|
||||||
|
else if (age == 1)
|
||||||
|
sdate = g_strdup (_("Yesterday"));
|
||||||
|
else if (age < 7)
|
||||||
|
sdate = g_strdup_printf (ngettext ("%d day ago",
|
||||||
|
"%d days ago", (gint)age), (gint)age);
|
||||||
|
else if (age == 7)
|
||||||
|
sdate = g_strdup (_("A week ago"));
|
||||||
|
else
|
||||||
|
sdate = g_date_time_format (then, "%x");
|
||||||
|
#else
|
||||||
|
gchar token[50];
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
|
|
||||||
current_time = time (NULL);
|
current_time = time (NULL);
|
||||||
day = katze_item_get_added (item);
|
|
||||||
|
|
||||||
age = sokoke_days_between ((time_t*)&day, ¤t_time);
|
age = sokoke_days_between ((time_t*)&day, ¤t_time);
|
||||||
|
|
||||||
/* A negative age is a date in the future, the clock is probably off */
|
/* A negative age is a date in the future, the clock is probably off */
|
||||||
|
@ -147,6 +188,7 @@ midori_history_format_date (KatzeItem *item)
|
||||||
sdate = g_strdup (_("Today"));
|
sdate = g_strdup (_("Today"));
|
||||||
else
|
else
|
||||||
sdate = g_strdup (_("Yesterday"));
|
sdate = g_strdup (_("Yesterday"));
|
||||||
|
#endif
|
||||||
return sdate;
|
return sdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +454,8 @@ midori_history_add_item_cb (KatzeArray* array,
|
||||||
GtkTreeModel* model = gtk_tree_view_get_model (treeview);
|
GtkTreeModel* model = gtk_tree_view_get_model (treeview);
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
KatzeItem* today;
|
KatzeItem* today;
|
||||||
time_t current_time;
|
time_t current_time = time (NULL);
|
||||||
|
|
||||||
current_time = time (NULL);
|
|
||||||
if (gtk_tree_model_iter_children (model, &iter, NULL))
|
if (gtk_tree_model_iter_children (model, &iter, NULL))
|
||||||
{
|
{
|
||||||
gint64 day;
|
gint64 day;
|
||||||
|
@ -423,7 +464,18 @@ midori_history_add_item_cb (KatzeArray* array,
|
||||||
gtk_tree_model_get (model, &iter, 0, &today, -1);
|
gtk_tree_model_get (model, &iter, 0, &today, -1);
|
||||||
|
|
||||||
day = katze_item_get_added (today);
|
day = katze_item_get_added (today);
|
||||||
|
#if GLIB_CHECK_VERSION (2, 26, 0)
|
||||||
|
has_today = g_date_time_get_day_of_month (
|
||||||
|
g_date_time_new_from_unix_local (day))
|
||||||
|
== g_date_time_get_day_of_month (
|
||||||
|
g_date_time_new_from_unix_local (current_time))
|
||||||
|
&& g_date_time_get_day_of_year (
|
||||||
|
g_date_time_new_from_unix_local (day))
|
||||||
|
== g_date_time_get_day_of_year (
|
||||||
|
g_date_time_new_from_unix_local (current_time));
|
||||||
|
#else
|
||||||
has_today = sokoke_days_between ((time_t*)&day, ¤t_time) == 0;
|
has_today = sokoke_days_between ((time_t*)&day, ¤t_time) == 0;
|
||||||
|
#endif
|
||||||
g_object_unref (today);
|
g_object_unref (today);
|
||||||
if (has_today)
|
if (has_today)
|
||||||
{
|
{
|
||||||
|
@ -945,12 +997,7 @@ midori_history_init (MidoriHistory* history)
|
||||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||||
GTK_ICON_ENTRY_PRIMARY,
|
GTK_ICON_ENTRY_PRIMARY,
|
||||||
GTK_STOCK_FIND);
|
GTK_STOCK_FIND);
|
||||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
|
||||||
GTK_ICON_ENTRY_SECONDARY,
|
|
||||||
GTK_STOCK_CLEAR);
|
|
||||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
|
||||||
GTK_ICON_ENTRY_SECONDARY,
|
|
||||||
TRUE);
|
|
||||||
g_signal_connect (entry, "icon-release",
|
g_signal_connect (entry, "icon-release",
|
||||||
G_CALLBACK (midori_history_filter_entry_clear_cb), history);
|
G_CALLBACK (midori_history_filter_entry_clear_cb), history);
|
||||||
g_signal_connect (entry, "changed",
|
g_signal_connect (entry, "changed",
|
||||||
|
|
|
@ -39,7 +39,9 @@ extensions/feed-panel/feed-panel.c
|
||||||
extensions/feed-panel/feed-parse.c
|
extensions/feed-panel/feed-parse.c
|
||||||
extensions/feed-panel/feed-rss.c
|
extensions/feed-panel/feed-rss.c
|
||||||
extensions/feed-panel/main.c
|
extensions/feed-panel/main.c
|
||||||
extensions/formhistory.c
|
extensions/formhistory/formhistory.c
|
||||||
|
extensions/formhistory/formhistory-gdom-frontend.c
|
||||||
|
extensions/formhistory/formhistory-js-frontend.c
|
||||||
extensions/history-list.vala
|
extensions/history-list.vala
|
||||||
extensions/mouse-gestures.c
|
extensions/mouse-gestures.c
|
||||||
extensions/shortcuts.c
|
extensions/shortcuts.c
|
||||||
|
|
1613
po/pt_BR.po
1613
po/pt_BR.po
File diff suppressed because it is too large
Load diff
1441
po/zh_CN.po
1441
po/zh_CN.po
File diff suppressed because it is too large
Load diff
1121
po/zh_TW.po
1121
po/zh_TW.po
File diff suppressed because it is too large
Load diff
|
@ -94,6 +94,38 @@ browser_tooltips (void)
|
||||||
g_error ("Tooltip errors");
|
g_error ("Tooltip errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
browser_site_data (void)
|
||||||
|
{
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const gchar* url;
|
||||||
|
MidoriSiteDataPolicy policy;
|
||||||
|
} PolicyItem;
|
||||||
|
|
||||||
|
static const PolicyItem items[] = {
|
||||||
|
{ "google.com", MIDORI_SITE_DATA_BLOCK },
|
||||||
|
{ "facebook.com", MIDORI_SITE_DATA_BLOCK },
|
||||||
|
{ "bugzilla.gnome.org", MIDORI_SITE_DATA_PRESERVE },
|
||||||
|
{ "bugs.launchpad.net", MIDORI_SITE_DATA_ACCEPT },
|
||||||
|
};
|
||||||
|
|
||||||
|
const gchar* rules = "-google.com,-facebook.com,!bugzilla.gnome.org,+bugs.launchpad.net";
|
||||||
|
MidoriWebSettings* settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
|
||||||
|
"site-data-rules", rules, NULL);
|
||||||
|
|
||||||
|
guint i;
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (items); i++)
|
||||||
|
{
|
||||||
|
MidoriSiteDataPolicy policy = midori_web_settings_get_site_data_policy (
|
||||||
|
settings, items[i].url);
|
||||||
|
if (policy != items[i].policy)
|
||||||
|
g_error ("Match '%s' yields %d but %d expected",
|
||||||
|
items[i].url, policy, items[i].policy);
|
||||||
|
}
|
||||||
|
g_object_unref (settings);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char** argv)
|
char** argv)
|
||||||
|
@ -106,6 +138,7 @@ main (int argc,
|
||||||
|
|
||||||
g_test_add_func ("/browser/create", browser_create);
|
g_test_add_func ("/browser/create", browser_create);
|
||||||
g_test_add_func ("/browser/tooltips", browser_tooltips);
|
g_test_add_func ("/browser/tooltips", browser_tooltips);
|
||||||
|
g_test_add_func ("/browser/site_data", browser_site_data);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <midori/midori.h>
|
#include <midori/midori.h>
|
||||||
|
|
||||||
#define SM "http://www.searchmash.com/search/"
|
#define SM "http://www.searchmash.com/search/"
|
||||||
|
#define HTTP_PREFIX "midori-unit-test-expected-http-prefix"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_input (const gchar* input,
|
test_input (const gchar* input,
|
||||||
|
@ -20,6 +21,7 @@ test_input (const gchar* input,
|
||||||
{
|
{
|
||||||
static KatzeArray* search_engines = NULL;
|
static KatzeArray* search_engines = NULL;
|
||||||
gchar* uri;
|
gchar* uri;
|
||||||
|
gchar* real_expected = NULL;
|
||||||
|
|
||||||
if (G_UNLIKELY (!search_engines))
|
if (G_UNLIKELY (!search_engines))
|
||||||
{
|
{
|
||||||
|
@ -41,28 +43,29 @@ test_input (const gchar* input,
|
||||||
uri = sokoke_magic_uri (input);
|
uri = sokoke_magic_uri (input);
|
||||||
if (!uri)
|
if (!uri)
|
||||||
{
|
{
|
||||||
gchar** parts;
|
const gchar* keywords = NULL;
|
||||||
gchar* keywords = NULL;
|
|
||||||
const gchar* search_uri = NULL;
|
const gchar* search_uri = NULL;
|
||||||
|
KatzeItem* item;
|
||||||
|
|
||||||
/* Do we have a keyword and a string? */
|
/* Do we have a keyword and a string? */
|
||||||
parts = g_strsplit (input, " ", 2);
|
if ((item = katze_array_find_token (search_engines, input)))
|
||||||
if (parts[0])
|
|
||||||
{
|
{
|
||||||
KatzeItem* item;
|
keywords = strchr (input, ' ');
|
||||||
if ((item = katze_array_find_token (search_engines, parts[0])))
|
if (keywords != NULL)
|
||||||
{
|
keywords++;
|
||||||
keywords = g_strdup (parts[1] ? parts[1] : "");
|
else
|
||||||
|
keywords = "";
|
||||||
search_uri = katze_item_get_uri (item);
|
search_uri = katze_item_get_uri (item);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
g_strfreev (parts);
|
|
||||||
|
|
||||||
uri = keywords ? midori_uri_for_search (search_uri, keywords) : NULL;
|
uri = search_uri ? midori_uri_for_search (search_uri, keywords) : NULL;
|
||||||
|
|
||||||
g_free (keywords);
|
|
||||||
}
|
}
|
||||||
katze_assert_str_equal (input, uri, expected);
|
|
||||||
|
if (!g_strcmp0 (expected, HTTP_PREFIX))
|
||||||
|
real_expected = g_strconcat ("http://", input, NULL);
|
||||||
|
|
||||||
|
katze_assert_str_equal (input, uri, real_expected ? real_expected : expected);
|
||||||
|
g_free (real_expected);
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +100,13 @@ magic_uri_uri (void)
|
||||||
/* test_input ("foo:f1o2o3@bar.baz", "http://f1o2o3:foo@bar.baz"); */
|
/* test_input ("foo:f1o2o3@bar.baz", "http://f1o2o3:foo@bar.baz"); */
|
||||||
/* test_input ("foo:foo@bar.baz", "http://foo:foo@bar.baz"); */
|
/* test_input ("foo:foo@bar.baz", "http://foo:foo@bar.baz"); */
|
||||||
|
|
||||||
|
test_input ("2001:0db8:85a3:0000:0000:8a2e:0370:7334", HTTP_PREFIX);
|
||||||
|
test_input ("fe80:0:0:0:202:b3ff:fe1e:8329", HTTP_PREFIX);
|
||||||
|
test_input ("fe80::202:b3ff:fe1e:8329", HTTP_PREFIX);
|
||||||
|
test_input ("fe80::76e5:bff:fe04:38e0/64", HTTP_PREFIX);
|
||||||
|
test_input ("content::browser", NULL);
|
||||||
|
test_input ("std::copy", NULL);
|
||||||
|
|
||||||
uri = "http://bugs.launchpad.net/midori";
|
uri = "http://bugs.launchpad.net/midori";
|
||||||
g_assert_cmpstr ("bugs.launchpad.net", ==, midori_uri_parse_hostname (uri, NULL));
|
g_assert_cmpstr ("bugs.launchpad.net", ==, midori_uri_parse_hostname (uri, NULL));
|
||||||
uri = "https://bugs.launchpad.net/midori";
|
uri = "https://bugs.launchpad.net/midori";
|
||||||
|
|
|
@ -154,13 +154,13 @@ properties_object_get_set (GObject* object)
|
||||||
static void
|
static void
|
||||||
properties_object_test (gconstpointer object)
|
properties_object_test (gconstpointer object)
|
||||||
{
|
{
|
||||||
if (GTK_IS_OBJECT (object))
|
if (GTK_IS_WIDGET (object))
|
||||||
g_object_ref_sink ((GObject*)object);
|
g_object_ref_sink ((GObject*)object);
|
||||||
|
|
||||||
properties_object_get_set ((GObject*)object);
|
properties_object_get_set ((GObject*)object);
|
||||||
|
|
||||||
if (GTK_IS_OBJECT (object))
|
if (GTK_IS_WIDGET (object))
|
||||||
gtk_object_destroy (GTK_OBJECT (object));
|
gtk_widget_destroy (GTK_WIDGET (object));
|
||||||
g_object_unref ((GObject*)object);
|
g_object_unref ((GObject*)object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,6 @@ midori_findbar_entry_clear_icon_released_cb (GtkIconEntry* entry,
|
||||||
{
|
{
|
||||||
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
||||||
{
|
{
|
||||||
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
|
||||||
midori_findbar_set_icon (findbar, GTK_ICON_ENTRY_PRIMARY, "edit-find");
|
midori_findbar_set_icon (findbar, GTK_ICON_ENTRY_PRIMARY, "edit-find");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,8 +264,7 @@ midori_findbar_init (MidoriFindbar* findbar)
|
||||||
gtk_toolbar_insert (GTK_TOOLBAR (findbar), toolitem, -1);
|
gtk_toolbar_insert (GTK_TOOLBAR (findbar), toolitem, -1);
|
||||||
findbar->find_text = gtk_icon_entry_new ();
|
findbar->find_text = gtk_icon_entry_new ();
|
||||||
midori_findbar_set_icon (findbar, GTK_ICON_ENTRY_PRIMARY, "edit-find");
|
midori_findbar_set_icon (findbar, GTK_ICON_ENTRY_PRIMARY, "edit-find");
|
||||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (findbar->find_text),
|
sokoke_entry_set_clear_button_visible (GTK_ENTRY (findbar->find_text), TRUE);
|
||||||
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
|
||||||
g_signal_connect (findbar->find_text, "icon-release",
|
g_signal_connect (findbar->find_text, "icon-release",
|
||||||
G_CALLBACK (midori_findbar_entry_clear_icon_released_cb), findbar);
|
G_CALLBACK (midori_findbar_entry_clear_icon_released_cb), findbar);
|
||||||
g_signal_connect (findbar->find_text, "activate",
|
g_signal_connect (findbar->find_text, "activate",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# Copyright (C) 2010-2011 Peter de Ridder <peter@xfce.org>
|
# Copyright (C) 2010-2011 Peter de Ridder <peter@xfce.org>
|
||||||
|
# Copyright (C) 2012 Paweł Forysiuk <tuxator@o2.pl>
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -23,17 +24,30 @@
|
||||||
# a bit of configuration
|
# a bit of configuration
|
||||||
root_dir=$MINGW_PREFIX
|
root_dir=$MINGW_PREFIX
|
||||||
|
|
||||||
|
if [ "$MINGW_PREFIX" == "" ]; then
|
||||||
|
echo "Warning! MINGW_PREFIX variable is empty!"
|
||||||
|
sleep 5s
|
||||||
|
fi
|
||||||
|
|
||||||
# create temporary working directory
|
# create temporary working directory
|
||||||
temp_dir=`mktemp -d`
|
temp_dir=`mktemp -d`
|
||||||
|
|
||||||
# check if we can use 7zip
|
# check if we can use 7zip
|
||||||
have_7zip=`which 7za`
|
have_7zip=`which 7za`
|
||||||
|
|
||||||
|
if [ "$1" != "" ]; then
|
||||||
|
if [ "$1" == "debug" ]; then
|
||||||
|
DEBUG_BUILD=1
|
||||||
|
else
|
||||||
|
version_tag=$1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# generate unique filename
|
# generate unique filename
|
||||||
if [ "$have_7zip" != "" ]; then
|
if [ "$have_7zip" != "" ]; then
|
||||||
ARCHIVE=midori$1-`date +%Y%m%d%H%M`.7z
|
ARCHIVE=midori$version_tag-`date +%Y%m%d%H%M`.7z
|
||||||
else
|
else
|
||||||
ARCHIVE=midori$1-`date +%Y%m%d%H%M`.zip
|
ARCHIVE=midori$version_tag-`date +%Y%m%d%H%M`.zip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# function: dll-recursive <list of exe and dll files ...>
|
# function: dll-recursive <list of exe and dll files ...>
|
||||||
|
@ -55,7 +69,7 @@ dll_recursive ()
|
||||||
while [ "x`sha1sum - < $temp_file_new`" != "x`sha1sum - < $temp_file_old`" ]
|
while [ "x`sha1sum - < $temp_file_new`" != "x`sha1sum - < $temp_file_old`" ]
|
||||||
do
|
do
|
||||||
files=`cat $temp_file_new $temp_file_old | sort | uniq -u`
|
files=`cat $temp_file_new $temp_file_old | sort | uniq -u`
|
||||||
cp $temp_file_new $temp_file_old
|
cp -L $temp_file_new $temp_file_old
|
||||||
strings $files 2> /dev/null | grep \\.dll | cat - $temp_file_old | sort | uniq > $temp_file_new
|
strings $files 2> /dev/null | grep \\.dll | cat - $temp_file_old | sort | uniq > $temp_file_new
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -64,16 +78,36 @@ dll_recursive ()
|
||||||
rm $temp_file_new $temp_file_old
|
rm $temp_file_new $temp_file_old
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grab_files ()
|
||||||
|
{
|
||||||
|
local dir="$1"
|
||||||
|
pushd $root_dir > /dev/null
|
||||||
|
shift
|
||||||
|
while [ "$1" ]; do
|
||||||
|
find $dir "(" -name "$1" ")" -prune -exec mkdir -p $workdir/{} ";" -exec rmdir --ignore-fail-on-non-empty $workdir/{} ";" -exec cp -Lr {} $workdir/{} ";"
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
popd > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
echo -n "Creating $ARCHIVE ."
|
echo -n "Creating $ARCHIVE ."
|
||||||
|
|
||||||
# create destination folder
|
# create destination folder
|
||||||
mkdir $temp_dir/midori$1
|
workdir=$temp_dir/midori$version_tag
|
||||||
|
mkdir $workdir
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
# auto generate dll list, only of existing files
|
# auto generate dll list, only of existing files
|
||||||
pushd $root_dir/bin > /dev/null
|
pushd $root_dir/bin > /dev/null
|
||||||
dll_recursive midori*.exe gspawn-*-helper*.exe libhunspell*.dll > $temp_dir/midori.exe.lst
|
dll_recursive midori*.exe gspawn-*-helper*.exe libhunspell*.dll > $temp_dir/midori.exe.lst
|
||||||
|
dll_recursive ../lib/gio/modules/*.dll >> $temp_dir/midori.exe.lst
|
||||||
|
dll_recursive iconv.dll >> $temp_dir/midori.exe.lst
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" != "" ]; then
|
||||||
|
dll_recursive gdb.exe GtkLauncher.exe >> $temp_dir/midori.exe.lst
|
||||||
|
fi
|
||||||
|
|
||||||
files=`ls | cat - $temp_dir/midori.exe.lst | sort | uniq -d`
|
files=`ls | cat - $temp_dir/midori.exe.lst | sort | uniq -d`
|
||||||
rm $temp_dir/midori.exe.lst
|
rm $temp_dir/midori.exe.lst
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
@ -82,46 +116,80 @@ echo -n .
|
||||||
|
|
||||||
# copy auto generate dll list
|
# copy auto generate dll list
|
||||||
pushd $root_dir/bin > /dev/null
|
pushd $root_dir/bin > /dev/null
|
||||||
mkdir $temp_dir/midori$1/bin
|
mkdir $workdir/bin
|
||||||
cp $files $temp_dir/midori$1/bin
|
cp -L $files $workdir/bin
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
# copy etc
|
# copy etc
|
||||||
pushd $root_dir > /dev/null
|
grab_files etc midori
|
||||||
find etc "(" -name "*midori*" -o -name "gtkrc" ")" -prune -exec mkdir -p $temp_dir/midori$1/{} ";" -exec rmdir --ignore-fail-on-non-empty $temp_dir/midori$1/{} ";" -exec cp -r {} $temp_dir/midori$1/{} ";"
|
grab_files etc gtkrc
|
||||||
popd > /dev/null
|
|
||||||
|
# If modules are not compiled we need a list of them
|
||||||
|
grab_files etc pango
|
||||||
|
# Freetype is preferred font backend
|
||||||
|
# copy configuration, otherwise webkit will crash
|
||||||
|
grab_files etc fonts
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
# copy lib
|
# copy lib
|
||||||
pushd $root_dir > /dev/null
|
grab_files lib midori
|
||||||
find lib "(" -path "lib/midori/*" -o -path "lib/gtk-2.0/*" -o -path "lib/enchant/*" -o -path "lib/engines/*" ")" -a -name "*.dll" -prune -exec mkdir -p $temp_dir/midori$1/{} ";" -exec rmdir --ignore-fail-on-non-empty $temp_dir/midori$1/{} ";" -exec cp -r {} $temp_dir/midori$1/{} ";"
|
grab_files lib gtk-2.0
|
||||||
popd > /dev/null
|
grab_files lib/engines "*"
|
||||||
|
grab_files lib gdk-pixbuf-2.0
|
||||||
|
|
||||||
|
grab_files lib enchant
|
||||||
|
grab_files lib gio
|
||||||
|
|
||||||
|
# Fedora ships on-demand pango modules, check just in case
|
||||||
|
grab_files lib pango
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
# copy share
|
# copy share
|
||||||
pushd $root_dir > /dev/null
|
grab_files share midori
|
||||||
find share "(" -name "*midori*" -o -name "icons" -o -name "MS-Windows" -o -name "mime" ")" -prune -exec mkdir -p $temp_dir/midori$1/{} ";" -exec rmdir --ignore-fail-on-non-empty $temp_dir/midori$1/{} ";" -exec cp -r {} $temp_dir/midori$1/{} ";"
|
grab_files share icons
|
||||||
|
grab_files share MS-Windows
|
||||||
|
grab_files share mime
|
||||||
|
grab_files share midori.mo
|
||||||
|
|
||||||
|
grab_files share webkitgtk-1.0
|
||||||
|
|
||||||
|
if [ "$DEBUG_BUILD" == "" ];then
|
||||||
|
pushd $workdir > /dev/null
|
||||||
|
find -iname *.debug -exec rm {} \;
|
||||||
|
popd > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
# copy locales for gtk
|
# copy locales for gtk
|
||||||
# so we have translated stock items, file dialogs
|
# so we have translated stock items, file dialogs
|
||||||
|
|
||||||
find share "(" -name "midori.mo" ")" > locale.list
|
pushd $root_dir > /dev/null
|
||||||
mkdir -p $temp_dir/midori$1/share/locale/
|
find share "(" -name "midori.mo" ")" > $temp_dir/locale.list
|
||||||
for LOCALE in $(cat locale.list); do
|
mkdir -p $workdir/share/locale/
|
||||||
|
for LOCALE in $(cat $temp_dir/locale.list); do
|
||||||
LOCALE=$(echo $LOCALE|awk -F/ '{print $3}')
|
LOCALE=$(echo $LOCALE|awk -F/ '{print $3}')
|
||||||
cp /usr/share/locale/$LOCALE/LC_MESSAGES/gtk20.mo $temp_dir/midori$1/share/locale/$LOCALE/LC_MESSAGES/
|
cp /usr/share/locale/$LOCALE/LC_MESSAGES/gtk20.mo $workdir/share/locale/$LOCALE/LC_MESSAGES/
|
||||||
done
|
done
|
||||||
rm locale.list
|
rm $temp_dir/locale.list
|
||||||
|
|
||||||
|
# Use small icons and tango icons
|
||||||
|
gtk_etc_dir="$workdir/etc/gtk-2.0/"
|
||||||
|
mkdir -p $gtk_etc_dir
|
||||||
|
cat > $gtk_etc_dir/gtkrc << _EOF
|
||||||
|
gtk-theme-name = "MS-Windows"
|
||||||
|
gtk-fallback-icon-theme = "Tango"
|
||||||
|
gtk-toolbar-style = GTK_TOOLBAR_ICONS
|
||||||
|
_EOF
|
||||||
|
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
# copy doc files to root
|
# copy doc files to root
|
||||||
cp $temp_dir/midori$1/share/doc/midori/{COPYING,AUTHORS} $temp_dir/midori$1
|
cp -L $workdir/share/doc/midori/{COPYING,AUTHORS} $workdir
|
||||||
|
|
||||||
echo -n .
|
echo -n .
|
||||||
|
|
||||||
|
@ -130,9 +198,9 @@ ARCHIVE=`pwd`/$ARCHIVE
|
||||||
# store as zip/7z file
|
# store as zip/7z file
|
||||||
pushd $temp_dir > /dev/null
|
pushd $temp_dir > /dev/null
|
||||||
if [ "$have_7zip" != "" ]; then
|
if [ "$have_7zip" != "" ]; then
|
||||||
7za a -m0=lzma -mx=9 $ARCHIVE midori$1
|
7za a -m0=lzma $ARCHIVE midori$version_tag
|
||||||
else
|
else
|
||||||
zip -rq $ARCHIVE midori$1
|
zip -rq $ARCHIVE midori$version_tag
|
||||||
fi
|
fi
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
|
|
15
wscript
15
wscript
|
@ -29,7 +29,7 @@ from Configure import find_program_impl
|
||||||
|
|
||||||
major = 0
|
major = 0
|
||||||
minor = 4
|
minor = 4
|
||||||
micro = 3
|
micro = 4
|
||||||
|
|
||||||
APPNAME = 'midori'
|
APPNAME = 'midori'
|
||||||
VERSION = VERSION_FULL = str (major) + '.' + str (minor) + '.' + str (micro)
|
VERSION = VERSION_FULL = str (major) + '.' + str (minor) + '.' + str (micro)
|
||||||
|
@ -62,6 +62,9 @@ def is_mingw (env):
|
||||||
return cc.find ('mingw') != -1# or cc.find ('wine') != -1
|
return cc.find ('mingw') != -1# or cc.find ('wine') != -1
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_win32 (env):
|
||||||
|
return is_mingw (env) or Options.platform == 'win32'
|
||||||
|
|
||||||
# Compile Win32 res files to (resource) object files
|
# Compile Win32 res files to (resource) object files
|
||||||
def rc_file(self, node):
|
def rc_file(self, node):
|
||||||
rctask = self.create_task ('winrc')
|
rctask = self.create_task ('winrc')
|
||||||
|
@ -109,7 +112,7 @@ def configure (conf):
|
||||||
else:
|
else:
|
||||||
icons = 'no '
|
icons = 'no '
|
||||||
|
|
||||||
if is_mingw (conf.env) or Options.platform == 'win32':
|
if is_win32 (conf.env):
|
||||||
conf.find_program ('windres', var='WINRC')
|
conf.find_program ('windres', var='WINRC')
|
||||||
conf.env['platform'] = 'win32'
|
conf.env['platform'] = 'win32'
|
||||||
|
|
||||||
|
@ -271,8 +274,6 @@ def configure (conf):
|
||||||
if not conf.env['HAVE_UNIQUE']:
|
if not conf.env['HAVE_UNIQUE']:
|
||||||
if Options.platform == 'win32':
|
if Options.platform == 'win32':
|
||||||
conf.check (lib='ws2_32')
|
conf.check (lib='ws2_32')
|
||||||
check_pkg ('openssl', mandatory=False)
|
|
||||||
conf.define ('USE_SSL', [0,1][conf.env['HAVE_OPENSSL'] == 1])
|
|
||||||
conf.define ('HAVE_NETDB_H', [0,1][conf.check (header_name='netdb.h')])
|
conf.define ('HAVE_NETDB_H', [0,1][conf.check (header_name='netdb.h')])
|
||||||
conf.check (header_name='sys/wait.h')
|
conf.check (header_name='sys/wait.h')
|
||||||
conf.check (header_name='sys/select.h')
|
conf.check (header_name='sys/select.h')
|
||||||
|
@ -391,7 +392,7 @@ def set_options (opt):
|
||||||
add_enable_option ('apidocs', 'API documentation', group, disable=True)
|
add_enable_option ('apidocs', 'API documentation', group, disable=True)
|
||||||
|
|
||||||
group = opt.add_option_group ('Optional features', '')
|
group = opt.add_option_group ('Optional features', '')
|
||||||
add_enable_option ('unique', 'single instance support', group)
|
add_enable_option ('unique', 'single instance support', group, disable=is_win32 (os.environ))
|
||||||
add_enable_option ('libnotify', 'notification support', group)
|
add_enable_option ('libnotify', 'notification support', group)
|
||||||
add_enable_option ('addons', 'building of extensions', group)
|
add_enable_option ('addons', 'building of extensions', group)
|
||||||
add_enable_option ('tests', 'building of tests', group, disable=True)
|
add_enable_option ('tests', 'building of tests', group, disable=True)
|
||||||
|
@ -452,7 +453,7 @@ def build (bld):
|
||||||
bld.install_files ('${DOCDIR}/api/', blddir + '/docs/api/*')
|
bld.install_files ('${DOCDIR}/api/', blddir + '/docs/api/*')
|
||||||
|
|
||||||
for desktop in [APPNAME + '.desktop', APPNAME + '-private.desktop']:
|
for desktop in [APPNAME + '.desktop', APPNAME + '-private.desktop']:
|
||||||
if is_mingw (bld.env) or Options.platform == 'win32':
|
if is_win32 (bld.env):
|
||||||
break
|
break
|
||||||
if bld.env['HAVE_HILDON']:
|
if bld.env['HAVE_HILDON']:
|
||||||
appdir = '${MDATADIR}/applications/hildon'
|
appdir = '${MDATADIR}/applications/hildon'
|
||||||
|
@ -497,7 +498,7 @@ def build (bld):
|
||||||
else:
|
else:
|
||||||
Utils.pprint ('BLUE', "logo-shade could not be rasterized.")
|
Utils.pprint ('BLUE', "logo-shade could not be rasterized.")
|
||||||
|
|
||||||
for res_file in ['error.html', 'close.png']:
|
for res_file in ['about.css', 'error.html', 'close.png']:
|
||||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/' + res_file)
|
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/' + res_file)
|
||||||
bld.install_as ( \
|
bld.install_as ( \
|
||||||
'${MDATADIR}/' + APPNAME + '/res/speeddial-head-%s.html' % VERSION, \
|
'${MDATADIR}/' + APPNAME + '/res/speeddial-head-%s.html' % VERSION, \
|
||||||
|
|
Loading…
Reference in a new issue