gboolean enforce_font_family;
gboolean flash_window_on_bg_tabs;
gchar* user_stylesheet_uri;
+ gchar* user_stylesheet_uri_cached;
GHashTable* user_stylesheets;
};
web_settings->http_proxy = NULL;
web_settings->open_popups_in_tabs = TRUE;
web_settings->kinetic_scrolling = TRUE;
- web_settings->user_stylesheet_uri = NULL;
+ web_settings->user_stylesheet_uri = web_settings->user_stylesheet_uri_cached = NULL;
web_settings->user_stylesheets = NULL;
g_signal_connect (web_settings, "notify::default-encoding",
katze_assign (web_settings->http_proxy, NULL);
katze_assign (web_settings->ident_string, NULL);
katze_assign (web_settings->user_stylesheet_uri, NULL);
+ katze_assign (web_settings->user_stylesheet_uri_cached, NULL);
if (web_settings->user_stylesheets != NULL)
g_hash_table_destroy (web_settings->user_stylesheets);
}
}
+static void
+midori_web_settings_process_stylesheets (MidoriWebSettings* settings,
+ gint delta_len);
+
+static void
+base64_space_pad (gchar* base64,
+ guint len);
+
static void
midori_web_settings_set_property (GObject* object,
guint prop_id,
web_settings->flash_window_on_bg_tabs = g_value_get_boolean (value);
break;
case PROP_USER_STYLESHEET_URI:
- if ((web_settings->user_stylesheet_uri = g_value_dup_string (value)))
{
- gchar* css = g_strdup_printf ("@import url(\"%s\"\n);",
- web_settings->user_stylesheet_uri);
- midori_web_settings_add_style (web_settings, "user-stylesheet-uri", css);
- g_free (css);
+ gint old_len = web_settings->user_stylesheet_uri_cached
+ ? strlen (web_settings->user_stylesheet_uri_cached) : 0;
+ gint new_len = 0;
+ if ((web_settings->user_stylesheet_uri = g_value_dup_string (value)))
+ {
+ gchar* import = g_strdup_printf ("@import url(\"%s\");",
+ web_settings->user_stylesheet_uri);
+ gchar* encoded = g_base64_encode ((const guchar*)import, strlen (import));
+ new_len = strlen (encoded);
+ base64_space_pad (encoded, new_len);
+ g_free (import);
+ katze_assign (web_settings->user_stylesheet_uri_cached, encoded);
+ }
+ /* Make original user-stylesheet-uri available to main.c */
+ g_object_set_data (G_OBJECT (web_settings), "user-stylesheet-uri",
+ web_settings->user_stylesheet_uri);
+ midori_web_settings_process_stylesheets (web_settings, new_len - old_len);
}
- else
- midori_web_settings_remove_style (web_settings, "user-stylesheet-uri");
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_value_set_boolean (value, web_settings->flash_window_on_bg_tabs);
break;
case PROP_USER_STYLESHEET_URI:
- g_value_set_string (value, web_settings->user_stylesheet_uri);
+ g_value_take_string (value, katze_object_get_string (web_settings,
+ "WebKitWebSettings::user-stylesheet-uri"));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
-midori_web_settings_process_stylesheets (MidoriWebSettings* settings)
+midori_web_settings_process_stylesheets (MidoriWebSettings* settings,
+ gint delta_len)
{
GHashTableIter it;
- GString* css = g_string_new ("");
- gchar* base64;
+ GString* css;
gchar* encoded;
- gpointer key;
gpointer value;
+ static guint length = 0;
- g_hash_table_iter_init (&it, settings->user_stylesheets);
- while (g_hash_table_iter_next (&it, &key, &value))
- g_string_append_printf (css, "%s\n", (const gchar*) value);
+ g_return_if_fail ((gint)length >= -delta_len);
- /* data: uri prefix from Source/WebCore/page/Page.cpp:700 in WebKit */
- encoded = g_base64_encode ((guchar*)css->str, css->len);
- base64 = g_strdup_printf ("data:text/css;charset=utf-8;base64,%s", encoded);
- g_object_set (settings, "WebKitWebSettings::user-stylesheet-uri", base64, NULL);
+ length += delta_len;
+
+ /* Precalculate size to avoid re-allocations */
+ css = g_string_sized_new (length);
+
+ if (settings->user_stylesheet_uri_cached != NULL)
+ g_string_append (css, settings->user_stylesheet_uri_cached);
+
+ if (settings->user_stylesheets != NULL)
+ {
+ g_hash_table_iter_init (&it, settings->user_stylesheets);
+ while (g_hash_table_iter_next (&it, NULL, &value))
+ g_string_append (css, (gchar*)value);
+ }
+ /* data: uri prefix from Source/WebCore/page/Page.cpp:700 in WebKit */
+ encoded = g_strconcat ("data:text/css;charset=utf-8;base64,", css->str, NULL);
+ g_object_set (G_OBJECT (settings), "WebKitWebSettings::user-stylesheet-uri", encoded, NULL);
g_free (encoded);
- g_free (base64);
g_string_free (css, TRUE);
}
+static void
+base64_space_pad (gchar* base64,
+ guint len)
+{
+ /* Replace '=' padding at the end with encoded spaces
+ so WebKit will accept concatenations to this string */
+ if (len > 2 && base64[len - 2] == '=')
+ {
+ base64[len - 3] += 2;
+ base64[len - 2] = 'A';
+ }
+ if (len > 1 && base64[len - 1] == '=')
+ base64[len - 1] = 'g';
+}
+
/**
* midori_web_settings_add_style:
* @rule_id: a static string identifier
const gchar* rule_id,
const gchar* style)
{
+ gchar* base64;
+ guint len;
+
g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
g_return_if_fail (rule_id != NULL);
g_return_if_fail (style != NULL);
+ len = strlen (style);
+ base64 = g_base64_encode ((const guchar*)style, len);
+ len = ((len + 2) / 3) * 4;
+ base64_space_pad (base64, len);
+
if (settings->user_stylesheets == NULL)
settings->user_stylesheets = g_hash_table_new_full (g_str_hash, NULL,
- NULL, g_free);
- g_hash_table_insert (settings->user_stylesheets, (gchar*)rule_id, g_strdup (style));
- midori_web_settings_process_stylesheets (settings);
+ NULL, g_free);
+
+ g_hash_table_insert (settings->user_stylesheets, (gchar*)rule_id, base64);
+ midori_web_settings_process_stylesheets (settings, len);
}
/**
midori_web_settings_remove_style (MidoriWebSettings* settings,
const gchar* rule_id)
{
+ gchar* str;
+
g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
g_return_if_fail (rule_id != NULL);
if (settings->user_stylesheets != NULL)
{
- g_hash_table_remove (settings->user_stylesheets, rule_id);
- midori_web_settings_process_stylesheets (settings);
+ if ((str = g_hash_table_lookup (settings->user_stylesheets, rule_id)))
+ {
+ guint len = strlen (str);
+ g_hash_table_remove (settings->user_stylesheets, rule_id);
+ midori_web_settings_process_stylesheets (settings, -len);
+ }
}
}
-