Load external images based on scheme, not extension: Closes #6099
Squashed commit of the following:
commit 2e7b026f5865d84f369288a70d86c44e07e8c3b1
Merge: 08c6691 c476669
Author: Jim Nelson <jim@yorba.org>
Date: Wed Jan 16 15:24:35 2013 -0800
Merge branch 'master' into bug/6099-view-images
commit 08c6691c5c466448710a5b055676778348650b86
Author: Jim Nelson <jim@yorba.org>
Date: Wed Jan 16 15:06:00 2013 -0800
Updates in response to Eric's code review
commit 9694e0a4d678b3b0674e9970b8f3b840937955f3
Author: Jim Nelson <jim@yorba.org>
Date: Wed Jan 16 14:17:12 2013 -0800
Merge of Andrea Corbellini's patch for #6099
The merge had to be done by hand because of a recent refactoring of
the ConversationViewer and ConversationWebView.
This commit is contained in:
parent
c476669ff5
commit
1b6cad11d6
4 changed files with 64 additions and 43 deletions
1
THANKS
1
THANKS
|
|
@ -2,6 +2,7 @@ The Geary team would like to thank the following contributors:
|
|||
|
||||
Robert Ancell <robert.ancell@canonical.com>
|
||||
Jürg Billeter <j@bitron.ch>
|
||||
Andrea Corbellini <corbellini.andrea@gmail.com>
|
||||
Sergey Shnatsel Davidoff <sergey@elementaryos.org>
|
||||
Joanmarie Diggs <jdiggs@igalia.com>
|
||||
Christian Dywan <christian@twotoasts.de>
|
||||
|
|
|
|||
|
|
@ -192,19 +192,6 @@ public WebKit.DOM.HTMLElement? closest_ancestor(WebKit.DOM.Element element, stri
|
|||
}
|
||||
}
|
||||
|
||||
public bool is_image(string? uri) {
|
||||
if (uri == null)
|
||||
return false;
|
||||
|
||||
try {
|
||||
Regex regex = new Regex("(?:jpe?g|gif|png)$", RegexCompileFlags.CASELESS);
|
||||
return regex.match(uri);
|
||||
} catch (RegexError err) {
|
||||
debug("Error creating image-matching regex: %s", err.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string decorate_quotes(string text) throws Error {
|
||||
int level = 0;
|
||||
string outtext = "";
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public class ConversationViewer : Gtk.Box {
|
|||
}
|
||||
|
||||
private void on_external_images_info_bar_response(Gtk.InfoBar sender, int response_id) {
|
||||
web_view.set_load_external_images(response_id == Gtk.ResponseType.OK);
|
||||
web_view.apply_load_external_images(response_id == Gtk.ResponseType.OK);
|
||||
sender.hide();
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ public class ConversationViewer : Gtk.Box {
|
|||
}
|
||||
|
||||
public void add_message(Geary.Email email) {
|
||||
web_view.set_load_external_images(false);
|
||||
web_view.apply_load_external_images(false);
|
||||
|
||||
// Make sure the message container is showing and the multi-message counter hidden.
|
||||
try {
|
||||
|
|
@ -871,25 +871,39 @@ public class ConversationViewer : Gtk.Box {
|
|||
// Now look for the signature.
|
||||
wrap_html_signature(ref container);
|
||||
|
||||
// Then get all inline images and replace them with data URLs.
|
||||
WebKit.DOM.NodeList inline_list = container.query_selector_all("img[src^=\"cid:\"]");
|
||||
for (int i = 0; i < inline_list.length; ++i) {
|
||||
// Then look for all <img> tags. Inline images are replaced with
|
||||
// data URLs, while external images are added to
|
||||
// external_images_uri (to be used later by is_image()).
|
||||
Gee.ArrayList<string> external_images_uri = new Gee.ArrayList<string>();
|
||||
WebKit.DOM.NodeList inline_list = container.query_selector_all("img");
|
||||
for (ulong i = 0; i < inline_list.length; ++i) {
|
||||
// Get the MIME content for the image.
|
||||
WebKit.DOM.HTMLImageElement img = (WebKit.DOM.HTMLImageElement) inline_list.item(i);
|
||||
string mime_id = img.get_attribute("src").substring(4);
|
||||
Geary.Memory.AbstractBuffer image_content =
|
||||
email.get_message().get_content_by_mime_id(mime_id);
|
||||
uint8[] image_data = image_content.get_array();
|
||||
string? src = img.get_attribute("src");
|
||||
if (Geary.String.is_empty(src)) {
|
||||
continue;
|
||||
} else if (src.has_prefix("cid:")) {
|
||||
string mime_id = src.substring(4);
|
||||
Geary.Memory.AbstractBuffer image_content =
|
||||
email.get_message().get_content_by_mime_id(mime_id);
|
||||
uint8[] image_data = image_content.get_array();
|
||||
|
||||
// Get the content type.
|
||||
bool uncertain_content_type;
|
||||
string mimetype = ContentType.get_mime_type(ContentType.guess(null, image_data,
|
||||
out uncertain_content_type));
|
||||
// Get the content type.
|
||||
bool uncertain_content_type;
|
||||
string mimetype = ContentType.get_mime_type(ContentType.guess(null, image_data,
|
||||
out uncertain_content_type));
|
||||
|
||||
// Then set the source to a data url.
|
||||
web_view.set_data_url(img, mimetype, image_data);
|
||||
// Then set the source to a data url.
|
||||
web_view.set_data_url(img, mimetype, image_data);
|
||||
} else if (!src.has_prefix("data:")) {
|
||||
external_images_uri.add(src);
|
||||
if (!web_view.load_external_images)
|
||||
external_images_info_bar.show();
|
||||
}
|
||||
}
|
||||
|
||||
web_view.set_external_images_uris(external_images_uri);
|
||||
|
||||
// Now return the whole message.
|
||||
return set_up_quotes(container.get_inner_html());
|
||||
} catch (Error e) {
|
||||
|
|
|
|||
|
|
@ -12,16 +12,19 @@ public class ConversationWebView : WebKit.WebView {
|
|||
|
||||
private const string USER_CSS = "user-message.css";
|
||||
private const string STYLE_NAME = "STYLE";
|
||||
|
||||
public signal void image_load_requested();
|
||||
public signal void link_selected(string link);
|
||||
|
||||
private bool load_external_images = false;
|
||||
private FileMonitor? user_style_monitor = null;
|
||||
|
||||
|
||||
public bool load_external_images { get; private set; default = false; }
|
||||
|
||||
// HTML element that contains message DIVs.
|
||||
public WebKit.DOM.HTMLDivElement? container { get; private set; default = null; }
|
||||
|
||||
|
||||
private Gee.ArrayList<string>? external_images_uri = null;
|
||||
private FileMonitor? user_style_monitor = null;
|
||||
|
||||
public signal void image_load_requested();
|
||||
|
||||
public signal void link_selected(string link);
|
||||
|
||||
public ConversationWebView() {
|
||||
// Set defaults.
|
||||
set_border_width(0);
|
||||
|
|
@ -79,15 +82,31 @@ public class ConversationWebView : WebKit.WebView {
|
|||
private void on_resource_request_starting(WebKit.WebFrame web_frame,
|
||||
WebKit.WebResource web_resource, WebKit.NetworkRequest request,
|
||||
WebKit.NetworkResponse? response) {
|
||||
|
||||
if (response != null) {
|
||||
// A request that was previously approved resulted in a redirect.
|
||||
return;
|
||||
}
|
||||
|
||||
string? uri = request.get_uri();
|
||||
bool uri_is_image = is_image(uri);
|
||||
if (uri_is_image && !load_external_images)
|
||||
image_load_requested();
|
||||
if (!is_always_loaded(uri) && !(uri_is_image && load_external_images))
|
||||
if (!is_always_loaded(uri) && !(is_image(uri) && load_external_images))
|
||||
request.set_uri("about:blank");
|
||||
}
|
||||
|
||||
|
||||
public void set_external_images_uris(Gee.ArrayList<string> uris) {
|
||||
external_images_uri = uris;
|
||||
}
|
||||
|
||||
public bool is_image(string? uri) {
|
||||
if (Geary.String.is_empty_or_whitespace(uri))
|
||||
return false;
|
||||
|
||||
if (uri.has_prefix("data:image/"))
|
||||
return true;
|
||||
|
||||
// check if external_images_uri is null in case this is called before a page is loaded
|
||||
return (external_images_uri != null) ? (uri in external_images_uri) : false;
|
||||
}
|
||||
|
||||
private bool is_always_loaded(string? uri) {
|
||||
if (uri == null)
|
||||
return false;
|
||||
|
|
@ -100,7 +119,7 @@ public class ConversationWebView : WebKit.WebView {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void set_load_external_images(bool load_external_images) {
|
||||
public void apply_load_external_images(bool load_external_images) {
|
||||
this.load_external_images = load_external_images;
|
||||
|
||||
// Refreshing the images would do nothing in this case--the resource has already been
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue