[geary/wip/728002-webkit2] Reimplement selection_changed signal for WK2.



commit 0b347f630bc435e00e1a439699386062e9e32c1d
Author: Michael James Gratton <mike vee net>
Date:   Sun Nov 27 11:24:09 2016 +1100

    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.

 src/client/components/client-web-view.vala         |   24 +++++++++++++++++++-
 src/client/composer/composer-widget.vala           |    9 ++++---
 .../conversation-viewer/conversation-email.vala    |   16 ++++++------
 .../conversation-viewer/conversation-message.vala  |   13 +++-------
 src/client/web-process/web-process-extension.vala  |    9 +++++++
 ui/client-web-view.js                              |    4 +++
 6 files changed, 53 insertions(+), 22 deletions(-)
---
diff --git a/src/client/components/client-web-view.vala b/src/client/components/client-web-view.vala
index 3830319..2a49b8e 100644
--- a/src/client/components/client-web-view.vala
+++ b/src/client/components/client-web-view.vala
@@ -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);
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 288a423..333efbb 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -513,7 +513,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);
 
@@ -845,9 +845,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) {
diff --git a/src/client/conversation-viewer/conversation-email.vala 
b/src/client/conversation-viewer/conversation-email.vala
index 99921cc..30bc0bc 100644
--- a/src/client/conversation-viewer/conversation-email.vala
+++ b/src/client/conversation-viewer/conversation-email.vala
@@ -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,
diff --git a/src/client/conversation-viewer/conversation-message.vala 
b/src/client/conversation-viewer/conversation-message.vala
index 4b3dd15..a544377 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -368,7 +368,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
@@ -928,14 +928,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) {
diff --git a/src/client/web-process/web-process-extension.vala 
b/src/client/web-process/web-process-extension.vala
index c3daf52..5b2a61e 100644
--- a/src/client/web-process/web-process-extension.vala
+++ b/src/client/web-process/web-process-extension.vala
@@ -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
diff --git a/ui/client-web-view.js b/ui/client-web-view.js
index 89c47f0..f4105f9 100644
--- a/ui/client-web-view.js
+++ b/ui/client-web-view.js
@@ -45,6 +45,10 @@ PageState.prototype = {
                 height
             );
         }
+    },
+    selectionChanged: function() {
+        var has_selection = !window.getSelection().isCollapsed;
+        window.webkit.messageHandlers.selectionChanged.postMessage(has_selection);
     }
 };
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]