Reimplement selection_changed signal for WK2.

Add a "has_selection" param to avoid a second round-trip to the web
process to determine that.

* src/client/components/client-web-view.vala (ClientWebView): Add a
  selection_changed signal, register a JS message handler for the JS
  equivalent hook up firing the signal.

* src/client/web-process/web-process-extension.vala (GearyWebExtension):
  Send a JS selectionChanged message when the page's selection changes.

* src/client/composer/composer-widget.vala,
  src/client/conversation-viewer/conversation-email.vala,
  src/client/conversation-viewer/conversation-message.vala: Uncomment
  code that relied on the WK1 selection_changed signal, use signal param
  rather than DOM calls.

* ui/client-web-view.js: Implement sending the selectionChanged message.
This commit is contained in:
Michael James Gratton 2016-11-27 11:24:09 +11:00
parent 3068d1b0e5
commit 766d55e75d
6 changed files with 53 additions and 22 deletions

View file

@ -16,6 +16,8 @@ public class ClientWebView : WebKit.WebView {
private const string PREFERRED_HEIGHT_MESSAGE = "preferredHeightChanged";
private const string REMOTE_IMAGE_LOAD_BLOCKED_MESSAGE = "remoteImageLoadBlocked";
private const string SELECTION_CHANGED_MESSAGE = "selectionChanged";
private const double ZOOM_DEFAULT = 1.0;
private const double ZOOM_FACTOR = 0.1;
@ -81,6 +83,14 @@ public class ClientWebView : WebKit.WebView {
);
}
protected static bool get_bool_result(WebKit.JavascriptResult result)
throws JSError {
JS.GlobalContext context = result.get_global_context();
JS.Value value = result.get_value();
return context.to_boolean(value);
// XXX unref result?
}
protected static int get_int_result(WebKit.JavascriptResult result)
throws JSError {
JS.GlobalContext context = result.get_global_context();
@ -90,7 +100,7 @@ public class ClientWebView : WebKit.WebView {
}
JS.Value? err = null;
return (int) context.to_number(value, out err);
// XXX unref result
// XXX unref result?
}
private static inline uint to_wk2_font_size(Pango.FontDescription font) {
@ -144,6 +154,9 @@ public class ClientWebView : WebKit.WebView {
private int preferred_height = 0;
/** Emitted when the web view's selection has changed. */
public signal void selection_changed(bool has_selection);
/** Emitted when a user clicks a link in this web view. */
public signal void link_activated(string uri);
@ -198,9 +211,18 @@ public class ClientWebView : WebKit.WebView {
(result) => {
remote_image_load_blocked();
});
content_manager.script_message_received[SELECTION_CHANGED_MESSAGE].connect(
(result) => {
try {
selection_changed(get_bool_result(result));
} catch (JSError err) {
debug("Could not get selection content: %s", err.message);
}
});
register_message_handler(PREFERRED_HEIGHT_MESSAGE);
register_message_handler(REMOTE_IMAGE_LOAD_BLOCKED_MESSAGE);
register_message_handler(SELECTION_CHANGED_MESSAGE);
GearyApplication.instance.config.bind(Configuration.CONVERSATION_VIEWER_ZOOM_KEY, this, "zoom_level");
this.scroll_event.connect(on_scroll_event);

View file

@ -518,7 +518,7 @@ public class ComposerWidget : Gtk.EventBox {
// this.editor.paste_clipboard.connect(update_actions);
// this.editor.undo.connect(update_actions);
// this.editor.redo.connect(update_actions);
// this.editor.selection_changed.connect(update_actions);
this.editor.selection_changed.connect(update_actions);
this.editor.key_press_event.connect(on_editor_key_press);
//this.editor.user_changed_contents.connect(reset_draft_timer);
@ -861,9 +861,10 @@ public class ComposerWidget : Gtk.EventBox {
this.actions.change_action_state(ACTION_COMPOSE_AS_HTML,
GearyApplication.instance.config.compose_as_html);
// XXX
// if (can_delete_quote)
// this.editor.selection_changed.connect(() => { this.can_delete_quote = false; });
if (can_delete_quote)
this.editor.selection_changed.connect(
() => { this.can_delete_quote = false; }
);
}
private void show_attachment_overlay(bool visible) {

View file

@ -630,9 +630,9 @@ public class ConversationEmail : Gtk.Box {
this.message_bodies_loaded = true;
}
});
// view.web_view.selection_changed.connect(() => {
// on_message_selection_changed(view);
// });
view.web_view.selection_changed.connect(() => {
on_message_selection_changed(view);
});
}
private void update_email_state() {
@ -766,11 +766,11 @@ public class ConversationEmail : Gtk.Box {
contact_store.mark_contacts_async.begin(contact_list, flags, null);
}
// private void on_message_selection_changed(ConversationMessage view) {
// bool has_selection = view.web_view.has_selection();
// this.body_selection_message = has_selection ? view : null;
// body_selection_changed(has_selection);
// }
private void on_message_selection_changed(ConversationMessage view) {
bool has_selection = view.web_view.has_selection();
this.body_selection_message = has_selection ? view : null;
body_selection_changed(has_selection);
}
[GtkCallback]
private void on_attachments_child_activated(Gtk.FlowBox view,

View file

@ -380,7 +380,7 @@ public class ConversationMessage : Gtk.Grid {
this.web_view.remote_image_load_blocked.connect(() => {
this.remote_images_infobar.show();
});
//this.web_view.selection_changed.connect(on_selection_changed);
this.web_view.selection_changed.connect(on_selection_changed);
this.web_view.show();
this.body.set_has_tooltip(true); // Used to show link URLs
@ -940,14 +940,9 @@ public class ConversationMessage : Gtk.Grid {
return Gdk.EVENT_PROPAGATE;
}
// private void on_selection_changed() {
// bool has_selection = false;
// if (web_view.has_selection()) {
// WebKit.DOM.Document document = web_view.get_dom_document();
// has_selection = !document.default_view.get_selection().is_collapsed;
// }
// set_action_enabled(ACTION_COPY_SELECTION, has_selection);
// }
private void on_selection_changed(bool has_selection) {
set_action_enabled(ACTION_COPY_SELECTION, has_selection);
}
[GtkCallback]
private void on_remote_images_response(Gtk.InfoBar info_bar, int response_id) {

View file

@ -41,6 +41,9 @@ public class GearyWebExtension : Object {
// XXX Re-enable when we can depend on WK2 2.12
// web_page.console_message_sent.connect(on_console_message);
web_page.send_request.connect(on_send_request);
web_page.get_editor().selection_changed.connect(() => {
selection_changed(web_page);
});
});
}
@ -94,6 +97,12 @@ public class GearyWebExtension : Object {
execute_script(context, "geary.remoteImageLoadBlocked();");
}
private void selection_changed(WebKit.WebPage page) {
WebKit.Frame frame = page.get_main_frame();
JS.Context context = frame.get_javascript_global_context();
execute_script(context, "geary.selectionChanged();");
}
private JS.Value execute_script(JS.Context context, string script) {
JS.String js_script = new JS.String.create_with_utf8_cstring(script);
// XXX check err here, log it

View file

@ -45,6 +45,10 @@ PageState.prototype = {
height
);
}
},
selectionChanged: function() {
var has_selection = !window.getSelection().isCollapsed;
window.webkit.messageHandlers.selectionChanged.postMessage(has_selection);
}
};