Merge commit 'upstream/0.2.0'

This commit is contained in:
Ryan Niebur 2009-10-18 14:45:15 -07:00
commit 5e28c11b1e
49 changed files with 10658 additions and 3400 deletions

View file

@ -1,5 +1,24 @@
This file is licensed under the terms of the expat license, see the file EXPAT.
v0.2.0
+ (Kinetic) drag scrolling on touchscreen devices
+ Workaround a speed dial crasher
+ Faster Adblock with element blocking, for all WebKitGTK+ versions
+ Stripped menu, toolbar and tap on hold on Maemo, and 5.0 menu support
+ Add a DNS prefetching extension
+ Better IDN handling
+ Add a form history extension
+ Restore scrolling positions from the session
+ Keep typed address when switching tabs
+ Avoid storing duplicate history items per day
+ Fix multiple duplicate HTTP authentication dialogs
+ Pass mailto: links to the email client
+ Improve context menu with WebKitGTK+ 1.1.15
+ Checkbox "Remember password" in HTTP authentication
+ Fix a crasher when modifying bookmarks
+ Support page icons other than favicon.ico
+ iPhone identity in Network preferences
v0.1.10:
+ Fix freezing when opening multiple windows
+ Revamp Adblock with WebKitGTK+ 1.1.14 API

View file

@ -0,0 +1,16 @@
div.suggestions {
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #cccccc;
text-align: left;
background-color: #ffffff;
position: absolute;
}
div.suggestions div {
cursor: default;
padding: 0px 3px;
}
div.suggestions div.current {
background-color: #3366cc;
color: white;
}

370
data/autosuggestcontrol.js Normal file
View file

@ -0,0 +1,370 @@
/**
* An autosuggest textbox control.
* from Nicholas C. Zakas (Author) example: http://www.nczonline.net/
* @class
* @scope public
*/
function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
oProvider /*:SuggestionProvider*/) {
/**
* The currently selected suggestions.
* @scope private
*/
this.cur /*:int*/ = -1;
/**
* The dropdown list layer.
* @scope private
*/
this.layer = null;
/**
* Suggestion provider for the autosuggest feature.
* @scope private.
*/
this.provider /*:SuggestionProvider*/ = oProvider;
/**
* The textbox to capture.
* @scope private
*/
this.textbox /*:HTMLInputElement*/ = oTextbox;
//initialize the control
this.init();
}
/**
* Autosuggests one or more suggestions for what the user has typed.
* If no suggestions are passed in, then no autosuggest occurs.
* @scope private
* @param aSuggestions An array of suggestion strings.
* @param bTypeAhead If the control should provide a type ahead suggestion.
*/
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
bTypeAhead /*:boolean*/) {
//make sure theres at least one suggestion
if (aSuggestions.length > 0) {
if (bTypeAhead) {
this.typeAhead(aSuggestions[0]);
}
this.showSuggestions(aSuggestions);
} else {
this.hideSuggestions();
}
};
/**
* Creates the dropdown layer to display multiple suggestions.
* @scope private
*/
AutoSuggestControl.prototype.createDropDown = function () {
var oThis = this;
//create the layer and assign styles
this.layer = document.createElement("div");
this.layer.className = "suggestions";
this.layer.style.visibility = "hidden";
this.layer.style.width = this.textbox.offsetWidth + 10;
//when the user clicks on the a suggestion, get the text (innerHTML)
//and place it into a textbox
this.layer.onmousedown =
this.layer.onmouseup =
this.layer.onmouseover = function (oEvent) {
oEvent = oEvent || window.event;
oTarget = oEvent.target || oEvent.srcElement;
if (oEvent.type == "mousedown") {
oThis.textbox.value = oTarget.firstChild.nodeValue;
oThis.hideSuggestions();
} else if (oEvent.type == "mouseover") {
oThis.highlightSuggestion(oTarget);
} else {
oThis.textbox.focus();
}
};
document.body.appendChild(this.layer);
};
/**
* Gets the left coordinate of the textbox.
* @scope private
* @return The left coordinate of the textbox in pixels.
*/
AutoSuggestControl.prototype.getLeft = function () /*:int*/ {
var oNode = this.textbox;
var iLeft = 0;
while(oNode.tagName != "BODY") {
iLeft += oNode.offsetLeft;
oNode = oNode.offsetParent;
}
return iLeft;
};
/**
* Gets the top coordinate of the textbox.
* @scope private
* @return The top coordinate of the textbox in pixels.
*/
AutoSuggestControl.prototype.getTop = function () /*:int*/ {
var oNode = this.textbox;
var iTop = 0;
while(oNode.tagName != "BODY") {
iTop += oNode.offsetTop;
oNode = oNode.offsetParent;
}
return iTop;
};
/**
* Handles three keydown events.
* @scope private
* @param oEvent The event object for the keydown event.
*/
AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
switch(oEvent.keyCode) {
case 38: //up arrow
this.previousSuggestion();
break;
case 40: //down arrow
this.nextSuggestion();
break;
case 13: //enter
this.hideSuggestions();
break;
}
};
/**
* Handles keyup events.
* @scope private
* @param oEvent The event object for the keyup event.
*/
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
var iKeyCode = oEvent.keyCode;
//for backspace (8) and delete (46), shows suggestions without typeahead
if (iKeyCode == 8 || iKeyCode == 46) {
this.provider.requestSuggestions(this, false);
//make sure not to interfere with non-character keys
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123) ) {
//ignore
} else if (oEvent.ctrlKey) {
iKeyCode = 0;
this.hideSuggestions();
} else {
//request suggestions from the suggestion provider with typeahead
this.provider.requestSuggestions(this, true);
}
};
/**
* Hides the suggestion dropdown.
* @scope private
*/
AutoSuggestControl.prototype.hideSuggestions = function () {
this.layer.style.visibility = "hidden";
};
/**
* Highlights the given node in the suggestions dropdown.
* @scope private
* @param oSuggestionNode The node representing a suggestion in the dropdown.
*/
AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
for (var i=0; i < this.layer.childNodes.length; i++) {
var oNode = this.layer.childNodes[i];
if (oNode == oSuggestionNode) {
oNode.className = "current"
} else if (oNode.className == "current") {
oNode.className = "";
}
}
};
/**
* Initializes the textbox with event handlers for
* auto suggest functionality.
* @scope private
*/
AutoSuggestControl.prototype.init = function () {
//save a reference to this object
var oThis = this;
//assign the onkeyup event handler
this.textbox.onkeyup = function (oEvent) {
//check for the proper location of the event object
if (!oEvent) {
oEvent = window.event;
}
//call the handleKeyUp() method with the event object
oThis.handleKeyUp(oEvent);
};
//assign onkeydown event handler
this.textbox.onkeydown = function (oEvent) {
//check for the proper location of the event object
if (!oEvent) {
oEvent = window.event;
}
//call the handleKeyDown() method with the event object
oThis.handleKeyDown(oEvent);
};
//assign onblur event handler (hides suggestions)
this.textbox.onblur = function () {
oThis.hideSuggestions();
};
this.textbox.onclick = function () {
oThis.hideSuggestions();
};
//create the suggestions dropdown
this.createDropDown();
};
/**
* Highlights the next suggestion in the dropdown and
* places the suggestion into the textbox.
* @scope private
*/
AutoSuggestControl.prototype.nextSuggestion = function () {
var cSuggestionNodes = this.layer.childNodes;
if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
var oNode = cSuggestionNodes[++this.cur];
this.highlightSuggestion(oNode);
this.textbox.value = oNode.firstChild.nodeValue;
}
};
/**
* Highlights the previous suggestion in the dropdown and
* places the suggestion into the textbox.
* @scope private
*/
AutoSuggestControl.prototype.previousSuggestion = function () {
var cSuggestionNodes = this.layer.childNodes;
if (cSuggestionNodes.length > 0 && this.cur > 0) {
var oNode = cSuggestionNodes[--this.cur];
this.highlightSuggestion(oNode);
this.textbox.value = oNode.firstChild.nodeValue;
}
};
/**
* Selects a range of text in the textbox.
* @scope public
* @param iStart The start index (base 0) of the selection.
* @param iLength The number of characters to select.
*/
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {
//use text ranges for Internet Explorer
if (this.textbox.createTextRange) {
var oRange = this.textbox.createTextRange();
oRange.moveStart("character", iStart);
oRange.moveEnd("character", iLength - this.textbox.value.length);
oRange.select();
//use setSelectionRange() for Mozilla
} else if (this.textbox.setSelectionRange) {
this.textbox.setSelectionRange(iStart, iLength);
}
//set focus back to the textbox
this.textbox.focus();
};
/**
* Builds the suggestion layer contents, moves it into position,
* and displays the layer.
* @scope private
* @param aSuggestions An array of suggestions for the control.
*/
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
var oDiv = null;
this.layer.innerHTML = ""; //clear contents of the layer
for (var i=0; i < aSuggestions.length; i++) {
oDiv = document.createElement("div");
oDiv.appendChild(document.createTextNode(aSuggestions[i]));
this.layer.appendChild(oDiv);
}
this.layer.style.left = this.getLeft() + "px";
this.layer.style.top = (this.getTop()+this.textbox.offsetHeight) + "px";
this.layer.style.visibility = "visible";
};
/**
* Inserts a suggestion into the textbox, highlighting the
* suggested part of the text.
* @scope private
* @param sSuggestion The suggestion for the textbox.
*/
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {
//check for support of typeahead functionality
if (this.textbox.createTextRange || this.textbox.setSelectionRange){
var iLen = this.textbox.value.length;
this.textbox.value = sSuggestion;
this.selectRange(iLen, sSuggestion.length);
}
};
/**
* Request suggestions for the given autosuggest control.
* @scope protected
* @param oAutoSuggestControl The autosuggest control to provide suggestions for.
*/
FormSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
bTypeAhead /*:boolean*/) {
var aSuggestions = [];
var sTextboxValue = oAutoSuggestControl.textbox.value;
if (!this.suggestions)
return;
if (sTextboxValue.length > 0){
//search for matching suggestions
for (var i=0; i < this.suggestions.length; i++) {
if (this.suggestions[i].indexOf(sTextboxValue) == 0) {
aSuggestions.push(this.suggestions[i]);
}
}
}
//provide suggestions to the control
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};
function initSuggestions () {
var inputs = document.getElementsByTagName("input");
for (i=0;i<inputs.length;i++)
{
var ename = inputs[i].getAttribute("name");
var eid = inputs[i].getAttribute("id");
if (!ename && eid)
ename=eid;
if (inputs[i].type == "text")
var smth = new AutoSuggestControl(inputs[i], new FormSuggestions(ename));
}
};

View file

@ -0,0 +1,2 @@
[settings]
filters=http://adblockplus.mozdev.org/easylist/easylist.txt

View file

@ -20,9 +20,18 @@
#include <unistd.h>
#endif
#if WEBKIT_CHECK_VERSION (1, 1, 14)
#define HAVE_WEBKIT_RESOURCE_REQUEST WEBKIT_CHECK_VERSION (1, 1, 14)
static GHashTable* pattern = NULL;
#define ADBLOCK_FILTER_VALID(__filter) \
(__filter && (g_str_has_prefix (__filter, "http") \
|| g_str_has_prefix (__filter, "file")))
static GHashTable* pattern;
static gchar* blockcss = NULL;
static gchar* blockscript = NULL;
static void
adblock_parse_file (gchar* path);
static gchar *
adblock_fixup_regexp (gchar* src)
@ -36,6 +45,10 @@ adblock_fixup_regexp (gchar* src)
/* FIXME: Avoid always allocating twice the string */
s = dst = g_malloc (strlen (src) * 2);
/* |http:// means ^http:// */
if (src[0] == '|')
src[0] = '^';
while (*src)
{
switch (*src)
@ -60,29 +73,88 @@ adblock_fixup_regexp (gchar* src)
return dst;
}
static void
adblock_download_notify_status_cb (WebKitDownload* download,
GParamSpec* pspec,
gchar* path)
{
if (!g_file_test (path, G_FILE_TEST_EXISTS))
return;
adblock_parse_file (path);
g_free (path);
/* g_object_unref (download); */
}
static void
adblock_reload_rules (MidoriExtension* extension)
{
gchar** filters;
gchar* folder;
guint i = 0;
filters = midori_extension_get_string_list (extension, "filters", NULL);
folder = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
"adblock", NULL);
g_mkdir_with_parents (folder, 0700);
if (!filters)
return;
pattern = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_regex_unref);
katze_assign (blockcss, NULL);
while (filters[i++] != NULL)
{
gchar* filename = g_compute_checksum_for_string (G_CHECKSUM_MD5,
filters[i - 1], -1);
gchar* path = g_build_filename (folder, filename, NULL);
if (!g_file_test (path, G_FILE_TEST_EXISTS))
{
WebKitNetworkRequest* request;
WebKitDownload* download;
gchar* destination = g_filename_to_uri (path, NULL, NULL);
request = webkit_network_request_new (filters[i -1]);
download = webkit_download_new (request);
g_object_unref (request);
webkit_download_set_destination_uri (download, destination);
g_free (destination);
g_signal_connect (download, "notify::status",
G_CALLBACK (adblock_download_notify_status_cb), path);
webkit_download_start (download);
}
else
{
adblock_parse_file (path);
g_free (path);
}
g_free (filename);
}
g_strfreev (filters);
g_free (folder);
}
static void
adblock_browser_populate_tool_menu_cb (MidoriBrowser* browser,
GtkWidget* menu,
MidoriExtension* extension);
static void
adblock_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
MidoriExtension* extension);
static void
adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser)
adblock_preferences_render_tick_cb (GtkTreeViewColumn* column,
GtkCellRenderer* renderer,
GtkTreeModel* model,
GtkTreeIter* iter,
MidoriExtension* extension)
{
MidoriApp* app = midori_extension_get_app (extension);
gchar* filter;
g_signal_handlers_disconnect_by_func (
browser, adblock_browser_populate_tool_menu_cb, extension);
g_signal_handlers_disconnect_by_func (
extension, adblock_deactivate_cb, browser);
g_signal_handlers_disconnect_by_func (
app, adblock_app_add_browser_cb, extension);
/* FIXME: Disconnect session callbacks */
gtk_tree_model_get (model, iter, 0, &filter, -1);
g_object_set (renderer,
"activatable", ADBLOCK_FILTER_VALID (filter),
"active", ADBLOCK_FILTER_VALID (filter) && filter[4] != '-',
NULL);
g_free (filter);
}
static void
@ -97,6 +169,51 @@ adblock_preferences_renderer_text_edited_cb (GtkCellRenderer* renderer,
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, new_text, -1);
}
static void
adblock_preferences_renderer_toggle_toggled_cb (GtkTreeViewColumn* column,
const gchar* path,
GtkTreeModel* model)
{
GtkTreeIter iter;
if (gtk_tree_model_get_iter_from_string (model, &iter, path))
{
gchar* filter;
gtk_tree_model_get (model, &iter, 0, &filter, -1);
if (ADBLOCK_FILTER_VALID (filter))
{
filter[4] = filter[4] != '-' ? '-' : ':';
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, filter, -1);
g_free (filter);
}
}
}
static void
adblock_preferences_render_text_cb (GtkTreeViewColumn* column,
GtkCellRenderer* renderer,
GtkTreeModel* model,
GtkTreeIter* iter,
MidoriExtension* extension)
{
gchar* filter;
gtk_tree_model_get (model, iter, 0, &filter, -1);
if (ADBLOCK_FILTER_VALID (filter))
filter[4] = ':';
g_object_set (renderer,
"text", filter,
NULL);
g_free (filter);
}
static void
adblock_preferences_model_row_changed_cb (GtkTreeModel* model,
GtkTreePath* path,
@ -106,17 +223,27 @@ adblock_preferences_model_row_changed_cb (GtkTreeModel* model,
gsize length = gtk_tree_model_iter_n_children (model, NULL);
gchar** filters = g_new (gchar*, length + 1);
guint i = 0;
gboolean need_reload = FALSE;
if (gtk_tree_model_iter_children (model, iter, NULL))
do
{
gchar* filter;
gtk_tree_model_get (model, iter, 0, &filter, -1);
if (filter && *filter)
{
filters[i++] = filter;
need_reload = TRUE;
}
else
g_free (filter);
}
while (gtk_tree_model_iter_next (model, iter));
filters[length] = NULL;
midori_extension_set_string_list (extension, "filters", filters, length);
filters[i] = NULL;
midori_extension_set_string_list (extension, "filters", filters, i);
g_free (filters);
if (need_reload)
adblock_reload_rules (extension);
}
static void
@ -132,8 +259,10 @@ static void
adblock_preferences_add_clicked_cb (GtkWidget* button,
GtkTreeModel* model)
{
GtkEntry* entry = g_object_get_data (G_OBJECT (button), "entry");
gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
NULL, 0, 0, "", -1);
NULL, 0, 0, gtk_entry_get_text (entry), -1);
gtk_entry_set_text (entry, "");
}
static void
@ -146,6 +275,15 @@ adblock_preferences_remove_clicked_cb (GtkWidget* button,
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
}
#if GTK_CHECK_VERSION (2, 18, 0)
static gboolean
adblock_activate_link_cb (GtkWidget* label,
const gchar* uri)
{
return sokoke_show_uri (gtk_widget_get_screen (label), uri, GDK_CURRENT_TIME, NULL);
}
#endif
static GtkWidget*
adblock_get_preferences_dialog (MidoriExtension* extension)
{
@ -160,11 +298,13 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
GtkWidget* treeview;
GtkTreeViewColumn* column;
GtkCellRenderer* renderer_text;
GtkCellRenderer* renderer_pixbuf;
GtkCellRenderer* renderer_toggle;
GtkWidget* scrolled;
gchar** filters;
GtkWidget* vbox;
GtkWidget* button;
gchar* description;
GtkWidget* entry;
#if HAVE_OSX
GtkWidget* icon;
#endif
@ -198,6 +338,28 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
TRUE, TRUE, 12);
vbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 4);
button = gtk_label_new (NULL);
description = g_strdup_printf (_(
"Type the address of a preconfigured filter list in the text entry "
"and click \"Add\" to add it to the list. "
"You can find more lists at %s."),
#if GTK_CHECK_VERSION (2, 18, 0)
"<a href=\"http://easylist.adblockplus.org/\">easylist.adblockplus.org</a>");
#else
"<u>http://easylist.adblockplus.org/</u>");
#endif
#if GTK_CHECK_VERSION (2, 18, 0)
g_signal_connect (button, "activate-link",
G_CALLBACK (adblock_activate_link_cb), NULL);
#endif
gtk_label_set_markup (GTK_LABEL (button), description);
g_free (description);
gtk_label_set_line_wrap (GTK_LABEL (button), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 4);
entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 4);
liststore = gtk_list_store_new (1, G_TYPE_STRING);
g_object_connect (liststore,
"signal::row-inserted",
@ -210,15 +372,23 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
column = gtk_tree_view_column_new ();
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
renderer_toggle = gtk_cell_renderer_toggle_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer_toggle, FALSE);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer_toggle,
(GtkCellLayoutDataFunc)adblock_preferences_render_tick_cb,
extension, NULL);
g_signal_connect (renderer_toggle, "toggled",
G_CALLBACK (adblock_preferences_renderer_toggle_toggled_cb), liststore);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
column = gtk_tree_view_column_new ();
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer_text,
"text", 0, NULL);
g_object_set (renderer_text, "editable", TRUE, NULL);
g_signal_connect (renderer_text, "edited",
G_CALLBACK (adblock_preferences_renderer_text_edited_cb), liststore);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer_text,
(GtkCellLayoutDataFunc)adblock_preferences_render_text_cb,
extension, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
@ -226,7 +396,7 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
gtk_container_add (GTK_CONTAINER (scrolled), treeview);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5);
filters = midori_extension_get_string_list (extension, "filters", NULL);
if (filters != NULL)
@ -242,6 +412,7 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 4);
button = gtk_button_new_from_stock (GTK_STOCK_ADD);
g_object_set_data (G_OBJECT (button), "entry", entry);
g_signal_connect (button, "clicked",
G_CALLBACK (adblock_preferences_add_clicked_cb), liststore);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
@ -324,6 +495,7 @@ adblock_is_matched (const gchar* patt,
return g_regex_match_full (regex, uri, -1, 0, 0, NULL, NULL);
}
#if HAVE_WEBKIT_RESOURCE_REQUEST
static void
adblock_resource_request_starting_cb (WebKitWebView* web_view,
WebKitWebFrame* web_frame,
@ -333,21 +505,78 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
MidoriView* view)
{
const gchar* uri = webkit_network_request_get_uri (request);
if (!strncmp (uri, "data", 4))
return;
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, (char*)uri))
{
webkit_network_request_set_uri (request, "about:blank");
/* TODO: Need to figure out how to indicate what was blocked */
}
}
#else
static void
adblock_session_request_queued_cb (SoupSession* session,
SoupMessage* msg)
{
SoupURI* soup_uri = soup_message_get_uri (msg);
gchar* uri = soup_uri ? soup_uri_to_string (soup_uri, FALSE) : g_strdup ("");
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, uri))
{
soup_uri = soup_uri_new ("http://.invalid");
soup_message_set_uri (msg, soup_uri);
soup_uri_free (soup_uri);
}
g_free (uri);
}
#endif
static gchar*
adblock_build_js (gchar* style)
{
return g_strdup_printf (
"window.addEventListener ('DOMContentLoaded',"
"function () {"
"var mystyle = document.createElement(\"style\");"
"mystyle.setAttribute(\"type\", \"text/css\");"
"mystyle.appendChild(document.createTextNode('%s'));"
"var head = document.getElementsByTagName(\"head\")[0];"
"if (head) head.appendChild(mystyle);"
"else document.documentElement.insertBefore(mystyle, document.documentElement.firstChild);"
"}, true);",
style);
}
static void
adblock_window_object_cleared_cb (GtkWidget* web_view,
WebKitWebFrame* web_frame,
JSContextRef js_context,
JSObjectRef js_window)
{
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view), blockscript);
}
static void
adblock_add_tab_cb (MidoriBrowser* browser,
MidoriView* view)
{
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
g_signal_connect (web_view, "window-object-cleared",
G_CALLBACK (adblock_window_object_cleared_cb), 0);
#if HAVE_WEBKIT_RESOURCE_REQUEST
g_signal_connect (web_view, "resource-request-starting",
G_CALLBACK (adblock_resource_request_starting_cb), view);
#endif
}
static void
adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser);
static void
adblock_add_tab_foreach_cb (MidoriView* view,
MidoriBrowser* browser)
{
adblock_add_tab_cb (browser, view);
}
static void
@ -355,54 +584,73 @@ adblock_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
MidoriExtension* extension)
{
if (pattern)
g_signal_connect (browser, "add-tab",
G_CALLBACK (adblock_add_tab_cb), 0);
midori_browser_foreach (browser,
(GtkCallback)adblock_add_tab_foreach_cb, browser);
g_signal_connect (browser, "add-tab", G_CALLBACK (adblock_add_tab_cb), 0);
g_signal_connect (browser, "populate-tool-menu",
G_CALLBACK (adblock_browser_populate_tool_menu_cb), extension);
g_signal_connect (extension, "deactivate",
G_CALLBACK (adblock_deactivate_cb), browser);
}
static void
adblock_frame_add (gchar* line)
{
gchar* new_blockcss;
(void)*line++;
(void)*line++;
new_blockcss = g_strdup_printf ("%s %s { display: none !important; }",
blockcss, line);
katze_assign (blockcss, new_blockcss);
}
static gchar*
adblock_parse_line (gchar* line)
{
if (!line)
return NULL;
g_strchomp (line);
/* Ignore comments and new lines */
if (line[0] == '!')
return NULL;
/* FIXME: No support for whitelisting */
if (line[0] == '@' && line[1] == '@')
return NULL;
/* FIXME: Differentiate # comments from element hiding */
/* FIXME: No support for element hiding */
/* FIXME: What is this? */
if (line[0] == '|' && line[1] == '|')
return NULL;
/* ditto */
if (strstr (line,"$"))
return NULL;
/* Got block hider */
if (line[0] == '#' && line[1] == '#' && (line[2] == '.'||line[2] == '#'||line[2] == 'a'))
{
adblock_frame_add (line);
return NULL;
}
/* FIXME: Do we have smth else starting with ##? */
if (line[0] == '#' && line[1] == '#')
return NULL;
/* FIXME: No support for per domain element hiding */
if (strstr (line,"##"))
return NULL;
/* FIXME: No support for [include] and [exclude] tags */
if (line[0] == '[')
return NULL;
g_strchomp (line);
return adblock_fixup_regexp (line);
}
static GHashTable*
static void
adblock_parse_file (gchar* path)
{
FILE* file;
if ((file = g_fopen (path, "r")))
{
GHashTable* patt = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_regex_unref);
gboolean have_pattern = FALSE;
gchar line[255];
gchar line[500];
GRegex* regex;
while (fgets (line, 255, file))
while (fgets (line, 500, file))
{
GError* error = NULL;
gchar* parsed;
@ -420,28 +668,47 @@ adblock_parse_file (gchar* path)
g_free (parsed);
}
else
{
have_pattern = TRUE;
g_hash_table_insert (patt, parsed, regex);
}
g_hash_table_insert (pattern, parsed, regex);
}
katze_assign (blockscript, adblock_build_js (blockcss));
fclose (file);
if (have_pattern)
return patt;
}
/* FIXME: This should presumably be freed, but there's a possible crash
g_free (path); */
return NULL;
}
static void
adblock_download_notify_status_cb (WebKitDownload* download,
GParamSpec* pspec,
gchar* path)
adblock_deactivate_tabs (MidoriView* view,
MidoriBrowser* browser)
{
pattern = adblock_parse_file (path);
/* g_object_unref (download); */
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
g_signal_handlers_disconnect_by_func (
browser, adblock_add_tab_cb, 0);
g_signal_handlers_disconnect_by_func (
web_view, adblock_window_object_cleared_cb, 0);
#if HAVE_WEBKIT_RESOURCE_REQUEST
g_signal_handlers_disconnect_by_func (
web_view, adblock_resource_request_starting_cb, view);
#else
g_signal_handlers_disconnect_by_func (
webkit_get_default_session (), adblock_session_request_queued_cb, NULL);
#endif
}
static void
adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser)
{
MidoriApp* app = midori_extension_get_app (extension);
g_signal_handlers_disconnect_by_func (
browser, adblock_browser_populate_tool_menu_cb, extension);
g_signal_handlers_disconnect_by_func (
extension, adblock_deactivate_cb, browser);
g_signal_handlers_disconnect_by_func (
app, adblock_app_add_browser_cb, extension);
midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, browser);
katze_assign (blockcss, NULL);
g_hash_table_destroy (pattern);
}
static void
@ -451,9 +718,14 @@ adblock_activate_cb (MidoriExtension* extension,
KatzeArray* browsers;
MidoriBrowser* browser;
guint i;
gchar* folder;
gchar** filters;
SoupSession* session;
#if !HAVE_WEBKIT_RESOURCE_REQUEST
SoupSession* session = webkit_get_default_session ();
g_signal_connect (session, "request-queued",
G_CALLBACK (adblock_session_request_queued_cb), NULL);
#endif
adblock_reload_rules (extension);
browsers = katze_object_get_object (app, "browsers");
i = 0;
@ -461,43 +733,8 @@ adblock_activate_cb (MidoriExtension* extension,
adblock_app_add_browser_cb (app, browser, extension);
g_signal_connect (app, "add-browser",
G_CALLBACK (adblock_app_add_browser_cb), extension);
g_object_unref (browsers);
session = webkit_get_default_session ();
folder = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
"adblock", NULL);
g_mkdir_with_parents (folder, 0700);
filters = midori_extension_get_string_list (extension, "filters", NULL);
if (filters != NULL)
{
i = 0;
while (filters[i++] != NULL)
{
gchar* filename = g_compute_checksum_for_string (G_CHECKSUM_MD5,
filters[i - 1], -1);
gchar* path = g_build_filename (folder, filename, NULL);
if (!g_file_test (path, G_FILE_TEST_EXISTS))
{
WebKitNetworkRequest* request;
WebKitDownload* download;
gchar* destination = g_filename_to_uri (path, NULL, NULL);
request = webkit_network_request_new (filters[i -1]);
download = webkit_download_new (request);
g_object_unref (request);
webkit_download_set_destination_uri (download, destination);
g_free (destination);
g_signal_connect (download, "notify::status",
G_CALLBACK (adblock_download_notify_status_cb), path);
webkit_download_start (download);
}
else
pattern = adblock_parse_file (path);
g_free (filename);
}
}
g_strfreev (filters);
g_free (folder);
}
#if G_ENABLE_DEBUG
@ -525,6 +762,10 @@ test_adblock_pattern (void)
gint temp;
gchar* filename;
pattern = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_regex_unref);
temp = g_file_open_tmp ("midori_adblock_match_test_XXXXXX", &filename, NULL);
g_file_set_contents (filename,
@ -533,7 +774,7 @@ test_adblock_pattern (void)
"http://ads.bla.blub/*\n"
"http://ads.blub.boing/*",
-1, NULL);
pattern = adblock_parse_file (filename);
adblock_parse_file (filename);
g_assert (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched,
"http://ads.foo.bar/teddy"));
@ -548,9 +789,43 @@ test_adblock_pattern (void)
g_assert (!g_hash_table_find (pattern, (GHRFunc) adblock_is_matched,
"http://ads.foo.boing/beer"));
g_hash_table_destroy (pattern);
close (temp);
g_unlink (filename);
g_hash_table_destroy (pattern);
}
static void
test_adblock_count (void)
{
pattern = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_regex_unref);
gchar* urls[6] = {
"https://bugs.webkit.org/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&long_desc_type=substring&long_desc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&keywords_type=allwords&keywords=&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&emailassigned_to1=1&emailtype1=substring&email1=&emailassigned_to2=1&emailreporter2=1&emailcc2=1&emailtype2=substring&email2=&bugidtype=include&bug_id=&votes=&chfieldfrom=&chfieldto=Now&chfieldvalue=&query_based_on=gtkport&field0-0-0=keywords&type0-0-0=anywordssubstr&value0-0-0=Gtk%20Cairo%20soup&field0-0-1=short_desc&type0-0-1=anywordssubstr&value0-0-1=Gtk%20Cairo%20soup%20autoconf%20automake%20autotool&field0-0-2=component&type0-0-2=equals&value0-0-2=WebKit%20Gtk",
"http://www.engadget.com/2009/09/24/google-hits-android-rom-modder-with-a-cease-and-desist-letter/",
"http://karibik-invest.com/es/bienes_raices/search.php?sqT=19&sqN=&sqMp=&sqL=0&qR=1&sqMb=&searchMode=1&action=B%FAsqueda",
"http://google.com",
"http://ya.ru",
"http://google.com"
};
/* FIXME */
gchar* filename = "/home/avb/.cache/midori/adblock/bb6cd38a4579b3605946b1228fa65297";
gdouble elapsed = 0.0;
gchar* str;
int i;
adblock_parse_file (filename);
for (i = 0; i < 6; i++)
{
str = urls[i];
g_test_timer_start ();
g_hash_table_find (pattern, (GHRFunc) adblock_is_matched,str);
elapsed += g_test_timer_elapsed ();
}
g_print ("Search took %f seconds\n", elapsed);
g_hash_table_destroy (pattern);
}
void
@ -558,28 +833,23 @@ extension_test (void)
{
g_test_add_func ("/extensions/adblock/parse", test_adblock_parse);
g_test_add_func ("/extensions/adblock/pattern", test_adblock_pattern);
g_test_add_func ("/extensions/adblock/count", test_adblock_count);
}
#endif
#endif
MidoriExtension*
extension_init (void)
{
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
"name", _("Advertisement blocker"),
"description", _("Block advertisements according to a filter list"),
#if WEBKIT_CHECK_VERSION (1, 1, 14)
"version", "0.1",
#endif
"authors", "Christian Dywan <christian@twotoasts.de>",
NULL);
#if WEBKIT_CHECK_VERSION (1, 1, 14)
midori_extension_install_string_list (extension, "filters", NULL, G_MAXSIZE);
g_signal_connect (extension, "activate",
G_CALLBACK (adblock_activate_cb), NULL);
#endif
return extension;
}

203
extensions/dnsprefetch.c Normal file
View file

@ -0,0 +1,203 @@
/*
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
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 <midori/midori.h>
#include "config.h"
#include <glib/gstdio.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#define MAXHOSTS 50
static gchar* hosts = NULL;
static int host_count;
static bool
dnsprefetch_do_prefetch (const char* uri)
{
SoupURI* s_uri;
if (!uri)
return FALSE;
s_uri = soup_uri_new (uri);
if (!s_uri || !s_uri->host)
return FALSE;
#if GLIB_CHECK_VERSION (2, 22, 0)
if (g_hostname_is_ip_address (s_uri->host))
#else
if (g_ascii_isdigit (s_uri->host[0]) && g_strstr_len (s_uri->host, 4, "."))
#endif
{
soup_uri_free (s_uri);
return FALSE;
}
if (!g_str_has_prefix (uri, "http"))
{
soup_uri_free (s_uri);
return FALSE;
}
if (!g_regex_match_simple (s_uri->host, hosts,
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
{
SoupAddress* address;
gchar* new_hosts;
address = soup_address_new (s_uri->host, SOUP_ADDRESS_ANY_PORT);
soup_address_resolve_async (address, 0, 0, 0, 0);
g_object_unref (address);
if (host_count > MAXHOSTS)
{
katze_assign (hosts, g_strdup (""));
host_count = 0;
}
host_count++;
new_hosts = g_strdup_printf ("%s|%s", hosts, s_uri->host);
katze_assign (hosts, new_hosts);
}
soup_uri_free (s_uri);
return TRUE;
}
static void
dnsprefetch_prefetch_cb (WebKitWebView* web_view,
const gchar* title,
const char* uri,
gpointer user_data)
{
dnsprefetch_do_prefetch (uri);
}
static void
dnsprefetch_add_tab_cb (MidoriBrowser* browser,
MidoriView* view)
{
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
g_signal_connect (web_view, "hovering-over-link",
G_CALLBACK (dnsprefetch_prefetch_cb), 0);
}
static void
dnsprefetch_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser);
static void
dnsprefetch_add_tab_foreach_cb (MidoriView* view,
MidoriBrowser* browser)
{
dnsprefetch_add_tab_cb (browser, view);
}
static void
dnsprefetch_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
MidoriExtension* extension)
{
midori_browser_foreach (browser,
(GtkCallback)dnsprefetch_add_tab_foreach_cb, browser);
g_signal_connect (browser, "add-tab",
G_CALLBACK (dnsprefetch_add_tab_cb), 0);
g_signal_connect (extension, "deactivate",
G_CALLBACK (dnsprefetch_deactivate_cb), browser);
}
static void
dnsprefetch_deactivate_tabs (MidoriView* view,
MidoriBrowser* browser)
{
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
g_signal_handlers_disconnect_by_func (
browser, dnsprefetch_add_tab_cb, 0);
g_signal_handlers_disconnect_by_func (
web_view, dnsprefetch_do_prefetch, 0);
}
static void
dnsprefetch_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser)
{
MidoriApp* app = midori_extension_get_app (extension);
katze_assign (hosts, g_strdup (""));
host_count = 0;
g_signal_handlers_disconnect_by_func (
extension, dnsprefetch_deactivate_cb, browser);
g_signal_handlers_disconnect_by_func (
app, dnsprefetch_app_add_browser_cb, extension);
midori_browser_foreach (browser, (GtkCallback)dnsprefetch_deactivate_tabs, browser);
}
static void
dnsprefetch_activate_cb (MidoriExtension* extension,
MidoriApp* app)
{
KatzeArray* browsers;
MidoriBrowser* browser;
guint i;
katze_assign (hosts, g_strdup (""));
host_count = 0;
browsers = katze_object_get_object (app, "browsers");
i = 0;
while ((browser = katze_array_get_nth_item (browsers, i++)))
dnsprefetch_app_add_browser_cb (app, browser, extension);
g_signal_connect (app, "add-browser",
G_CALLBACK (dnsprefetch_app_add_browser_cb), extension);
g_object_unref (browsers);
}
#if G_ENABLE_DEBUG
static void
dnsprefetch_parse (void)
{
g_assert (!dnsprefetch_do_prefetch (NULL));
g_assert (dnsprefetch_do_prefetch ("http://google.com"));
g_assert (dnsprefetch_do_prefetch ("http://google.com"));
g_assert (dnsprefetch_do_prefetch ("http://googlecom"));
g_assert (dnsprefetch_do_prefetch ("http://1kino.com"));
g_assert (dnsprefetch_do_prefetch ("http://"));
g_assert (!dnsprefetch_do_prefetch ("http:/"));
g_assert (!dnsprefetch_do_prefetch ("http"));
g_assert (!dnsprefetch_do_prefetch ("ftp://ftphost.org"));
g_assert (!dnsprefetch_do_prefetch ("http://10.0.0.1"));
g_assert (!dnsprefetch_do_prefetch ("about:blank"));
g_assert (!dnsprefetch_do_prefetch ("javascript: alert()"));
}
void
extension_test (void)
{
katze_assign (hosts, g_strdup (""));
host_count = 0;
g_test_add_func ("/extensions/dnsprefetch/parse", dnsprefetch_parse);
}
#endif
MidoriExtension*
extension_init (void)
{
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
"name", _("DNS prefetching"),
"description", _("Prefetch IP addresses of hovered links"),
"version", "0.1",
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
NULL);
g_signal_connect (extension, "activate",
G_CALLBACK (dnsprefetch_activate_cb), NULL);
return extension;
}

308
extensions/formhistory.c Normal file
View file

@ -0,0 +1,308 @@
/*
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
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 20
#define MINCHARS 2
#include <midori/midori.h>
#include "config.h"
#include <glib/gstdio.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
static GHashTable* global_keys;
static gchar* jsforms;
static gboolean
formhistory_prepare_js ()
{
gchar* autosuggest;
gchar* style;
guint i;
gchar* file;
gchar* data_path = g_build_filename (MDATADIR, PACKAGE_NAME, NULL);
file = g_build_filename (data_path,"/autosuggestcontrol.js",NULL);
if (!g_file_test (file, G_FILE_TEST_EXISTS))
return FALSE;
g_file_get_contents (file, &autosuggest, NULL, NULL);
g_strchomp (autosuggest);
file = g_build_filename (data_path,"/autosuggestcontrol.css",NULL);
if (!g_file_test (file, G_FILE_TEST_EXISTS))
return FALSE;
g_file_get_contents (file, &style, NULL, NULL);
g_strchomp (style);
i = 0;
while (style[i])
{
if (style[i] == '\n')
style[i] = ' ';
i++;
}
jsforms = g_strdup_printf (
"%s"
"window.addEventListener (\"load\", function () { initSuggestions (); }, true);"
"window.addEventListener ('DOMContentLoaded',"
"function () {"
"var mystyle = document.createElement(\"style\");"
"mystyle.setAttribute(\"type\", \"text/css\");"
"mystyle.appendChild(document.createTextNode(\"%s\"));"
"var head = document.getElementsByTagName(\"head\")[0];"
"if (head) head.appendChild(mystyle);"
"else document.documentElement.insertBefore(mystyle, document.documentElement.firstChild);"
"}, true);",
autosuggest,
style);
g_strstrip (jsforms);
g_free (data_path);
g_free (file);
g_free (style);
g_free (autosuggest);
return TRUE;
}
static gchar*
formhistory_build_js ()
{
gchar* suggestions = g_strdup ("");
GHashTableIter iter;
gpointer key, value;
gchar* script;
g_hash_table_iter_init (&iter, global_keys);
while (g_hash_table_iter_next (&iter, &key, &value))
{
gchar* _suggestions = g_strdup_printf ("%s arr[\"%s\"] = [%s]; ",
suggestions, (char*)key, (char*)value);
katze_assign (suggestions, _suggestions);
}
script = g_strdup_printf ("function FormSuggestions(eid) { "
"arr = new Array();"
"%s"
"this.suggestions = arr[eid]; }"
"%s",
suggestions,
jsforms);
g_free (suggestions);
return script;
}
static void
formhistory_update_main_hash (GHashTable* keys)
{
GHashTableIter iter;
gchar* key;
gchar* value;
g_hash_table_iter_init (&iter, keys);
while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value))
{
guint length;
gchar* tmp;
if (!(value && *value))
continue;
length = strlen (value);
if (length > MAXCHARS || length < MINCHARS)
continue;
tmp = g_hash_table_lookup (global_keys, (gpointer)key);
if (tmp)
{
gchar* rvalue = g_strdup_printf ("\"%s\"",value);
if (!g_regex_match_simple (rvalue, tmp,
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
{
gchar* new_value = g_strdup_printf ("%s%s,", tmp, rvalue);
g_hash_table_replace (global_keys, key, new_value);
}
g_free (rvalue);
}
else
{
gchar* new_value = g_strdup_printf ("\"%s\",",value);
g_hash_table_insert (global_keys, key, new_value);
}
}
}
static void
formhistory_session_request_queued_cb (SoupSession* session,
SoupMessage* msg)
{
gchar* method = katze_object_get_string (msg, "method");
if (method && !strncmp (method, "POST", 4))
{
/* SoupMessageHeaders* hdrs = msg->request_headers;
const gchar* referer; */
SoupMessageBody* body = msg->request_body;
if (soup_message_body_get_accumulate (body))
{
SoupBuffer* buffer = soup_message_body_flatten (body);
GHashTable* keys = soup_form_decode (body->data);
formhistory_update_main_hash (keys);
soup_buffer_free (buffer);
}
/* FIXME: Need a permanent storage implementation */
/* referer = soup_message_headers_get_one (hdrs, "Referer"); */
}
g_free (method);
}
static void
formhistory_window_object_cleared_cb (GtkWidget* web_view,
WebKitWebFrame* web_frame,
JSContextRef js_context,
JSObjectRef js_window)
{
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view),
formhistory_build_js ());
}
static void
formhistory_add_tab_cb (MidoriBrowser* browser,
MidoriView* view)
{
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
SoupSession *session = webkit_get_default_session ();
g_signal_connect (web_view, "window-object-cleared",
G_CALLBACK (formhistory_window_object_cleared_cb), 0);
g_signal_connect (session, "request-queued",
G_CALLBACK (formhistory_session_request_queued_cb), 0);
}
static void
formhistory_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser);
static void
formhistory_add_tab_foreach_cb (MidoriView* view,
MidoriBrowser* browser)
{
formhistory_add_tab_cb (browser, view);
}
static void
formhistory_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
MidoriExtension* extension)
{
midori_browser_foreach (browser,
(GtkCallback)formhistory_add_tab_foreach_cb, browser);
g_signal_connect (browser, "add-tab", G_CALLBACK (formhistory_add_tab_cb), 0);
g_signal_connect (extension, "deactivate",
G_CALLBACK (formhistory_deactivate_cb), browser);
}
static void
formhistory_deactivate_tabs (MidoriView* view,
MidoriBrowser* browser)
{
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
SoupSession *session = webkit_get_default_session ();
g_signal_handlers_disconnect_by_func (
browser, formhistory_add_tab_cb, 0);
g_signal_handlers_disconnect_by_func (
web_view, formhistory_window_object_cleared_cb, 0);
g_signal_handlers_disconnect_by_func (
session, formhistory_session_request_queued_cb, 0);
}
static void
formhistory_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser)
{
MidoriApp* app = midori_extension_get_app (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, browser);
jsforms = "";
if (global_keys)
g_hash_table_destroy (global_keys);
}
static void
formhistory_activate_cb (MidoriExtension* extension,
MidoriApp* app)
{
KatzeArray* browsers;
MidoriBrowser* browser;
guint i;
global_keys = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_free);
browsers = katze_object_get_object (app, "browsers");
i = 0;
while ((browser = katze_array_get_nth_item (browsers, i++)))
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);
}
#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;
gchar* ver;
gchar* desc;
if (formhistory_prepare_js ())
{
ver = "0.1";
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;
}
MidoriExtension* 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)
g_signal_connect (extension, "activate",
G_CALLBACK (formhistory_activate_cb), NULL);
return extension;
}

View file

@ -220,8 +220,18 @@ static void mouse_gestures_deactivate (MidoriExtension *extension, MidoriApp *ap
static void mouse_gestures_activate (MidoriExtension *extension, MidoriApp *app)
{
KatzeArray* browsers;
MidoriBrowser* browser;
guint i;
gesture = mouse_gesture_new ();
browsers = katze_object_get_object (app, "browsers");
i = 0;
while ((browser = katze_array_get_nth_item (browsers, i++)))
mouse_gestures_browser_cb (app, browser);
g_object_unref (browsers);
g_signal_connect (app, "add-browser",
G_CALLBACK (mouse_gestures_browser_cb), NULL);
g_signal_connect (extension, "deactivate",

View file

@ -34,6 +34,11 @@ tab_panel_browser_remove_tab_cb (MidoriBrowser* browser,
GtkWidget* view,
MidoriExtension* extension);
static void
tab_panel_browser_notify_tab_cb (MidoriBrowser* browser,
GParamSpec* pspec,
GtkTreeView* treeview);
static void
tab_panel_view_notify_minimized_cb (GtkWidget* view,
GParamSpec* pspec,
@ -67,28 +72,50 @@ tab_panel_get_toolitem_for_view (GtkWidget* view)
return g_object_get_data (G_OBJECT (view), "tab-panel-ext-toolitem");
}
static gboolean
tab_panel_get_iter_for_view (GtkTreeModel* model,
GtkTreeIter* iter,
gpointer view)
{
guint i = 0;
while (gtk_tree_model_iter_nth_child (model, iter, NULL, i))
{
MidoriView* view_;
gtk_tree_model_get (model, iter, 0, &view_, -1);
g_object_unref (view_);
if (view_ == view)
return TRUE;
i++;
}
return FALSE;
}
static void
tab_panel_deactivate_cb (MidoriExtension* extension,
GtkWidget* panel)
GtkWidget* treeview)
{
MidoriApp* app = midori_extension_get_app (extension);
GtkTreeModel* model;
MidoriBrowser* browser;
browser = midori_browser_get_for_widget (panel);
browser = midori_browser_get_for_widget (treeview);
g_object_set (browser, "show-tabs", TRUE, NULL);
model = tab_panel_get_model_for_browser (browser);
g_object_unref (model);
gtk_widget_destroy (panel);
g_signal_handlers_disconnect_by_func (
extension, tab_panel_deactivate_cb, panel);
extension, tab_panel_deactivate_cb, treeview);
g_signal_handlers_disconnect_by_func (
app, tab_panel_app_add_browser_cb, extension);
g_signal_handlers_disconnect_by_func (
browser, tab_panel_browser_add_tab_cb, extension);
g_signal_handlers_disconnect_by_func (
browser, tab_panel_browser_remove_tab_cb, extension);
g_signal_handlers_disconnect_by_func (
browser, tab_panel_browser_notify_tab_cb, treeview);
g_signal_handlers_disconnect_by_func (
browser, tab_panel_settings_notify_cb, model);
g_signal_handlers_disconnect_by_func (
@ -97,6 +124,8 @@ tab_panel_deactivate_cb (MidoriExtension* extension,
browser, tab_panel_view_notify_icon_cb, extension);
g_signal_handlers_disconnect_by_func (
browser, tab_panel_view_notify_title_cb, extension);
gtk_widget_destroy (treeview);
}
static void
@ -265,24 +294,8 @@ tab_panel_remove_view (MidoriBrowser* browser,
{
GtkTreeModel* model = tab_panel_get_model_for_browser (browser);
GtkTreeIter iter;
guint i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
{
MidoriView* view_;
gtk_tree_model_get (model, &iter, 0, &view_, -1);
if ((MidoriView*)view == view_)
{
if (tab_panel_get_iter_for_view (model, &iter, view))
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
g_object_unref (view_);
break;
}
g_object_unref (view_);
i++;
}
}
}
@ -317,24 +330,8 @@ tab_panel_view_notify_icon_cb (GtkWidget* view,
{
GtkTreeModel* model = tab_panel_get_model_for_browser (browser);
GtkTreeIter iter;
guint i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
{
MidoriView* view_;
gtk_tree_model_get (model, &iter, 0, &view_, -1);
if ((MidoriView*)view == view_)
{
if (tab_panel_get_iter_for_view (model, &iter, view))
gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 3, icon, -1);
g_object_unref (view_);
break;
}
g_object_unref (view_);
i++;
}
}
}
@ -356,24 +353,11 @@ tab_panel_view_notify_title_cb (GtkWidget* view,
{
GtkTreeModel* model = tab_panel_get_model_for_browser (browser);
GtkTreeIter iter;
guint i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
{
MidoriView* view_;
gtk_tree_model_get (model, &iter, 0, &view_, -1);
if ((MidoriView*)view == view_)
if (tab_panel_get_iter_for_view (model, &iter, view))
{
gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
4, title, 5, midori_view_get_label_ellipsize (view_), -1);
g_object_unref (view_);
break;
}
g_object_unref (view_);
i++;
4, title,
5, midori_view_get_label_ellipsize (MIDORI_VIEW (view)), -1);
}
}
}
@ -477,6 +461,26 @@ tab_panel_browser_remove_tab_cb (MidoriBrowser* browser,
tab_panel_remove_view (browser, view, minimized);
}
static void
tab_panel_browser_notify_tab_cb (MidoriBrowser* browser,
GParamSpec* pspec,
GtkTreeView* treeview)
{
GtkTreeModel* model = tab_panel_get_model_for_browser (browser);
GtkTreeIter iter;
GtkWidget* view;
if (GTK_OBJECT_FLAGS (browser) & GTK_IN_DESTRUCTION)
return;
view = midori_browser_get_current_tab (browser);
if (tab_panel_get_iter_for_view (model, &iter, view))
{
GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
gtk_tree_selection_select_iter (selection, &iter);
}
}
static void
tab_panel_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
@ -565,6 +569,8 @@ tab_panel_app_add_browser_cb (MidoriApp* app,
G_CALLBACK (tab_panel_browser_add_tab_cb), extension);
g_signal_connect (browser, "remove-tab",
G_CALLBACK (tab_panel_browser_remove_tab_cb), extension);
g_signal_connect (browser, "notify::tab",
G_CALLBACK (tab_panel_browser_notify_tab_cb), treeview);
g_signal_connect (extension, "deactivate",
G_CALLBACK (tab_panel_deactivate_cb), treeview);
}

View file

