Commit 8098f42c authored by Michael Gratton's avatar Michael Gratton 🤞

Merge branch 'master' into 'master'

Issue #45 Fix

See merge request !103
parents 9b09cdef 7a37a465
Pipeline #58728 failed with stages
in 19 minutes and 46 seconds
......@@ -420,6 +420,9 @@ public class ConversationEmail : Gtk.Box, Geary.BaseInterface {
/** Fired when the view source action is activated. */
public signal void view_source();
/** Fired when a internal link is activated */
public signal void internal_link_activated(int y);
/** Fired when the user selects text in a message. */
internal signal void body_selection_changed(bool has_selection);
......@@ -756,6 +759,9 @@ public class ConversationEmail : Gtk.Box, Geary.BaseInterface {
private void connect_message_view_signals(ConversationMessage view) {
view.flag_remote_images.connect(on_flag_remote_images);
view.remember_remote_images.connect(on_remember_remote_images);
view.internal_link_activated.connect((y) => {
internal_link_activated(y);
});
view.web_view.internal_resource_loaded.connect(on_resource_loaded);
view.web_view.content_loaded.connect(on_content_loaded);
view.web_view.selection_changed.connect((has_selection) => {
......
......@@ -229,7 +229,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
}
// Base class for list rows it the list box
// Base class for list rows in the list box
internal abstract class ConversationRow : Gtk.ListBoxRow, Geary.BaseInterface {
......@@ -907,6 +907,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
);
view.mark_email.connect(on_mark_email);
view.mark_email_from_here.connect(on_mark_email_from_here);
view.internal_link_activated.connect(on_internal_link_activated);
view.body_selection_changed.connect((email, has_selection) => {
this.body_selected_view = has_selection ? email : null;
});
......@@ -957,6 +958,20 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
get_adjustment().set_value(y);
}
private void scroll_to_anchor(EmailRow row, int anchor_y) {
Gtk.Allocation? alloc = null;
row.get_allocation(out alloc);
int x = 0, y = 0;
ConversationWebView web_view = row.view.primary_message.web_view;
web_view.translate_coordinates(row, x, anchor_y, out x, out y);
Gtk.Adjustment adj = get_adjustment();
y = alloc.y + y;
adj.set_value(y);
}
/**
* Finds any currently visible messages, marks them as being read.
*/
......@@ -1156,4 +1171,9 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
}
}
private void on_internal_link_activated(ConversationEmail email, int y) {
EmailRow row = get_email_row_by_id(email.email.id);
scroll_to_anchor(row, y);
}
}
......@@ -20,6 +20,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
private const string FROM_CLASS = "geary-from";
private const string MATCH_CLASS = "geary-match";
private const string INTERNAL_ANCHOR_PREFIX = "geary:body#";
private const string REPLACED_CID_TEMPLATE = "replaced_%02u@geary";
private const string REPLACED_IMAGE_CLASS = "geary_replaced_inline_image";
......@@ -261,6 +262,9 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
/** Fired when the user clicks a link in the email. */
public signal void link_activated(string link);
/** Fired when the user clicks a internal link in the email. */
public signal void internal_link_activated(int y);
/** Fired when the user requests remote images be loaded. */
public signal void flag_remote_images();
......@@ -355,9 +359,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
this.web_view.get_inspector().show();
});
add_action(ACTION_OPEN_LINK, true, VariantType.STRING)
.activate.connect((param) => {
link_activated(param.get_string());
});
.activate.connect(on_link_activated);
add_action(ACTION_SAVE_IMAGE, true, new VariantType("(sms)"))
.activate.connect(on_save_image);
add_action(ACTION_SEARCH_FROM, true, VariantType.STRING)
......@@ -445,7 +447,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
this.web_view.context_menu.connect(on_context_menu);
this.web_view.deceptive_link_clicked.connect(on_deceptive_link_clicked);
this.web_view.link_activated.connect((link) => {
link_activated(link);
on_link_activated(new GLib.Variant("s", link));
});
this.web_view.mouse_target_changed.connect(on_mouse_target_changed);
this.web_view.notify["is-loading"].connect(on_is_loading_notify);
......@@ -1158,4 +1160,28 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
});
}
private void on_link_activated(GLib.Variant? param) {
string link = param.get_string();
if (link.has_prefix(INTERNAL_ANCHOR_PREFIX)) {
long start = INTERNAL_ANCHOR_PREFIX.length;
long end = link.length;
string anchor_body = link.substring(start, end - start);
this.web_view.get_anchor_target_y.begin(anchor_body, (obj, res) => {
try {
int y = this.web_view.get_anchor_target_y.end(res);
if (y > 0) {
internal_link_activated(y);
} else {
debug("Failed to get anchor destination");
}
} catch (GLib.Error err) {
debug("Failed to get anchor destination");
}
});
} else {
link_activated(link);
}
}
}
......@@ -96,6 +96,18 @@ public class ConversationWebView : ClientWebView {
return WebKitUtil.to_string(result);
}
/**
* Returns the y value for a element, by its id
*/
public async int? get_anchor_target_y(string anchor_body)
throws GLib.Error {
WebKit.JavascriptResult result = yield call(
Geary.JS.callable("geary.getAnchorTargetY")
.string(anchor_body), null
);
return (int) WebKitUtil.to_number(result);
}
/**
* Highlights user search terms in the message view.
*
......
......@@ -244,6 +244,21 @@ ConversationPageState.prototype = {
}
return value;
},
getAnchorTargetY: function(anchor) {
let target = document.getElementById(anchor);
if (target == null) {
target = document.getElementsByName(anchor);
if (target.length > 0) {
target = target[0];
}
}
if (target != null) {
return target.getBoundingClientRect().top +
document.documentElement.scrollTop;
} else {
return -1;
}
},
linkClicked: function(link) {
let cancelClick = false;
let href = link.href;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment