diff --git a/src/client/views/conversation-viewer.vala b/src/client/views/conversation-viewer.vala index 0b0041fa..b3a1be04 100644 --- a/src/client/views/conversation-viewer.vala +++ b/src/client/views/conversation-viewer.vala @@ -645,15 +645,18 @@ public class ConversationViewer : Gtk.Box { private void show_images_email(WebKit.DOM.Element email_element) { // TODO: Remember that these images have been shown. try { - WebKit.DOM.NodeList nodes = email_element.query_selector_all("img"); + WebKit.DOM.Element? body = email_element.query_selector(".body"); + if (body == null) + return; + + WebKit.DOM.NodeList nodes = body.query_selector_all("img"); for (ulong i = 0; i < nodes.length; i++) { WebKit.DOM.Element? element = nodes.item(i) as WebKit.DOM.Element; if (element == null || !element.has_attribute("src")) continue; string src = element.get_attribute("src"); - if (src.has_prefix("remote:")) - element.set_attribute("src", src.substring(7)); + element.set_attribute("src", web_view.allow_prefix + src); } WebKit.DOM.Element? remote_images = email_element.query_selector(".remote_images"); @@ -957,7 +960,6 @@ public class ConversationViewer : Gtk.Box { // Then set the source to a data url. web_view.set_data_url(img, mimetype, image_data); } else if (!src.has_prefix("data:")) { // TODO: Test whether to show images - img.set_attribute("src", "remote:" + src); remote_images = true; } } diff --git a/src/client/views/conversation-web-view.vala b/src/client/views/conversation-web-view.vala index 50b0c7f1..2aeda9ff 100644 --- a/src/client/views/conversation-web-view.vala +++ b/src/client/views/conversation-web-view.vala @@ -5,11 +5,18 @@ */ public class ConversationWebView : WebKit.WebView { + private const string[] always_loaded_prefixes = { + "http://www.gravatar.com/avatar/", + "data:" + }; + private const string USER_CSS = "user-message.css"; private const string STYLE_NAME = "STYLE"; // HTML element that contains message DIVs. public WebKit.DOM.HTMLDivElement? container { get; private set; default = null; } + + public string allow_prefix { get; private set; default = ""; } private FileMonitor? user_style_monitor = null; @@ -18,6 +25,7 @@ public class ConversationWebView : WebKit.WebView { public ConversationWebView() { // Set defaults. set_border_width(0); + allow_prefix = random_string(10) + ":"; WebKit.WebSettings config = new WebKit.WebSettings(); config.enable_scripts = false; @@ -39,6 +47,15 @@ public class ConversationWebView : WebKit.WebView { load_string(html_text, "text/html", "UTF8", ""); } + private string random_string(int length) { + // No upper case letters, since request gets lower-cased. + string chars = "abcdefghijklmnopqrstuvwxyz"; + char[] random = new char[length]; + for (int i = 0; i < length; i++) + random[i] = chars[Random.int_range(0, chars.length)]; + return (string) random; + } + public override bool query_tooltip(int x, int y, bool keyboard_tooltip, Gtk.Tooltip tooltip) { // Disable tooltips from within WebKit itself. return false; @@ -79,8 +96,24 @@ public class ConversationWebView : WebKit.WebView { } string? uri = request.get_uri(); - if (uri.has_prefix("remote:")) - request.set_uri("about:blank"); + if (!is_always_loaded(uri)) { + if (uri.has_prefix(allow_prefix)) + request.set_uri(uri.substring(allow_prefix.length)); + else + request.set_uri("about:blank"); + } + } + + private bool is_always_loaded(string? uri) { + if (uri == null) + return true; + + foreach (string prefix in always_loaded_prefixes) { + if (uri.has_prefix(prefix)) + return true; + } + + return false; } private void on_load_finished(WebKit.WebFrame frame) {