@ -610,9 +610,11 @@ MidoriExtension *extension_init(void)
{
MidoriExtension* extension = g_object_new(MIDORI_TYPE_EXTENSION,
"name", _("Toolbar Editor"),
"description", _("Easily edit the toolbar layout"),
#if !HAVE_HILDON
"description", _("Easily edit the toolbar layout"),
"version", "0.1",
#else
"description", _("Not available on this platform"),
#endif
"authors", "Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>",
NULL);

View file

@ -27,5 +27,5 @@ for extension in extensions:
obj.target = target
obj.includes = '..'
obj.source = source
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML'
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML HILDON'
obj.install_path = '${LIBDIR}/midori'

View file

@ -375,13 +375,56 @@ katze_array_find_token (KatzeArray* array,
i = 0;
while ((item = g_list_nth_data (array->items, i++)))
{
const gchar* found_token = katze_item_get_token ((KatzeItem*)item);
const gchar* found_token;
if (!KATZE_IS_ITEM (item))
continue;
found_token = ((KatzeItem*)item)->token;
if (!g_strcmp0 (found_token, token))
return item;
}
return NULL;
}
/**
* katze_array_find_uri:
* @array: a #KatzeArray
* @uri: an URI
*
* Looks up an item in the array which has the specified URI.
*
* This function will silently fail if the type of the list
* is not based on #GObject and only #KatzeItem children
* are checked for their token, any other objects are skipped.
*
* Return value: an item, or %NULL
*
* Since: 0.2.0
**/
gpointer
katze_array_find_uri (KatzeArray* array,
const gchar* uri)
{
guint i;
gpointer item;
if (!katze_array_is_a (array, G_TYPE_OBJECT))
return NULL;
i = 0;
while ((item = g_list_nth_data (array->items, i++)))
{
const gchar* found_uri;
if (!KATZE_IS_ITEM (item))
continue;
found_uri = ((KatzeItem*)item)->uri;
if (!g_strcmp0 (found_uri, uri))
return item;
}
return NULL;
}
/**
* katze_array_get_length:
* @array: a #KatzeArray

View file

@ -65,6 +65,10 @@ gpointer
katze_array_find_token (KatzeArray* array,
const gchar* token);
gpointer
katze_array_find_uri (KatzeArray* array,
const gchar* uri);
guint
katze_array_get_length (KatzeArray* array);

View file

@ -144,11 +144,12 @@ authentication_dialog_response_cb (GtkWidget* dialog,
{
GtkEntry* username = g_object_get_data (G_OBJECT (dialog), "username");
GtkEntry* password = g_object_get_data (G_OBJECT (dialog), "password");
GtkToggleButton* remember = g_object_get_data (G_OBJECT (dialog), "remember");
soup_auth_authenticate (save->auth,
gtk_entry_get_text (username), gtk_entry_get_text (password));
if (save->http_auth->filename)
if (gtk_toggle_button_get_active (remember) && save->http_auth->filename)
{
save->username = g_strdup (gtk_entry_get_text (username));
save->password = g_strdup (gtk_entry_get_text (password));
@ -261,6 +262,11 @@ katze_http_auth_session_authenticate_cb (SoupSession* session,
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
g_object_set_data (G_OBJECT (dialog), "password", entry);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
hbox = gtk_hbox_new (FALSE, 6);
label = gtk_check_button_new_with_mnemonic (_("_Remember password"));
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
g_object_set_data (G_OBJECT (dialog), "remember", label);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
@ -289,7 +295,7 @@ katze_http_auth_session_request_queued_cb (SoupSession* session,
g_signal_connect (session, "authenticate",
G_CALLBACK (katze_http_auth_session_authenticate_cb), http_auth);
g_signal_handlers_disconnect_by_func (session,
katze_http_auth_session_request_queued_cb, NULL);
katze_http_auth_session_request_queued_cb, http_auth);
}
static void

View file

@ -525,7 +525,6 @@ katze_net_load_icon (KatzeNet* net,
GtkWidget* widget,
gpointer user_data)
{
guint i;
KatzeNetIconPriv* priv;
gchar* icon_uri;
gchar* icon_file;
@ -535,12 +534,17 @@ katze_net_load_icon (KatzeNet* net,
g_return_val_if_fail (KATZE_IS_NET (net), NULL);
g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (uri != NULL, NULL);
pixbuf = NULL;
if (uri && (g_str_has_prefix (uri, "http://") ||
g_str_has_prefix (uri, "https://")))
icon_uri = g_strdup (g_object_get_data (G_OBJECT (net), uri));
g_object_set_data (G_OBJECT (net), uri, NULL);
if ((icon_uri && g_str_has_prefix (icon_uri, "http"))
|| g_str_has_prefix (uri, "http"))
{
i = 8;
if (!icon_uri)
{
guint i = 8;
while (uri[i] != '\0' && uri[i] != '/')
i++;
if (uri[i] == '/')
@ -551,6 +555,7 @@ katze_net_load_icon (KatzeNet* net,
}
else
icon_uri = g_strdup_printf ("%s/favicon.ico", uri);
}
icon_file = katze_net_get_cached_path (net, icon_uri, "icons");

1098
katze/katze-scrolled.c Normal file

File diff suppressed because it is too large Load diff

59
katze/katze-scrolled.h Normal file
View file

@ -0,0 +1,59 @@
/*
Copyright (C) 2007 Henrik Hedberg <hhedberg@innologies.fi>
Copyright (C) 2009 Nadav Wiener <nadavwr@yahoo.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.
See the file COPYING for the full license text.
*/
#ifndef KATZE_SCROLLED_H
#define KATZE_SCROLLED_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define KATZE_TYPE_SCROLLED (katze_scrolled_get_type())
#define KATZE_SCROLLED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), KATZE_TYPE_SCROLLED, KatzeScrolled))
#define KATZE_SCROLLED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), KATZE_TYPE_SCROLLED, KatzeScrolledClass))
#define KATZE_IS_SCROLLED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), KATZE_TYPE_SCROLLED))
#define KATZE_IS_SCROLLED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), KATZE_TYPE_SCROLLED))
#define KATZE_SCROLLED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), KATZE_TYPE_SCROLLED, KatzeScrolledClass))
typedef struct _KatzeScrolled KatzeScrolled;
typedef struct _KatzeScrolledClass KatzeScrolledClass;
typedef struct _KatzeScrolledPrivate KatzeScrolledPrivate;
struct _KatzeScrolled
{
GtkScrolledWindow parent;
KatzeScrolledPrivate* priv;
};
struct _KatzeScrolledClass
{
GtkScrolledWindowClass parent;
/* Padding for future expansion */
void (*_katze_reserved1) (void);
void (*_katze_reserved2) (void);
void (*_katze_reserved3) (void);
void (*_katze_reserved4) (void);
};
GType
katze_scrolled_get_type (void);
GtkWidget*
katze_scrolled_new (GtkAdjustment* hadjustment,
GtkAdjustment* vadjustment);
G_END_DECLS
#endif /* __KATZE_SCROLLED_H__ */

View file

@ -165,11 +165,14 @@ proxy_widget_string_destroy_cb (GtkWidget* proxy,
* "uri": the widget created will be particularly suitable for
* choosing an existing filename, encoded as an URI.
* "font": the widget created will be particularly suitable for
* choosing a font from installed fonts.
* choosing a variable-width font from installed fonts.
* Since 0.1.6 the following hints are also supported:
* "toggle": the widget created will be an empty toggle button. This
* is only supported with boolean properties.
* Since 0.1.8 "toggle" creates GtkCheckButton widgets without checkmarks.
* Since 0.2.0 the following hints are also supported:
* "font-monospace": the widget created will be particularly suitable for
* choosing a fixed-width font from installed fonts.
*
* Any other values for @hint are silently ignored.
*
@ -276,28 +279,38 @@ katze_property_proxy (gpointer object,
G_CALLBACK (proxy_uri_file_set_cb), object);
#endif
}
else if (type == G_TYPE_PARAM_STRING && _hint == g_intern_string ("font"))
else if (type == G_TYPE_PARAM_STRING && (_hint == g_intern_string ("font")
|| _hint == g_intern_string ("font-monospace")))
{
int n_families, i;
GtkComboBox* combo;
gint n_families, i;
PangoContext* context;
PangoFontFamily** families;
gboolean monospace = _hint == g_intern_string ("font-monospace");
string = katze_object_get_string (object, property);
widget = gtk_combo_box_new_text ();
combo = GTK_COMBO_BOX (widget);
context = gtk_widget_get_pango_context (widget);
pango_context_list_families (context, &families, &n_families);
if (!string)
string = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
if (string)
{
gint j = 0;
for (i = 0; i < n_families; i++)
{
const gchar* font = pango_font_family_get_name (families[i]);
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), font);
if (string && !strcmp (font, string))
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
if (monospace != pango_font_family_is_monospace (families[i]))
continue;
gtk_combo_box_append_text (combo, font);
if (!g_ascii_strcasecmp (font, string))
gtk_combo_box_set_active (combo, j);
j++;
}
}
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (
gtk_combo_box_get_model (GTK_COMBO_BOX (widget))),
0, GTK_SORT_ASCENDING);
gtk_combo_box_get_model (combo)), 0, GTK_SORT_ASCENDING);
g_signal_connect (widget, "changed",
G_CALLBACK (proxy_combo_box_text_changed_cb), object);
g_free (families);

View file

@ -21,5 +21,6 @@
#include "katze-arrayaction.h"
#include "katze-separatoraction.h"
#include "katze-net.h"
#include "katze-scrolled.h"
#endif /* __KATZE_H__ */

View file

@ -94,7 +94,7 @@ settings_new_from_file (const gchar* filename,
{
if (error->code == G_FILE_ERROR_NOENT)
{
gchar* config_file = sokoke_find_config_filename ("config");
gchar* config_file = sokoke_find_config_filename (NULL, "config");
g_key_file_load_from_file (key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, NULL);
}
@ -960,11 +960,6 @@ midori_app_add_browser_cb (MidoriApp* app,
gtk_widget_show (addon);
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
/* Userstyles */
addon = midori_addons_new (MIDORI_ADDON_USER_STYLES, GTK_WIDGET (browser));
gtk_widget_show (addon);
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
/* Plugins */
addon = g_object_new (MIDORI_TYPE_PLUGINS, "app", app, NULL);
gtk_widget_show (addon);
@ -1155,6 +1150,17 @@ static void
button_reset_session_clicked_cb (GtkWidget* button,
KatzeArray* session)
{
gchar* config_file;
GError* error;
config_file = build_config_filename ("session.old.xbel");
error = NULL;
if (!midori_array_to_file (session, config_file, "xbel", &error))
{
g_warning (_("The session couldn't be saved. %s"), error->message);
g_error_free (error);
}
g_free (config_file);
katze_array_clear (session);
gtk_widget_set_sensitive (button, FALSE);
}
@ -1179,7 +1185,16 @@ midori_create_diagnostic_dialog (MidoriWebSettings* settings,
MidoriApp* app = katze_item_get_parent (KATZE_ITEM (_session));
dialog = gtk_message_dialog_new (
NULL, 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
NULL, 0, GTK_MESSAGE_WARNING,
#if HAVE_HILDON
#if HILDON_CHECK_VERSION (2, 2, 0)
GTK_BUTTONS_NONE,
#else
GTK_BUTTONS_OK,
#endif
#else
GTK_BUTTONS_OK,
#endif
_("Midori seems to have crashed the last time it was opened. "
"If this happened repeatedly, try one of the following options "
"to solve the problem."));
@ -1213,6 +1228,19 @@ midori_create_diagnostic_dialog (MidoriWebSettings* settings,
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 4);
gtk_widget_show_all (box);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), box);
#if HAVE_HILDON
#if HILDON_CHECK_VERSION (2, 2, 0)
box = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, FALSE, 4);
button = hildon_gtk_button_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_HALFSCREEN_WIDTH);
gtk_button_set_label (GTK_BUTTON (button), GTK_STOCK_OK);
gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy), dialog);
gtk_box_pack_start (GTK_BOX (box), button, TRUE, FALSE, 4);
gtk_widget_show_all (box);
#endif
#endif
if (1)
{
/* GtkLabel can't wrap the text properly. Until some day
@ -1344,6 +1372,32 @@ midori_load_extensions (gpointer data)
return FALSE;
}
static void
midori_browser_action_last_session_activate_cb (GtkAction* action,
MidoriBrowser* browser)
{
KatzeArray* old_session = katze_array_new (KATZE_TYPE_ITEM);
gchar* config_file = build_config_filename ("session.old.xbel");
GError* error = NULL;
if (midori_array_from_file (old_session, config_file, "xbel", &error))
{
guint i = 0;
KatzeItem* item;
while ((item = katze_array_get_nth_item (old_session, i++)))
midori_browser_add_item (browser, item);
}
else
{
g_warning (_("The session couldn't be loaded: %s\n"), error->message);
/* FIXME: Show a graphical dialog */
g_error_free (error);
}
g_free (config_file);
gtk_action_set_sensitive (action, FALSE);
g_signal_handlers_disconnect_by_func (action,
midori_browser_action_last_session_activate_cb, browser);
}
static gboolean
midori_load_session (gpointer data)
{
@ -1358,10 +1412,19 @@ midori_load_session (gpointer data)
gchar** command = g_object_get_data (G_OBJECT (app), "execute-command");
browser = midori_app_create_browser (app);
config_file = build_config_filename ("session.old.xbel");
if (g_file_test (config_file, G_FILE_TEST_EXISTS))
{
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
GtkAction* action = gtk_action_group_get_action (action_group, "LastSession");
g_signal_connect (action, "activate",
G_CALLBACK (midori_browser_action_last_session_activate_cb), browser);
gtk_action_set_sensitive (action, TRUE);
}
midori_app_add_browser (app, browser);
gtk_widget_show (GTK_WIDGET (browser));
config_file = build_config_filename ("accels");
katze_assign (config_file, build_config_filename ("accels"));
if (is_writable (config_file))
g_signal_connect_after (gtk_accel_map_get (), "changed",
G_CALLBACK (accel_map_changed_cb), NULL);
@ -1571,8 +1634,8 @@ main (int argc,
#if ENABLE_NLS
setlocale (LC_ALL, "");
if (g_getenv ("NLSPATH"))
bindtextdomain (GETTEXT_PACKAGE, g_getenv ("NLSPATH"));
if (g_getenv ("MIDORI_NLSPATH"))
bindtextdomain (GETTEXT_PACKAGE, g_getenv ("MIDORI_NLSPATH"));
else
#ifdef G_OS_WIN32
{
@ -1731,6 +1794,14 @@ main (int argc,
{
/* TODO: Open a tab per URI, seperated by pipes */
/* FIXME: Handle relative files or magic URI here */
/* Encode any IDN addresses because libUnique doesn't like them */
i = 0;
while (uris[i] != NULL)
{
gchar* new_uri = sokoke_uri_to_ascii (uris[i]);
katze_assign (uris[i], new_uri);
i++;
}
result = midori_app_instance_send_uris (app, uris);
}
else
@ -1777,7 +1848,7 @@ main (int argc,
search_engines = search_engines_new_from_file (config_file, NULL);
#else
katze_assign (config_file,
sokoke_find_config_filename ("search"));
sokoke_find_config_filename (NULL, "search"));
search_engines = search_engines_new_from_file (config_file, NULL);
#endif
}
@ -1798,7 +1869,7 @@ main (int argc,
if (error->code == G_FILE_ERROR_NOENT)
{
katze_assign (config_file,
sokoke_find_config_filename ("bookmarks.xbel"));
sokoke_find_config_filename (NULL, "bookmarks.xbel"));
midori_array_from_file (bookmarks, config_file, "xbel", NULL);
}
else

View file

@ -364,8 +364,13 @@ katze_item_metadata_to_xbel (KatzeItem* item)
i = 0;
while ((key = g_list_nth_data (keys, i++)))
if (katze_item_get_meta_string (item, key))
{
gchar* escaped =
g_markup_escape_text (katze_item_get_meta_string (item, key), -1);
g_string_append_printf (markup, " %s:%s=\"%s\"", namespace, key,
katze_item_get_meta_string (item, key));
escaped);
g_free (escaped);
}
g_string_append_printf (markup, "/>\n</info>\n");
return g_string_free (markup, FALSE);
}

File diff suppressed because it is too large Load diff

View file

@ -272,11 +272,22 @@ midori_extension_activate_cb (MidoriExtension* extension,
if (!g_key_file_load_from_file (extension->priv->key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, &error))
{
if (error->code != G_FILE_ERROR_NOENT)
if (error->code == G_FILE_ERROR_NOENT)
{
gchar* filename = g_object_get_data (G_OBJECT (extension), "filename");
gchar* folder = g_strconcat ("extensions/", filename, NULL);
katze_assign (config_file,
sokoke_find_config_filename (folder, "config"));
g_free (folder);
g_key_file_load_from_file (extension->priv->key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, NULL);
}
else
printf (_("The configuration of the extension '%s' couldn't be loaded: %s\n"),
extension->priv->name, error->message);
g_error_free (error);
}
g_free (config_file);
}
while (lsettings)

View file

@ -26,6 +26,7 @@ struct _MidoriLocationAction
{
GtkAction parent_instance;
gchar* text;
gchar* uri;
KatzeArray* search_engines;
gdouble progress;
@ -352,7 +353,7 @@ midori_location_action_create_model (void)
static void
midori_location_action_init (MidoriLocationAction* location_action)
{
location_action->uri = NULL;
location_action->text = location_action->uri = NULL;
location_action->search_engines = NULL;
location_action->progress = 0.0;
location_action->secondary_icon = NULL;
@ -374,6 +375,7 @@ midori_location_action_finalize (GObject* object)
{
MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (object);
katze_assign (location_action->text, NULL);
katze_assign (location_action->uri, NULL);
katze_assign (location_action->search_engines, NULL);
@ -551,8 +553,15 @@ midori_location_action_create_tool_item (GtkAction* action)
return toolitem;
}
static void
midori_location_action_changed_cb (GtkEntry* entry,
MidoriLocationAction* location_action)
{
katze_assign (location_action->text, g_strdup (gtk_entry_get_text (entry)));
}
static gboolean
midori_location_action_key_press_event_cb (GtkWidget* widget,
midori_location_action_key_press_event_cb (GtkEntry* entry,
GdkEventKey* event,
GtkAction* action)
{
@ -564,7 +573,7 @@ midori_location_action_key_press_event_cb (GtkWidget* widget,
case GDK_KP_Enter:
case GDK_Return:
{
if ((uri = gtk_entry_get_text (GTK_ENTRY (widget))) && *uri)
if ((uri = gtk_entry_get_text (entry)) && *uri)
{
g_signal_emit (action, signals[SUBMIT_URI], 0, uri,
(event->state & GDK_MOD1_MASK) ? TRUE : FALSE);
@ -733,9 +742,10 @@ midori_location_entry_completion_match_cb (GtkEntryCompletion* completion,
temp = g_utf8_casefold (title, -1);
match = (strstr (temp, key) != NULL);
g_free (temp);
}
}
g_free (title);
}
}
return match;
}
@ -826,41 +836,51 @@ midori_location_action_iter_insert (MidoriLocationAction* location_action,
static void
midori_location_action_set_item (MidoriLocationAction* location_action,
MidoriLocationEntryItem* item,
GdkPixbuf* icon,
const gchar* uri,
const gchar* title,
gboolean increment_visits,
gboolean filter)
{
GtkTreeModel* model;
GtkTreeModel* filter_model;
GtkTreeIter iter;
GdkPixbuf* icon;
GdkPixbuf* new_icon;
gint visits = 0;
gchar* _title = NULL;
GdkPixbuf* original_icon = NULL;
model = location_action->model;
if (midori_location_action_iter_insert (location_action,
item->uri, &iter, G_MAXINT))
if (midori_location_action_iter_insert (location_action, uri, &iter, G_MAXINT))
gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
gtk_tree_model_get (model, &iter, FAVICON_COL, &original_icon, -1);
if (increment_visits)
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
VISITS_COL, ++visits, VISIBLE_COL, TRUE, -1);
/* Ensure we keep the title if we added the same URI with a title before */
if (!item->title)
gtk_tree_model_get (model, &iter, TITLE_COL, &item->title, -1);
if (!title)
{
gtk_tree_model_get (model, &iter, TITLE_COL, &_title, -1);
title = _title;
}
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
URI_COL, item->uri, TITLE_COL, item->title, YALIGN_COL, 0.25, -1);
URI_COL, uri, TITLE_COL, title, YALIGN_COL, 0.25, -1);
g_free (_title);
gtk_tree_model_get (model, &iter, FAVICON_COL, &icon, -1);
if (item->favicon)
new_icon = item->favicon;
else if (!icon)
new_icon = location_action->default_icon;
else
if (icon)
new_icon = icon;
else if (original_icon)
{
new_icon = NULL;
g_object_unref (original_icon);
}
else
new_icon = location_action->default_icon;
if (new_icon)
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
FAVICON_COL, new_icon, -1);
@ -896,7 +916,7 @@ midori_location_entry_match_selected_cb (GtkEntryCompletion* completion,
gchar* uri;
gtk_tree_model_get (model, iter, URI_COL, &uri, -1);
midori_location_action_set_uri (location_action, uri);
midori_location_action_set_text (location_action, uri);
g_signal_emit (location_action, signals[SUBMIT_URI], 0, uri, FALSE);
g_free (uri);
@ -919,7 +939,7 @@ midori_location_entry_action_activated_cb (GtkEntryCompletion* completion,
if (!item)
return;
search = sokoke_search_uri (uri, keywords);
midori_location_action_set_uri (location_action, search);
midori_location_action_set_text (location_action, search);
g_signal_emit (location_action, signals[SUBMIT_URI], 0, search, FALSE);
g_free (search);
}
@ -1018,10 +1038,13 @@ midori_location_action_entry_changed_cb (GtkComboBox* combo_box,
gtk_tree_model_get (model, &iter, FAVICON_COL, &pixbuf,
URI_COL, &uri, -1);
#if !HAVE_HILDON
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, pixbuf);
#endif
g_object_unref (pixbuf);
katze_assign (location_action->uri, uri);
katze_assign (location_action->text, uri);
katze_assign (location_action->uri, g_strdup (uri));
g_signal_emit (location_action, signals[ACTIVE_CHANGED], 0,
gtk_combo_box_get_active (combo_box));
@ -1074,6 +1097,8 @@ midori_location_action_connect_proxy (GtkAction* action,
G_CALLBACK (midori_location_action_entry_changed_cb), action);
g_object_connect (gtk_bin_get_child (GTK_BIN (entry)),
"signal::changed",
midori_location_action_changed_cb, action,
"signal::key-press-event",
midori_location_action_key_press_event_cb, action,
"signal::focus-in-event",
@ -1098,6 +1123,14 @@ midori_location_action_disconnect_proxy (GtkAction* action,
(action, proxy);
}
/**
* midori_location_action_get_uri:
* @location_action: a #MidoriLocationAction
*
* Retrieves the current URI. See also midori_location_action_get_text().
*
* Return value: the current URI
**/
const gchar*
midori_location_action_get_uri (MidoriLocationAction* location_action)
{
@ -1106,14 +1139,35 @@ midori_location_action_get_uri (MidoriLocationAction* location_action)
return location_action->uri;
}
/**
* midori_location_action_get_text:
* @location_action: a #MidoriLocationAction
*
* Retrieves the current text, which may be the current URI or
* anything typed in the entry.
*
* Return value: the current text
*
* Since: 0.2.0
**/
const gchar*
midori_location_action_get_text (MidoriLocationAction* location_action)
{
g_return_val_if_fail (MIDORI_IS_LOCATION_ACTION (location_action), NULL);
return location_action->text;
}
/**
* midori_location_action_set_text:
* @location_action: a #MidoriLocationAction
* @text: a string
*
* Sets the entry text to @text and, if applicable, updates the icon.
*
* Since: 0.2.0
**/
static void
void
midori_location_action_set_text (MidoriLocationAction* location_action,
const gchar* text)
{
@ -1123,12 +1177,20 @@ midori_location_action_set_text (MidoriLocationAction* location_action,
GtkTreeIter iter;
GdkPixbuf* icon;
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
g_return_if_fail (text != NULL);
katze_assign (location_action->text, g_strdup (text));
if (!(proxies = gtk_action_get_proxies (GTK_ACTION (location_action))))
return;
if (midori_location_action_iter_lookup (location_action, text, &iter))
{
gtk_tree_model_get (location_action->model,
&iter, FAVICON_COL, &icon, -1);
katze_assign (location_action->uri, g_strdup (text));
}
else
icon = g_object_ref (location_action->default_icon);
@ -1139,14 +1201,25 @@ midori_location_action_set_text (MidoriLocationAction* location_action,
entry = gtk_bin_get_child (GTK_BIN (location_entry));
gtk_entry_set_text (GTK_ENTRY (entry), text);
#if !HAVE_HILDON
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, icon);
#endif
}
if (icon)
g_object_unref (icon);
}
/**
* midori_location_action_set_uri:
* @location_action: a #MidoriLocationAction
* @uri: an URI string
*
* Sets the entry URI to @uri and, if applicable, updates the icon.
*
* Deprecated: 0.2.0
**/
void
midori_location_action_set_uri (MidoriLocationAction* location_action,
const gchar* uri)
@ -1177,6 +1250,7 @@ midori_location_action_set_icon (MidoriLocationAction* location_action,
GtkWidget* location_entry;
GtkWidget* entry;
#if !HAVE_HILDON
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
@ -1195,24 +1269,20 @@ midori_location_action_set_icon (MidoriLocationAction* location_action,
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_JUMP_TO);
}
#endif
}
void
midori_location_action_add_uri (MidoriLocationAction* location_action,
const gchar* uri)
{
MidoriLocationEntryItem item;
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
g_return_if_fail (uri != NULL);
if (midori_location_action_is_frozen (location_action))
return;
item.favicon = NULL;
item.uri = uri;
item.title = NULL;
midori_location_action_set_item (location_action, &item, TRUE, TRUE);
midori_location_action_set_item (location_action, NULL, uri, NULL, TRUE, TRUE);
katze_assign (location_action->uri, g_strdup (uri));
}
@ -1226,28 +1296,23 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
GSList* proxies;
GtkWidget* location_entry;
GtkWidget* entry;
MidoriLocationEntryItem item;
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
g_return_if_fail (uri != NULL);
g_return_if_fail (title != NULL);
g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
item.favicon = icon;
item.uri = uri;
item.title = title;
midori_location_action_set_item (location_action, &item, TRUE, FALSE);
midori_location_action_set_item (location_action, icon, uri, title, TRUE, FALSE);
#if !HAVE_HILDON
if (midori_location_action_is_frozen (location_action))
return;
katze_assign (location_action->uri, g_strdup (uri));
proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
if (!g_strcmp0 (location_action->uri, uri))
for (; proxies != NULL; proxies = g_slist_next (proxies))
if (GTK_IS_TOOL_ITEM (proxies->data) &&
!strcmp (location_action->uri, uri))
if (GTK_IS_TOOL_ITEM (proxies->data))
{
location_entry = midori_location_action_entry_for_proxy (proxies->data);
entry = gtk_bin_get_child (GTK_BIN (location_entry));
@ -1255,6 +1320,7 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, icon);
}
#endif
}
void
@ -1265,22 +1331,19 @@ midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
GSList* proxies;
GtkWidget* location_entry;
GtkWidget* entry;
MidoriLocationEntryItem item;
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);
item.favicon = icon;
item.uri = uri;
item.title = NULL;
midori_location_action_set_item (location_action, &item, FALSE, TRUE);
midori_location_action_set_item (location_action, icon, uri, NULL, FALSE, TRUE);
#if !HAVE_HILDON
proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
if (!g_strcmp0 (location_action->uri, uri))
for (; proxies != NULL; proxies = g_slist_next (proxies))
if (GTK_IS_TOOL_ITEM (proxies->data) &&
!g_strcmp0 (location_action->uri, uri))
if (GTK_IS_TOOL_ITEM (proxies->data))
{
location_entry = midori_location_action_entry_for_proxy (proxies->data);
entry = gtk_bin_get_child (GTK_BIN (location_entry));
@ -1288,6 +1351,7 @@ midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, icon);
}
#endif
}
void
@ -1295,16 +1359,11 @@ midori_location_action_set_title_for_uri (MidoriLocationAction* location_action,
const gchar* title,
const gchar* uri)
{
MidoriLocationEntryItem item;
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
g_return_if_fail (title != NULL);
g_return_if_fail (uri != NULL);
item.favicon = NULL;
item.uri = uri;
item.title = title;
midori_location_action_set_item (location_action, &item, FALSE, TRUE);
midori_location_action_set_item (location_action, NULL, uri, title, FALSE, TRUE);
}
/**
@ -1400,6 +1459,7 @@ midori_location_action_set_secondary_icon (MidoriLocationAction* location_action
katze_assign (location_action->secondary_icon, g_strdup (stock_id));
#if !HAVE_HILDON
proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
for (; proxies != NULL; proxies = g_slist_next (proxies))
@ -1411,6 +1471,7 @@ midori_location_action_set_secondary_icon (MidoriLocationAction* location_action
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (child),
GTK_ICON_ENTRY_SECONDARY, stock_id);
}
#endif
}
/**

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
Copyright (C) 2008-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
@ -34,13 +34,6 @@ G_BEGIN_DECLS
typedef struct _MidoriLocationAction MidoriLocationAction;
typedef struct _MidoriLocationActionClass MidoriLocationActionClass;
struct _MidoriLocationEntryItem
{
GdkPixbuf* favicon;
const gchar* uri;
const gchar* title;
};
GType
midori_location_action_get_type (void);
@ -50,6 +43,13 @@ midori_location_action_freeze (MidoriLocationAction* location_actio
void
midori_location_action_thaw (MidoriLocationAction* location_action);
const gchar*
midori_location_action_get_text (MidoriLocationAction* location_action);
void
midori_location_action_set_text (MidoriLocationAction* location_action,
const gchar* text);
const gchar*
midori_location_action_get_uri (MidoriLocationAction* location_action);

View file

@ -379,10 +379,12 @@ midori_location_entry_init (MidoriLocationEntry* location_entry)
location_entry->progress = 0.0;
entry = gtk_icon_entry_new ();
#if !HAVE_HILDON
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FILE);
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_SECONDARY, TRUE);
#endif
g_signal_connect_after (entry, "key-press-event",
G_CALLBACK (entry_key_press_event), location_entry);
#if !GTK_CHECK_VERSION (2, 16, 0)
@ -407,6 +409,11 @@ entry_key_press_event (GtkWidget* widget,
gtk_combo_box_popup (GTK_COMBO_BOX (location_entry));
return TRUE;
}
case GDK_Page_Up:
case GDK_Page_Down:
{
return TRUE;
}
}
return FALSE;

View file

@ -25,7 +25,6 @@ G_BEGIN_DECLS
typedef struct _MidoriLocationEntry MidoriLocationEntry;
typedef struct _MidoriLocationEntryClass MidoriLocationEntryClass;
typedef struct _MidoriLocationEntryItem MidoriLocationEntryItem;
GType
midori_location_entry_get_type (void);

View file

@ -356,8 +356,7 @@ midori_panel_init (MidoriPanel* panel)
gtk_toolbar_set_style (GTK_TOOLBAR (panel->toolbar), GTK_TOOLBAR_BOTH);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (panel->toolbar),
GTK_ICON_SIZE_BUTTON);
gtk_toolbar_set_orientation (GTK_TOOLBAR (panel->toolbar),
GTK_ORIENTATION_VERTICAL);
g_object_set (panel->toolbar, "orientation", GTK_ORIENTATION_VERTICAL, NULL);
gtk_box_pack_start (GTK_BOX (panel), panel->toolbar, FALSE, FALSE, 0);
gtk_widget_show_all (panel->toolbar);
vbox = gtk_vbox_new (FALSE, 0);

View file

@ -315,6 +315,9 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
GtkWidget* header;
GtkWindow* parent;
const gchar* icon_name;
#if WEBKIT_CHECK_VERSION (1, 1, 15)
GtkSettings* gtk_settings;
#endif
GtkSizeGroup* sizegroup;
GtkWidget* toolbar;
GtkWidget* toolbutton;
@ -341,6 +344,9 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
gtk_window_get_title (GTK_WINDOW (preferences)))))
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
header, FALSE, FALSE, 0);
#if WEBKIT_CHECK_VERSION (1, 1, 15)
gtk_settings = parent ? gtk_widget_get_settings (GTK_WIDGET (parent)) : NULL;
#endif
preferences->notebook = gtk_notebook_new ();
gtk_container_set_border_width (GTK_CONTAINER (preferences->notebook), 6);
@ -429,7 +435,6 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
button = katze_property_proxy (settings, "download-folder", "folder");
FILLED_ADD (button, 1, 2, 0, 1);
label = katze_property_proxy (settings, "ask-for-destination-folder", NULL);
gtk_widget_set_sensitive (label, FALSE);
INDENTED_ADD (label, 0, 1, 1, 2);
button = katze_property_proxy (settings, "notify-transfer-completed", NULL);
/* FIXME: Disable the option if notifications presumably cannot be sent
@ -453,7 +458,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
label = gtk_label_new (_("Fixed-width Font Family"));
INDENTED_ADD (label, 0, 1, 1, 2);
hbox = gtk_hbox_new (FALSE, 4);
button = katze_property_proxy (settings, "monospace-font-family", "font");
button = katze_property_proxy (settings, "monospace-font-family", "font-monospace");
gtk_widget_set_tooltip_text (button, _("The font family used to display fixed-width text"));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
entry = katze_property_proxy (settings, "default-monospace-font-size", NULL);
@ -487,10 +492,15 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
gtk_button_set_label (GTK_BUTTON (button), _("Load images automatically"));
gtk_widget_set_tooltip_text (button, _("Load and display images automatically"));
INDENTED_ADD (button, 0, 1, 0, 1);
#if 0
#if WEBKIT_CHECK_VERSION (1, 1, 15)
if (katze_object_get_boolean (gtk_settings, "gtk-touchscreen-mode"))
button = katze_property_proxy (settings, "kinetic-scrolling", NULL);
else
{
button = katze_property_proxy (settings, "auto-shrink-images", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Shrink images automatically"));
gtk_widget_set_tooltip_text (button, _("Automatically shrink standalone images to fit"));
}
#else
button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
#endif

View file

@ -28,7 +28,6 @@
#define STOCK_WEB_BROWSER "web-browser"
#define STOCK_NEWS_FEED "news-feed"
#define STOCK_STYLE "gnome-settings-theme"
#define STOCK_STYLES "gnome-settings-theme"
#define STOCK_TRANSFER "package"
#define STOCK_TRANSFERS "package"
#define STOCK_PLUGINS GTK_STOCK_CONVERT
@ -38,7 +37,7 @@
#define STOCK_IMAGE "gnome-mime-image"
#define STOCK_NETWORK_OFFLINE "network-offline"
#define STOCK_SCRIPT "stock_script"
#define STOCK_SCRIPTS "stock_script"
#define STOCK_SCRIPTS "gnome-settings-theme"
#define STOCK_SEND "stock_mail-send"
#define STOCK_TAB_NEW "stock_new-tab"
#define STOCK_USER_TRASH "gnome-stock-trash"

File diff suppressed because it is too large Load diff

View file

@ -75,6 +75,7 @@ struct _MidoriWebSettings
gboolean zoom_text_and_images;
gboolean find_while_typing;
gboolean kinetic_scrolling;
MidoriAcceptCookies accept_cookies;
gboolean original_cookies_only;
gint maximum_cookie_age;
@ -151,6 +152,7 @@ enum
PROP_ZOOM_TEXT_AND_IMAGES,
PROP_FIND_WHILE_TYPING,
PROP_KINETIC_SCROLLING,
PROP_ACCEPT_COOKIES,
PROP_ORIGINAL_COOKIES_ONLY,
PROP_MAXIMUM_COOKIE_AGE,
@ -286,6 +288,7 @@ midori_identity_get_type (void)
static const GEnumValue values[] = {
{ MIDORI_IDENT_MIDORI, "MIDORI_IDENT_MIDORI", N_("Midori") },
{ MIDORI_IDENT_SAFARI, "MIDORI_IDENT_SAFARI", N_("Safari") },
{ MIDORI_IDENT_IPHONE, "MIDORI_IDENT_IPHONE", N_("iPhone") },
{ MIDORI_IDENT_FIREFOX, "MIDORI_IDENT_FIREFOX", N_("Firefox") },
{ MIDORI_IDENT_EXPLORER, "MIDORI_IDENT_EXPLORER", N_("Internet Explorer") },
{ MIDORI_IDENT_CUSTOM, "MIDORI_IDENT_CUSTOM", N_("Custom...") },
@ -519,7 +522,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
"toolbar-items",
_("Toolbar Items"),
_("The items to show on the toolbar"),
"Back,Forward,ReloadStop,Location,Panel,Search,Trash",
"TabNew,Back,Forward,ReloadStop,Location,Panel,Search,Trash",
flags));
g_object_class_install_property (gobject_class,
@ -634,6 +637,8 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
*
* Whether to ask for the destination folder when downloading a file.
*
* Note: Only since 0.2.0 is this value actually used.
*
* Since: 0.1.7
*/
g_object_class_install_property (gobject_class,
@ -643,7 +648,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
_("Ask for the destination folder"),
_("Whether to ask for the destination folder when downloading a file"),
FALSE,
#if WEBKIT_CHECK_VERSION (1, 1, 3)
#if WEBKIT_CHECK_VERSION (1, 1, 15)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
#else
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
@ -830,6 +835,22 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
FALSE,
flags));
/**
* MidoriWebSettings:kinetic-scrolling:
*
* Whether scrolling should kinetically move according to speed.
*
* Since: 0.2.0
*/
g_object_class_install_property (gobject_class,
PROP_KINETIC_SCROLLING,
g_param_spec_boolean (
"kinetic-scrolling",
_("Kinetic scrolling"),
_("Whether scrolling should kinetically move according to speed"),
TRUE,
flags));
g_object_class_install_property (gobject_class,
PROP_ACCEPT_COOKIES,
g_param_spec_enum (
@ -1022,6 +1043,7 @@ midori_web_settings_init (MidoriWebSettings* web_settings)
web_settings->open_popups_in_tabs = TRUE;
web_settings->remember_last_form_inputs = TRUE;
web_settings->remember_last_downloaded_files = TRUE;
web_settings->kinetic_scrolling = TRUE;
web_settings->auto_detect_proxy = TRUE;
g_signal_connect (web_settings, "notify::default-encoding",
@ -1109,19 +1131,23 @@ generate_ident_string (MidoriIdentity identify_as)
#define WEBKIT_USER_AGENT_MAJOR_VERSION 532
#define WEBKIT_USER_AGENT_MINOR_VERSION 1
#endif
const gchar* webcore = "WebKit/" G_STRINGIFY (WEBKIT_USER_AGENT_MAJOR_VERSION)
"." G_STRINGIFY (WEBKIT_USER_AGENT_MINOR_VERSION) "+";
const int webcore_major = WEBKIT_USER_AGENT_MAJOR_VERSION;
const int webcore_minor = WEBKIT_USER_AGENT_MINOR_VERSION;
switch (identify_as)
{
case MIDORI_IDENT_MIDORI:
return g_strdup_printf ("%s (%s; %s; U; %s) %s",
appname, platform, os, lang, webcore);
return g_strdup_printf ("%s (%s; %s; U; %s) WebKit/%d.%d+",
appname, platform, os, lang, webcore_major, webcore_minor);
case MIDORI_IDENT_SAFARI:
return g_strdup_printf ("Mozilla/5.0 (%s; U; %s; %s) "
"AppleWebKit/532+ (KHTML, like Gecko) Safari/%s %s",
platform, os, lang, webcore, appname);
"AppleWebKit/%d+ (KHTML, like Gecko) Safari/%d.%d+ %s",
platform, os, lang, webcore_major, webcore_major, webcore_minor, appname);
case MIDORI_IDENT_IPHONE:
return g_strdup_printf ("Mozilla/5.0 (iPhone; U; %s; %s) "
"AppleWebKit/532+ (KHTML, like Gecko) Version/3.0 Mobile/1A538b "
"Safari/419.3 %s",
os, lang, appname);
case MIDORI_IDENT_FIREFOX:
return g_strdup_printf ("Mozilla/5.0 (%s; U; %s; %s; rv:1.8.1) "
"Gecko/20061010 Firefox/2.0 %s",
@ -1296,6 +1322,9 @@ midori_web_settings_set_property (GObject* object,
case PROP_FIND_WHILE_TYPING:
web_settings->find_while_typing = g_value_get_boolean (value);
break;
case PROP_KINETIC_SCROLLING:
web_settings->kinetic_scrolling = g_value_get_boolean (value);
break;
case PROP_ACCEPT_COOKIES:
web_settings->accept_cookies = g_value_get_enum (value);
break;
@ -1499,6 +1528,9 @@ midori_web_settings_get_property (GObject* object,
case PROP_FIND_WHILE_TYPING:
g_value_set_boolean (value, web_settings->find_while_typing);
break;
case PROP_KINETIC_SCROLLING:
g_value_set_boolean (value, web_settings->kinetic_scrolling);
break;
case PROP_ACCEPT_COOKIES:
g_value_set_enum (value, web_settings->accept_cookies);
break;

View file

@ -133,9 +133,10 @@ typedef enum
{
MIDORI_IDENT_MIDORI,
MIDORI_IDENT_SAFARI,
MIDORI_IDENT_IPHONE,
MIDORI_IDENT_FIREFOX,
MIDORI_IDENT_EXPLORER,
MIDORI_IDENT_CUSTOM
MIDORI_IDENT_CUSTOM,
} MidoriIdentity;
GType

View file

@ -185,41 +185,31 @@ sokoke_spawn_program (const gchar* command,
return TRUE;
}
static gchar*
sokoke_idn_to_punycode (gchar* uri)
/**
* sokoke_hostname_from_uri:
* @uri: an URI string
* @path: location of a string pointer
*
* Returns the hostname of the specified URI,
* and stores the path in @path.
* @path is at least set to ""
*
* Return value: a newly allocated hostname
**/
gchar*
sokoke_hostname_from_uri (const gchar* uri,
gchar** path)
{
#if HAVE_LIBIDN
gchar* proto;
gchar* hostname;
gchar* path;
char *s;
uint32_t *q;
int rc;
gchar *result;
if ((proto = g_utf8_strchr (uri, -1, ':')))
{
gulong offset;
gchar* buffer;
/* 'file' URIs don't have a hostname */
if (!strcmp (proto, "file"))
return uri;
offset = g_utf8_pointer_to_offset (uri, proto);
buffer = g_malloc0 (offset + 1);
g_utf8_strncpy (buffer, uri, offset);
proto = buffer;
}
path = NULL;
*path = "";
if ((hostname = g_utf8_strchr (uri, -1, '/')))
{
if (hostname[1] == '/')
hostname += 2;
if ((path = g_utf8_strchr (hostname, -1, '/')))
if ((*path = g_utf8_strchr (hostname, -1, '/')))
{
gulong offset = g_utf8_pointer_to_offset (hostname, path);
gulong offset = g_utf8_pointer_to_offset (hostname, *path);
gchar* buffer = g_malloc0 (offset + 1);
g_utf8_strncpy (buffer, hostname, offset);
hostname = buffer;
@ -229,35 +219,90 @@ sokoke_idn_to_punycode (gchar* uri)
}
else
hostname = g_strdup (uri);
if (!(q = stringprep_utf8_to_ucs4 (hostname, -1, NULL)))
{
g_free (proto);
g_free (hostname);
return uri;
return hostname;
}
rc = idna_to_ascii_4z (q, &s, IDNA_ALLOW_UNASSIGNED);
/**
* sokoke_hostname_to_ascii:
* @uri: an URI string
*
* The specified hostname is encoded if it is not ASCII.
*
* If no IDN support is available at compile time,
* the hostname will be returned unaltered.
*
* Return value: a newly allocated hostname
**/
static gchar*
sokoke_hostname_to_ascii (const gchar* hostname)
{
#ifdef HAVE_LIBSOUP_2_27_90
return g_hostname_to_ascii (hostname);
#elif HAVE_LIBIDN
uint32_t* q;
char* encoded;
int rc;
if ((q = stringprep_utf8_to_ucs4 (hostname, -1, NULL)))
{
rc = idna_to_ascii_4z (q, &encoded, IDNA_ALLOW_UNASSIGNED);
free (q);
if (rc != IDNA_SUCCESS)
{
g_free (proto);
g_free (hostname);
return uri;
if (rc == IDNA_SUCCESS)
return encoded;
}
#endif
return g_strdup (hostname);
}
if (proto)
/**
* sokoke_uri_to_ascii:
* @uri: an URI string
*
* The specified URI is parsed and the hostname
* part of it is encoded if it is not ASCII.
*
* If no IDN support is available at compile time,
* the URI will be returned unaltered.
*
* Return value: a newly allocated URI
**/
gchar*
sokoke_uri_to_ascii (const gchar* uri)
{
result = g_strconcat (proto, "://", s, path ? path : "", NULL);
g_free (proto);
if (path)
g_free (hostname);
gchar* proto;
if ((proto = g_utf8_strchr (uri, -1, ':')))
{
gulong offset;
gchar* buffer;
offset = g_utf8_pointer_to_offset (uri, proto);
buffer = g_malloc0 (offset + 1);
g_utf8_strncpy (buffer, uri, offset);
proto = buffer;
}
else
result = g_strdup (s);
gchar* path;
gchar* hostname = sokoke_hostname_from_uri (uri, &path);
gchar* encoded = sokoke_hostname_to_ascii (hostname);
if (encoded)
{
gchar* res = g_strconcat (proto ? proto : "", proto ? "://" : "",
encoded, path, NULL);
g_free (encoded);
return res;
}
g_free (hostname);
return g_strdup (uri);
}
static gchar*
sokoke_idn_to_punycode (gchar* uri)
{
#if HAVE_LIBIDN
gchar* result = sokoke_uri_to_ascii (uri);
g_free (uri);
free (s);
return result;
#else
return uri;
@ -294,6 +339,16 @@ gchar* sokoke_search_uri (const gchar* uri,
return search;
}
/**
* sokoke_magic_uri:
* @uri: a string typed by a user
* @search_engines: search engines
*
* Takes a string that was typed by a user,
* guesses what it is, and returns an URI.
*
* Return value: a newly allocated URI
**/
gchar*
sokoke_magic_uri (const gchar* uri,
KatzeArray* search_engines)
@ -319,8 +374,8 @@ sokoke_magic_uri (const gchar* uri,
if (g_strstr_len (uri, 8, "://"))
return sokoke_idn_to_punycode (g_strdup (uri));
/* Do we have a domain, ip address or localhost? */
if (g_ascii_isdigit (uri[0]))
/* Do we have an IP address? */
if (g_ascii_isdigit (uri[0]) && g_strstr_len (uri, 4, "."))
return g_strconcat ("http://", uri, NULL);
search = NULL;
if (!strchr (uri, ' ') &&
@ -358,6 +413,50 @@ sokoke_magic_uri (const gchar* uri,
return search;
}
/**
* sokoke_format_uri_for_display:
* @uri: an URI string
*
* Formats an URI for display, for instance by converting
* percent encoded characters and by decoding punycode.
*
* Return value: a newly allocated URI
**/
gchar*
sokoke_format_uri_for_display (const gchar* uri)
{
if (uri && g_str_has_prefix (uri, "http://"))
{
gchar* unescaped = g_uri_unescape_string (uri, NULL);
#ifdef HAVE_LIBSOUP_2_27_90
gchar* path;
gchar* hostname = sokoke_hostname_from_uri (unescaped, &path);
gchar* decoded = g_hostname_to_unicode (hostname);
if (decoded)
{
gchar* result = g_strconcat ("http://", decoded, path, NULL);
g_free (unescaped);
g_free (decoded);
g_free (hostname);
return result;
}
g_free (hostname);
return unescaped;
#elif HAVE_LIBIDN
gchar* decoded;
if (!idna_to_unicode_8z8z (unescaped, &decoded, 0) == IDNA_SUCCESS)
return unescaped;
g_free (unescaped);
return decoded;
#else
return unescaped;
#endif
}
return g_strdup (uri);
}
void
sokoke_combo_box_add_strings (GtkComboBox* combobox,
const gchar* label_first, ...)
@ -866,7 +965,6 @@ sokoke_register_stock_items (void)
{ STOCK_HISTORY, N_("_History"), 0, 0, GTK_STOCK_SORT_ASCENDING },
{ STOCK_HOMEPAGE, N_("_Homepage"), 0, 0, GTK_STOCK_HOME },
{ STOCK_SCRIPTS, N_("_Userscripts"), 0, 0, GTK_STOCK_EXECUTE },
{ STOCK_STYLES, N_("User_styles"), 0, 0, GTK_STOCK_SELECT_COLOR },
{ STOCK_TAB_NEW, N_("New _Tab"), 0, 0, GTK_STOCK_ADD },
{ STOCK_TRANSFERS, N_("_Transfers"), 0, 0, GTK_STOCK_SAVE },
{ STOCK_PLUGINS, N_("Netscape p_lugins"), 0, 0, GTK_STOCK_CONVERT },
@ -964,6 +1062,7 @@ sokoke_remove_path (const gchar* path,
/**
* sokoke_find_config_filename:
* @folder: a subfolder
* @filename: a filename or relative path
*
* Looks for the specified filename in the system config
@ -972,20 +1071,24 @@ sokoke_remove_path (const gchar* path,
* Return value: a full path
**/
gchar*
sokoke_find_config_filename (const gchar* filename)
sokoke_find_config_filename (const gchar* folder,
const gchar* filename)
{
const gchar* const* config_dirs = g_get_system_config_dirs ();
guint i = 0;
const gchar* config_dir;
if (!folder)
folder = "";
while ((config_dir = config_dirs[i++]))
{
gchar* path = g_build_filename (config_dir, PACKAGE_NAME, filename, NULL);
gchar* path = g_build_filename (config_dir, PACKAGE_NAME, folder, filename, NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return path;
g_free (path);
}
return g_build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, filename, NULL);
return g_build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder, filename, NULL);
}
/**

View file

@ -41,10 +41,20 @@ sokoke_spawn_program (const gchar* command,
gchar* sokoke_search_uri (const gchar* uri,
const gchar* keywords);
gchar*
sokoke_hostname_from_uri (const gchar* uri,
gchar** path);
gchar*
sokoke_uri_to_ascii (const gchar* uri);
gchar*
sokoke_magic_uri (const gchar* uri,
KatzeArray* search_engines);
gchar*
sokoke_format_uri_for_display (const gchar* uri);
typedef enum {
SOKOKE_MENU_POSITION_CURSOR = 0,
SOKOKE_MENU_POSITION_LEFT,
@ -152,7 +162,8 @@ sokoke_remove_path (const gchar* path,
gboolean ignore_errors);
gchar*
sokoke_find_config_filename (const gchar* filename);
sokoke_find_config_filename (const gchar* folder,
const gchar* filename);
gchar*
sokoke_find_data_filename (const gchar* filename);

20
module.xml Normal file
View file

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='UTF-8'?>
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:gnome="http://api.gnome.org/doap-extensions#"
xmlns="http://usefulinc.com/ns/doap#">
<name xml:lang="en">midori</name>
<shortdesc xml:lang="en">Midori is a lightweight web browser</shortdesc>
<homepage rdf:resource="http://www.twotoasts.de"/>
<mailing-list rdf:resource="http://foo-projects.org/mailman/listinfo/xfce"/>
<maintainer>
<foaf:Person>
<foaf:name>Christian Dywan</foaf:name>
<foaf:mbox>christian@twotoasts.de</foaf:mbox>
<gnome:userid>kalikiana</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View file

@ -29,7 +29,6 @@ struct _MidoriAddons
{
GtkVBox parent_instance;
MidoriAddonKind kind;
GtkWidget* web_widget;
GtkWidget* toolbar;
GtkWidget* treeview;
@ -137,23 +136,13 @@ midori_addons_class_init (MidoriAddonsClass* class)
static const gchar*
midori_addons_get_label (MidoriViewable* viewable)
{
if (MIDORI_ADDONS (viewable)->kind == MIDORI_ADDON_USER_SCRIPTS)
return _("Userscripts");
else if (MIDORI_ADDONS (viewable)->kind == MIDORI_ADDON_USER_STYLES)
return _("Userstyles");
else
return NULL;
}
static const gchar*
midori_addons_get_stock_id (MidoriViewable* viewable)
{
if (MIDORI_ADDONS (viewable)->kind == MIDORI_ADDON_USER_SCRIPTS)
return STOCK_SCRIPTS;
else if (MIDORI_ADDONS (viewable)->kind == MIDORI_ADDON_USER_STYLES)
return STOCK_STYLES;
else
return NULL;
}
static void
@ -175,7 +164,7 @@ midori_addons_set_property (GObject* object,
switch (prop_id)
{
case PROP_KIND:
addons->kind = g_value_get_enum (value);
/* Ignored */
break;
case PROP_WEB_WIDGET:
katze_object_assign (addons->web_widget, g_value_dup_object (value));
@ -197,7 +186,7 @@ midori_addons_get_property (GObject* object,
switch (prop_id)
{
case PROP_KIND:
g_value_set_enum (value, addons->kind);
g_value_set_enum (value, MIDORI_ADDON_USER_SCRIPTS);
break;
case PROP_WEB_WIDGET:
g_value_set_object (value, addons->web_widget);
@ -208,58 +197,32 @@ midori_addons_get_property (GObject* object,
}
}
static const gchar*
_addons_get_folder (MidoriAddons* addons)
{
switch (addons->kind)
{
case MIDORI_ADDON_USER_SCRIPTS:
return "scripts";
case MIDORI_ADDON_USER_STYLES:
return "styles";
default:
return NULL;
}
}
static const gchar*
_addons_get_extension (MidoriAddons* addons)
{
switch (addons->kind)
{
case MIDORI_ADDON_USER_SCRIPTS:
return ".js";
case MIDORI_ADDON_USER_STYLES:
return ".css";
default:
return NULL;
}
}
static GSList*
_addons_get_directories (MidoriAddons* addons)
{
const gchar* folders[] = { "scripts", "styles" };
GSList *directories;
guint i;
const char* const* datadirs;
const gchar* folder;
gchar* path;
folder = _addons_get_folder (addons);
directories = NULL;
/* user data dir */
for (i = 0; i < G_N_ELEMENTS (folders); i++)
{
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
PACKAGE_NAME, folder, NULL);
directories = g_slist_prepend (NULL, path);
PACKAGE_NAME, folders[i], NULL);
directories = g_slist_prepend (directories, path);
/* system data dirs */
datadirs = g_get_system_data_dirs ();
while (*datadirs)
{
path = g_build_path (G_DIR_SEPARATOR_S, *datadirs,
PACKAGE_NAME, folder, NULL);
PACKAGE_NAME, folders[i], NULL);
directories = g_slist_prepend (directories, path);
datadirs++;
}
}
return directories;
}
@ -269,8 +232,6 @@ _addons_get_files (MidoriAddons* addons)
{
GSList* files;
GDir* addon_dir;
const gchar* folder;
const gchar* extension;
GSList* list;
GSList* directories;
const gchar* filename;
@ -278,8 +239,6 @@ _addons_get_files (MidoriAddons* addons)
gchar* fullname;
files = NULL;
folder = _addons_get_folder (addons);
extension = _addons_get_extension (addons);
directories = _addons_get_directories (addons);
list = directories;
@ -290,7 +249,8 @@ _addons_get_files (MidoriAddons* addons)
{
while ((filename = g_dir_read_name (addon_dir)))
{
if (g_str_has_suffix (filename, extension))
if (g_str_has_suffix (filename, ".js")
|| g_str_has_suffix (filename, ".css"))
{
fullname = g_build_filename (dirname, filename, NULL);
files = g_slist_prepend (files, fullname);
@ -324,8 +284,10 @@ midori_addons_button_add_clicked_cb (GtkToolItem* toolitem,
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
"Put scripts in the folder ~/.local/share/midori/%s",
_addons_get_folder (addons));
_("Copy userscripts to the folder %s and "
"copy userstyles to the folder %s."),
"~/.local/share/midori/scripts",
"~/.local/share/midori/styles");
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
@ -819,7 +781,7 @@ midori_web_widget_context_ready_cb (GtkWidget* web_widget,
JSGlobalContextRef js_context,
MidoriAddons* addons)
{
const gchar* uri;
gchar* uri;
GSList* elements;
struct AddonElement* element;
gchar* fullname;
@ -850,7 +812,7 @@ midori_web_widget_context_ready_cb (GtkWidget* web_widget,
}
exception = NULL;
if (addons->kind == MIDORI_ADDON_USER_SCRIPTS &&
if (g_str_has_suffix (fullname, ".js") &&
!_js_script_from_file (js_context, fullname, &exception))
{
message = g_strdup_printf ("console.error ('%s');", exception);
@ -858,7 +820,7 @@ midori_web_widget_context_ready_cb (GtkWidget* web_widget,
g_free (message);
g_free (exception);
}
else if (addons->kind == MIDORI_ADDON_USER_STYLES &&
else if (g_str_has_suffix (fullname, ".css") &&
!_js_style_from_file (js_context, fullname, &exception))
{
message = g_strdup_printf ("console.error ('%s');", exception);
@ -869,6 +831,8 @@ midori_web_widget_context_ready_cb (GtkWidget* web_widget,
elements = g_slist_next (elements);
}
g_free (uri);
}
/**
@ -917,14 +881,15 @@ midori_addons_new (MidoriAddonKind kind,
monitor = g_file_monitor_directory (directory,
G_FILE_MONITOR_NONE,
NULL, &error);
if (!monitor)
{
g_warning ("could not monitor %s: %s", g_file_get_parse_name (directory),
error->message);
g_error_free (error);
}
if (monitor)
g_signal_connect (monitor, "changed",
G_CALLBACK (midori_addons_directory_monitor_changed), addons);
else
{
g_warning (_("Can't monitor folder '%s': %s"),
g_file_get_parse_name (directory), error->message);
g_error_free (error);
}
g_object_unref (directory);
}
g_slist_free (list);
@ -1011,7 +976,6 @@ midori_addons_update_elements (MidoriAddons* addons)
struct AddonElement* element;
g_return_if_fail (MIDORI_IS_ADDONS (addons));
g_return_if_fail (addons->kind != MIDORI_ADDON_NONE);
/* FIXME: would GHashTable be better? */
disabled = g_tree_new ((GCompareFunc)strcmp);
@ -1042,7 +1006,7 @@ midori_addons_update_elements (MidoriAddons* addons)
excludes = NULL;
broken = FALSE;
if (addons->kind == MIDORI_ADDON_USER_SCRIPTS)
if (g_str_has_suffix (fullname, ".js"))
{
name = NULL;
if (!js_metadata_from_file (fullname, &includes, &excludes,
@ -1055,7 +1019,7 @@ midori_addons_update_elements (MidoriAddons* addons)
displayname = name;
}
}
else if (addons->kind == MIDORI_ADDON_USER_STYLES)
else if (g_str_has_suffix (fullname, ".css"))
{
if (!css_metadata_from_file (fullname, &includes, &excludes))
broken = TRUE;

View file

@ -1,2 +1,2 @@
# set of available languages (in alphabetic order)
ast ca cs da de el en_GB es et fi fr gl he hu id it ja nl pl pt pt_BR ro ru sk sr sr@latin sv tr uk zh_CN zh_TW
ast ca cs da de el en_GB es et fi fr gl he hu id it ja ko nl pl pt pt_BR ro ru sk sr sr@latin sv tr uk zh_CN zh_TW

View file

@ -31,11 +31,13 @@ extensions/colorful-tabs.c
extensions/cookie-manager/cookie-manager.c
extensions/cookie-manager/cookie-manager-page.c
extensions/cookie-manager/main.c
extensions/dnsprefetch.c
extensions/feed-panel/feed-atom.c
extensions/feed-panel/feed-panel.c
extensions/feed-panel/feed-parse.c
extensions/feed-panel/feed-rss.c
extensions/feed-panel/main.c
extensions/formhistory.c
extensions/mouse-gestures/main.c
extensions/page-holder.c
extensions/shortcuts.c

148
po/ca.po
View file

@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: midori\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-07-29 23:58+0200\n"
"PO-Revision-Date: 2009-09-05 18:02+0100\n"
"PO-Revision-Date: 2009-09-13 19:12+0100\n"
"Last-Translator: Carles Muñoz Gorriz <carlesmu@internautas.org>\n"
"Language-Team: Catalan\n"
"MIME-Version: 1.0\n"
@ -34,9 +34,9 @@ msgid "Web Browser"
msgstr "Navegador web"
#: ../midori/main.c:96
#, fuzzy, c-format
#, c-format
msgid "The configuration couldn't be loaded: %s\n"
msgstr "No s'ha pogut carregar el fitxer."
msgstr "No s'ha pogut carregar la configuració: %s\n"
#: ../midori/main.c:151
#, c-format
@ -266,9 +266,9 @@ msgid "Stop loading the current page"
msgstr "Atura la càrrega d'aquesta pàgina"
#: ../midori/midori-browser.c:409
#, fuzzy, c-format
#, c-format
msgid "%d%% loaded"
msgstr "S'ha carregat"
msgstr "%d%% carregat"
#: ../midori/midori-browser.c:434
#, fuzzy, c-format
@ -925,9 +925,8 @@ msgid "New window"
msgstr "Nova finestra"
#: ../midori/midori-websettings.c:236
#, fuzzy
msgid "Current tab"
msgstr "/Estil de pestanya/E_stat actual"
msgstr "Pestanya actual"
#: ../midori/midori-websettings.c:251
msgid "Default"
@ -1059,9 +1058,8 @@ msgid "Whether to show the bookmarkbar"
msgstr "Si es mostra la barra d'adreces d'interès"
#: ../midori/midori-websettings.c:443
#, fuzzy
msgid "Show Panel"
msgstr "Mostra quadre"
msgstr "Mostra el quadre"
#: ../midori/midori-websettings.c:444
#, fuzzy
@ -1464,9 +1462,9 @@ msgid "The private data selected for deletion"
msgstr ""
#: ../midori/midori-view.c:781
#, fuzzy, c-format
#, c-format
msgid "The page '%s' couldn't be loaded."
msgstr "No s'ha pogut carregar el fitxer."
msgstr "No s'ha pogut carregar la pàgina «%s»."
#. WebKit 1.1.6 doesn't handle "alternate content" flawlessly,
#. so reloading via Javascript works but not via API calls.
@ -1476,66 +1474,56 @@ msgid "Error"
msgstr "Error"
#: ../midori/midori-view.c:786
#, fuzzy
msgid "Try again"
msgstr "Torneu a provar"
msgstr "Torneu-ho a provar"
#. i18n: The title of the 404 - Not found error page
#. Error pages are special, we want to try loading the destination
#. again, not the error page which isn't even a proper page
#: ../midori/midori-view.c:818 ../midori/midori-view.c:3017
#, fuzzy, c-format
#, c-format
msgid "Not found - %s"
msgstr "«%s» no trobat"
msgstr "No s'ha trobat «%s»"
#: ../midori/midori-view.c:1205
#, fuzzy
msgid "Open _Link"
msgstr "_Obre l'enllaç"
msgstr "Obre l'_enllaç"
#: ../midori/midori-view.c:1207
#, fuzzy
msgid "Open Link in New _Tab"
msgstr "Obre l'enllaç en una _pestanya nova"
msgstr "Obre l'enllaç en una nova _pestanya"
#: ../midori/midori-view.c:1224
#, fuzzy
msgid "Open Link in New _Window"
msgstr "Obre l'enllaç a una _nova finestra"
msgstr "Obre l'enllaç a una nova _finestra"
#: ../midori/midori-view.c:1230
#, fuzzy
msgid "_Download Link destination"
msgstr "%s és un enllaç sense destinació"
msgstr "_Descarrega el destí de l'enllaç"
#: ../midori/midori-view.c:1236
#, fuzzy
msgid "_Save Link destination"
msgstr "%s és un enllaç sense destinació"
msgstr "De_sa el destí de l'enllaç"
#: ../midori/midori-view.c:1245
#, fuzzy
msgid "Download with Download _Manager"
msgstr "Navega el sistema de fitxers amb el gestor de fitxers"
msgstr "Descarrega amb el _gestor de descàrregues"
#: ../midori/midori-view.c:1274
msgid "Search _with"
msgstr "Cerca _amb"
#: ../midori/midori-view.c:1306
#, fuzzy
msgid "_Search the Web"
msgstr "Cerca per Web"
msgstr "_Cerca la Web"
#: ../midori/midori-view.c:1316
#, fuzzy
msgid "Open Address in New _Tab"
msgstr "Obre l'enllaç en una _pestanya nova"
msgstr "Obre l'adreça en una nova _pestanya"
#: ../midori/midori-view.c:1494
#, fuzzy
msgid "Open or download file"
msgstr "Obre un fitxer existent o crea un nou fitxer."
msgstr "Obre o descarrega el fitxer"
#: ../midori/midori-view.c:1511
#, c-format
@ -1554,9 +1542,9 @@ msgid "Open %s"
msgstr "Obre %s"
#: ../midori/midori-view.c:1957
#, fuzzy, c-format
#, c-format
msgid "Inspect page - %s"
msgstr " Pàgina de manual "
msgstr "Inspecciona la pàgina «%s»"
#: ../midori/midori-view.c:2147
#, fuzzy
@ -1594,34 +1582,29 @@ msgid "No documentation installed"
msgstr "No s'han pogut trobar plantilles"
#: ../midori/midori-view.c:2323
#, fuzzy
msgid "Blank page"
msgstr " Pàgina de manual "
msgstr "Pàgina en blanc"
#: ../midori/midori-view.c:2551 ../midori/sokoke.c:865
#, fuzzy
msgid "New _Tab"
msgstr "Nova pes_tanya"
msgstr "Nova _pestanya"
#: ../midori/midori-view.c:2565
#, fuzzy
msgid "_Duplicate Tab"
msgstr "el separador és buit"
msgstr "_Duplica la pestanya"
#: ../midori/midori-view.c:2570
#, fuzzy
msgid "_Restore Tab"
msgstr "el separador és buit"
msgstr "_Restaura la pestanya"
#: ../midori/midori-view.c:2570
#, fuzzy
msgid "_Minimize Tab"
msgstr "el separador és buit"
msgstr "_Minimitza la pestanya"
#: ../midori/midori-preferences.c:91
#, fuzzy, c-format
#, c-format
msgid "Preferences for %s"
msgstr "Preferències de l'Orca per a %s"
msgstr "Preferències per a %s"
#. Page "General"
#: ../midori/midori-preferences.c:398
@ -1646,29 +1629,24 @@ msgid "Appearance"
msgstr "Aparença"
#: ../midori/midori-preferences.c:441
#, fuzzy
msgid "Font settings"
msgstr "Altres paràmetres de lletra"
msgstr "Paràmetres del tipus de lletra"
#: ../midori/midori-preferences.c:443
#, fuzzy
msgid "Default Font Family"
msgstr "Joc de família de tipus de lletra"
msgstr "Família de tipus de lletra per defecte"
#: ../midori/midori-preferences.c:447
#, fuzzy
msgid "The default font family used to display text"
msgstr "Font utilitzada per visualitzar el text a la sortida xosd"
msgstr "La família de tipus de lletra per defecte emprada per mostrar el text"
#: ../midori/midori-preferences.c:450
#, fuzzy
msgid "The default font size used to display text"
msgstr "Font utilitzada per visualitzar el text a la sortida xosd"
msgstr "La mida del tipus de lletra per defecte emprada per mostrar el text"
#: ../midori/midori-preferences.c:453
#, fuzzy
msgid "Fixed-width Font Family"
msgstr "Tipus de lletra per al text de mida fixa"
msgstr "Família de tipus de lletra d'amplada fixa"
#: ../midori/midori-preferences.c:457
msgid "The font family used to display fixed-width text"
@ -1679,23 +1657,20 @@ msgid "The font size used to display fixed-width text"
msgstr ""
#: ../midori/midori-preferences.c:463
#, fuzzy
msgid "Minimum Font Size"
msgstr "Joc de mida de tipus de lletra"
msgstr "Mida mínima del tipus de lletra"
#: ../midori/midori-preferences.c:466
#, fuzzy
msgid "The minimum font size used to display text"
msgstr "Font utilitzada per visualitzar el text a la sortida xosd"
msgstr "La mida mínima del tipus de lletra emprada per mostrar text"
#: ../midori/midori-preferences.c:473
msgid "Encoding"
msgstr "Codificació"
#: ../midori/midori-preferences.c:476
#, fuzzy
msgid "The character encoding to use by default"
msgstr "Nom del rerefons del GtkFileChooser predeterminat"
msgstr "La codificació de caràcters per defecte"
#. Page "Behavior"
#: ../midori/midori-preferences.c:483
@ -1707,33 +1682,28 @@ msgid "Features"
msgstr "Característiques"
#: ../midori/midori-preferences.c:487 ../extensions/statusbar-features.c:88
#, fuzzy
msgid "Load images automatically"
msgstr "Carrega automàticament el darrer projecte"
msgstr "Carrega les imatges automàticament"
#: ../midori/midori-preferences.c:488
#, fuzzy
msgid "Load and display images automatically"
msgstr "Nom de fitxer per carregar i visualitzar"
msgstr "Carrega i mostra les imatges automàticament"
#: ../midori/midori-preferences.c:491
#, fuzzy
msgid "Shrink images automatically"
msgstr "Esborra les imatges automàticament després de gravar"
msgstr "Encongeix les imatges automàticament"
#: ../midori/midori-preferences.c:492
msgid "Automatically shrink standalone images to fit"
msgstr ""
#: ../midori/midori-preferences.c:495
#, fuzzy
msgid "Print background images"
msgstr "/Afegeix pestanya/_Imatges"
msgstr "Imprimeix les imatges de fons"
#: ../midori/midori-preferences.c:496
#, fuzzy
msgid "Whether background images should be printed"
msgstr "Si s'han de mostrar imatges en els menús."
msgstr "Si s'han d'imprimir les imatges de fons"
#: ../midori/midori-preferences.c:499
#, fuzzy
@ -1779,14 +1749,12 @@ msgid "Enable special extensions for developers"
msgstr ""
#: ../midori/midori-preferences.c:523
#, fuzzy
msgid "Spell Checking"
msgstr "Comprovació de l'ortografia"
msgstr "Corrector ortogràfic"
#: ../midori/midori-preferences.c:526
#, fuzzy
msgid "Enable Spell Checking"
msgstr "La revisió d'ortografia ha fallat: %s"
msgstr "Habilita el corrector ortogràfic"
#: ../midori/midori-preferences.c:527
msgid "Enable spell checking while typing"
@ -1848,14 +1816,12 @@ msgid "Empty"
msgstr "Buit"
#: ../midori/midori-searchaction.c:908
#, fuzzy
msgid "Add search engine"
msgstr "Cercador de Gadu-Gadu"
msgstr "Afegeix giny de cerca"
#: ../midori/midori-searchaction.c:908
#, fuzzy
msgid "Edit search engine"
msgstr "Cercador de Gadu-Gadu"
msgstr "Edita giny de cerca"
#: ../midori/midori-searchaction.c:936
msgid "_Name:"
@ -1870,14 +1836,12 @@ msgid "_Token:"
msgstr "_Testimoni:"
#: ../midori/midori-searchaction.c:1213
#, fuzzy
msgid "Manage Search Engines"
msgstr "Repeteix l'última recerca"
msgstr "Gestiona els ginys de cerca"
#: ../midori/midori-searchaction.c:1312
#, fuzzy
msgid "Use as _default"
msgstr "usa la clau predeterminada com a destinatari predeterminat"
msgstr "Empra'l per _defecte"
#: ../midori/sokoke.c:162 ../midori/sokoke.c:174
#, fuzzy
@ -1913,9 +1877,8 @@ msgid "_Userscripts"
msgstr "Scripts d'_usuari"
#: ../midori/sokoke.c:864
#, fuzzy
msgid "User_styles"
msgstr "Múltiples estils"
msgstr "E_stils personals"
#: ../midori/sokoke.c:866
msgid "_Transfers"
@ -1931,7 +1894,7 @@ msgstr "Scripts d'usuari"
#: ../panels/midori-addons.c:96 ../panels/midori-addons.c:143
msgid "Userstyles"
msgstr ""
msgstr "Estils d'usuari"
#: ../panels/midori-bookmarks.c:108
msgid "Bookmarks"
@ -2000,7 +1963,6 @@ msgid "Yesterday"
msgstr "Ahir"
#: ../panels/midori-plugins.c:87 ../extensions/statusbar-features.c:108
#, fuzzy
msgid "Netscape plugins"
msgstr "Connectors de Netscape"
@ -2039,14 +2001,14 @@ msgid "Password"
msgstr "Contrasenya"
#: ../katze/katze-throbber.c:828
#, fuzzy, c-format
#, c-format
msgid "Named icon '%s' couldn't be loaded"
msgstr "No s'ha pogut carregar els següents fitxers:"
msgstr ""
#: ../katze/katze-throbber.c:841
#, fuzzy, c-format
#, c-format
msgid "Stock icon '%s' couldn't be loaded"
msgstr "No s'ha pogut carregar els següents fitxers:"
msgstr ""
#: ../katze/katze-throbber.c:907
#, fuzzy

1139
po/de.po

File diff suppressed because it is too large Load diff

1163
po/el.po

File diff suppressed because it is too large Load diff

2562
po/id.po

File diff suppressed because it is too large Load diff

1215
po/ja.po

File diff suppressed because it is too large Load diff

2197
po/ko.po Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: Midori 0.1.9-3345559\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-07-29 23:58+0200\n"
"PO-Revision-Date: 2009-09-07 22:06+0200\n"
"PO-Revision-Date: 2009-10-12 16:32+0200\n"
"Last-Translator: Robert Hartl <hartl.robert@gmail.com>\n"
"Language-Team: slovak <sk-i18n@lists.linux.sk>\n"
"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2;;\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
#: ../data/midori.desktop.in.h:1
msgid "Lightweight web browser"
@ -111,7 +111,7 @@ msgstr ""
#: ../midori/main.c:1116
msgid "Modify _preferences"
msgstr "Zmeniť _nastavenia"
msgstr "Zmeniť _predvoľby"
#: ../midori/main.c:1120
msgid "Reset the last _session"
@ -523,7 +523,7 @@ msgstr "Prepnúť zobrazenie na celú obrazovku"
#: ../midori/midori-browser.c:4257
msgid "_Go"
msgstr "sť"
msgstr "P_rejsť"
#: ../midori/midori-browser.c:4260
msgid "Go back to the previous page"
@ -956,7 +956,7 @@ msgstr "Posledná stránka panelu"
#: ../midori/midori-websettings.c:398
msgid "The last saved panel page"
msgstr ""
msgstr "Posledná uložená stránka panala"
#: ../midori/midori-websettings.c:406
msgid "Last Web search"
@ -1101,7 +1101,7 @@ msgstr "Zobraziť rýchly prístup na nových kartách"
#: ../midori/midori-websettings.c:615
msgid "Show speed dial in newly opened tabs"
msgstr ""
msgstr "Zobrazí rýchly prístup v novo otvorených kartách"
#: ../midori/midori-websettings.c:623
msgid "Save downloaded files to:"
@ -1490,7 +1490,7 @@ msgstr "_Minimalizovať kartu"
#: ../midori/midori-preferences.c:91
#, c-format
msgid "Preferences for %s"
msgstr "Nastavenia pre %s"
msgstr "Predvoľby pre %s"
#. Page "General"
#: ../midori/midori-preferences.c:398
@ -1920,11 +1920,11 @@ msgstr "Blokovač reklamy"
#: ../extensions/adblock.c:563
msgid "Block advertisements according to a filter list"
msgstr ""
msgstr "Blokovať reklamy podľa zoznamu filtorv"
#: ../extensions/colorful-tabs.c:115
msgid "Tint tabs distinctly"
msgstr "Ofarbiť kartdy"
msgstr "Ofarbiť karty"
#: ../extensions/colorful-tabs.c:151
msgid "Colorful Tabs"
@ -1963,11 +1963,11 @@ msgstr "Otázka"
#: ../extensions/cookie-manager/cookie-manager-page.c:471
msgid "Only cookies which match the filter will be deleted."
msgstr ""
msgstr "Iba cookies, ktoré zodpovedajú filtru budú zmazané"
#: ../extensions/cookie-manager/cookie-manager-page.c:539
msgid "At the end of the session"
msgstr ""
msgstr "Na konci sedenia"
#: ../extensions/cookie-manager/cookie-manager-page.c:542
#, c-format

View file

@ -18,6 +18,20 @@
#define SM "http://www.searchmash.com/search/"
static void
sokoke_assert_str_equal (const gchar* input,
const gchar* result,
const gchar* expected)
{
if (g_strcmp0 (result, expected))
{
g_error ("Input: %s\nExpected: %s\nResult: %s",
input ? input : "NULL",
expected ? expected : "NULL",
result ? result : "NULL");
}
}
static void
test_input (const gchar* input,
const gchar* expected)
@ -41,13 +55,7 @@ test_input (const gchar* input,
}
gchar* uri = sokoke_magic_uri (input, search_engines);
if (g_strcmp0 (uri, expected))
{
g_error ("Input: %s\nExpected: %s\nResult: %s",
input ? input : "NULL",
expected ? expected : "NULL",
uri ? uri : "NULL");
}
sokoke_assert_str_equal (input, uri, expected);
g_free (uri);
}
@ -78,27 +86,46 @@ magic_uri_uri (void)
static void
magic_uri_idn (void)
{
#if HAVE_LIBIDN
test_input ("http://www.münchhausen.at", "http://www.xn--mnchhausen-9db.at");
test_input ("http://www.خداوند.com/", "http://www.xn--mgbndb8il.com/");
test_input ("айкидо.com", "http://xn--80aildf0a.com");
test_input ("http://東京理科大学.jp", "http://xn--1lq68wkwbj6ugkpigi.jp");
test_input ("https://青のネコ", "https://xn--u9jthzcs263c");
typedef struct
{
const gchar* before;
const gchar* after;
} URIItem;
static const URIItem items[] = {
#if HAVE_LIBIDN || defined (HAVE_LIBSOUP_2_27_90)
{ "http://www.münchhausen.at", "http://www.xn--mnchhausen-9db.at" },
{ "http://www.خداوند.com/", "http://www.xn--mgbndb8il.com/" },
{ "айкидо.com", "xn--80aildf0a.com" },
{ "http://東京理科大学.jp", "http://xn--1lq68wkwbj6ugkpigi.jp" },
{ "https://青のネコ", "https://xn--u9jthzcs263c" },
#else
test_input ("http://www.münchhausen.at", "http://www.münchhausen.at");
test_input ("http://www.خداوند.com/", "http://www.خداوند.com/");
test_input ("айкидо.com", "http://айкидо.com");
test_input ("http://東京理科大学.jp", "http://東京理科大学.jp");
test_input ("https://青のネコ.co.jp", "https://青のネコ.co.jp");
{ "http://www.münchhausen.at", NULL },
{ "http://www.خداوند.com/", NULL },
{ "айкидо.com", NULL },
{ "http://東京理科大学.jp", NULL },
{ "https://青のネコ.co.jp", NULL },
#endif
{ "http://en.wikipedia.org/wiki/Kölsch_language", NULL },
{ "file:///home/mark/frühstück", NULL },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (items); i++)
{
gchar* result = sokoke_uri_to_ascii (items[i].before);
const gchar* after = items[i].after ? items[i].after : items[i].before;
sokoke_assert_str_equal (items[i].before, result, after);
g_free (result);
}
#if HAVE_LIBIDN
test_input ("айкидо.com", "http://xn--80aildf0a.com");
#else
test_input ("айкидо.com", "http://айкидо.com");
#endif
test_input ("http://en.wikipedia.org/wiki/Kölsch_language",
"http://en.wikipedia.org/wiki/Kölsch_language");
test_input ("en.wikipedia.org/wiki/Kölsch_language",
"http://en.wikipedia.org/wiki/Kölsch_language");
test_input ("sm Küchenzubehör", SM "Küchenzubehör");
test_input ("sm 東京理科大学", SM "東京理科大学");
test_input ("file:///home/mark/frühstück",
"file:///home/mark/frühstück");
}
static void
@ -114,6 +141,8 @@ magic_uri_search (void)
test_input ("gtk2.0", NULL);
test_input ("pcre++", NULL);
test_input ("sm pcre++", SM "pcre%2B%2B");
test_input ("5580", NULL);
test_input ("sm 5580", SM "5580");
test_input ("midori0.1.0", NULL);
test_input ("midori 0.1.0", NULL);
test_input ("search:cats", NULL);
@ -165,6 +194,35 @@ magic_uri_performance (void)
g_print ("\nTime needed for URI tests: %f ", g_test_timer_elapsed ());
}
static void
magic_uri_format (void)
{
typedef struct
{
const gchar* before;
const gchar* after;
} URIItem;
static const URIItem items[] = {
{ "http://www.csszengarden.com", NULL },
{ "http://live.gnome.org/GTK+/3.0/Tasks", NULL },
{ "http://www.johannkönig.com/index.php?ausw=home", NULL },
{ "http://digilife.bz/wiki/index.php?Python%E3%81%AE%E9%96%8B%E7%99%BA%E6%89%8B%E9%A0%86",
"http://digilife.bz/wiki/index.php?Pythonの開発手順" },
{ "http://die-welt.net/~evgeni/LenovoBatteryLinux/", NULL },
{ "http://wiki.c3sl.ufpr.br/multiseat/index.php/Xephyr_Solution", NULL },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (items); i++)
{
gchar* result = sokoke_format_uri_for_display (items[i].before);
const gchar* after = items[i].after ? items[i].after : items[i].before;
sokoke_assert_str_equal (items[i].before, result, after);
g_free (result);
}
}
int
main (int argc,
char** argv)
@ -177,6 +235,7 @@ main (int argc,
g_test_add_func ("/magic-uri/search", magic_uri_search);
g_test_add_func ("/magic-uri/pseudo", magic_uri_pseudo);
g_test_add_func ("/magic-uri/performance", magic_uri_performance);
g_test_add_func ("/magic-uri/format", magic_uri_format);
return g_test_run ();
}

49
wscript
View file

@ -24,8 +24,8 @@ from TaskGen import extension
import misc
major = 0
minor = 1
micro = 10
minor = 2
micro = 0
APPNAME = 'midori'
VERSION = str (major) + '.' + str (minor) + '.' + str (micro)
@ -181,15 +181,6 @@ def configure (conf):
unique = 'no '
conf.define ('HAVE_UNIQUE', [0,1][unique == 'yes'])
if option_enabled ('libidn'):
check_pkg ('libidn', '1.0', False)
libidn = ['N/A','yes'][conf.env['HAVE_LIBIDN'] == 1]
if libidn != 'yes':
option_checkfatal ('libidn', 'international domain names')
else:
libidn = 'no '
conf.define ('HAVE_LIBIDN', [0,1][libidn == 'yes'])
if option_enabled ('sqlite'):
check_pkg ('sqlite3', '3.0', False, var='SQLITE')
sqlite = ['N/A','yes'][conf.env['HAVE_SQLITE'] == 1]
@ -210,9 +201,22 @@ def configure (conf):
check_pkg ('webkit-1.0', '1.1.1', args=args)
check_pkg ('libsoup-2.4', '2.25.2')
conf.define ('HAVE_LIBSOUP_2_25_2', 1)
check_pkg ('libsoup-2.4', '2.27.91', False, var='LIBSOUP_2_27_91')
check_pkg ('libsoup-2.4', '2.27.90', False, var='LIBSOUP_2_27_90')
check_pkg ('libxml-2.0', '2.6')
if conf.env['HAVE_LIBSOUP_2_27_90']:
idn = 'yes'
conf.define ('HAVE_LIBIDN', 0)
else:
if option_enabled ('libidn'):
check_pkg ('libidn', '1.0', False)
idn = ['N/A','yes'][conf.env['HAVE_LIBIDN'] == 1]
if idn != 'yes':
option_checkfatal ('libidn', 'international domain names')
else:
idn = 'no '
conf.define ('HAVE_LIBIDN', [0,1][idn == 'yes'])
if option_enabled ('hildon'):
if check_pkg ('hildon-1', mandatory=False, var='HILDON'):
check_pkg ('libosso', var='HILDON')
@ -267,16 +271,15 @@ def configure (conf):
elif debug_level == 'full':
# -Wdeclaration-after-statement
# -Wmissing-declarations -Wmissing-prototypes
# -Wwrite-strings
# -Wwrite-strings -Wunsafe-loop-optimizations -Wmissing-include-dirs
conf.env.append_value ('CCFLAGS',
'-Wall -Wextra -O1 -g '
'-Waggregate-return -Wno-unused-parameter '
'-Wno-missing-field-initializers '
'-Wunsafe-loop-optimizations '
'-Wredundant-decls -Wmissing-noreturn '
'-Wshadow -Wpointer-arith -Wcast-align '
'-Winline -Wformat-security '
'-Winit-self -Wmissing-include-dirs -Wundef '
'-Winit-self -Wundef '
'-Wmissing-format-attribute -Wnested-externs '
'-DG_ENABLE_DEBUG'.split ())
elif debug_level != 'none':
@ -288,7 +291,7 @@ def configure (conf):
Icon optimizations: %(icons)s (rsvg-convert)
Persistent history: %(sqlite)s (sqlite3)
IDN support: %(libidn)s (libidn)
IDN support: %(idn)s (libidn or libsoup 2.27.90)
User documentation: %(user_docs)s (docutils)
API documentation: %(api_docs)s (gtk-doc)
''' % locals ()
@ -450,6 +453,18 @@ def build (bld):
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/speeddial-head.html')
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/speeddial.json')
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/mootools.js')
bld.install_files ('${MDATADIR}/' + APPNAME, 'data/autosuggestcontrol.js')
bld.install_files ('${MDATADIR}/' + APPNAME, 'data/autosuggestcontrol.css')
# FIXME: Determine the library naming for other platforms
if Options.platform == 'linux':
extensions = os.listdir ('data/extensions')
for extension in extensions:
folder = 'lib' + extension + '.so'
source = 'data/extensions/' + extension + '/config'
if os.path.exists (source):
bld.install_files ('${SYSCONFDIR}/' + APPNAME + \
'/extensions/' + folder, source)
if Options.commands['check']:
bld.add_subdirs ('tests')
@ -511,7 +526,7 @@ def shutdown ():
pass
try:
ext = 'MIDORI_EXTENSION_PATH=' + relfolder + os.sep + 'extensions'
nls = 'NLSPATH=' + relfolder + os.sep + 'po'
nls = 'MIDORI_NLSPATH=' + relfolder + os.sep + 'po'
lang = os.environ['LANG']
try:
for lang in os.listdir (folder + os.sep + 'po'):