[geary/bug/728002-webkit2: 102/140] Enable editing a link by clicking on it.



commit ab4fec91be80e1cf7bd35c66043426052d8b3cfa
Author: Michael James Gratton <mike vee net>
Date:   Thu Jan 19 13:16:13 2017 +1100

    Enable editing a link by clicking on it.
    
    * src/client/composer/composer-widget.vala
      (ComposerWidget::on_button_press): Show a link popover on button
      release.
    
    * src/client/composer/composer-web-view.vala (ComposerWebView): Add
      button_release_event_done signal to work around WK eating mouse events,
      fire it after default processing has occurred.
    
    * ui/composer-web-view.js: Don't bother selecting a link on click, we
      are handling insertion and deletion without it fine now. Just cancel
      the event's default so link clicks are not activated.

 src/client/composer/composer-web-view.vala |   12 ++++++++++++
 src/client/composer/composer-widget.vala   |   24 ++++++++++++++++++++++++
 ui/composer-web-view.js                    |    5 +----
 3 files changed, 37 insertions(+), 4 deletions(-)
---
diff --git a/src/client/composer/composer-web-view.vala b/src/client/composer/composer-web-view.vala
index 868b883..24f2a00 100644
--- a/src/client/composer/composer-web-view.vala
+++ b/src/client/composer/composer-web-view.vala
@@ -158,6 +158,9 @@ public class ComposerWebView : ClientWebView {
     /** Emitted when the cursor's edit context has changed. */
     public signal void cursor_context_changed(EditContext cursor_context);
 
+    /** Workaround for WebView eating the button event */
+    internal signal bool button_release_event_done(Gdk.Event event);
+
 
     public ComposerWebView(Configuration config) {
         base(config);
@@ -447,6 +450,15 @@ public class ComposerWebView : ClientWebView {
         return ""; // XXX
     }
 
+    public override bool button_release_event(Gdk.EventButton event) {
+        // WebView seems to unconditionally consume button events, so
+        // to show a link popopver after the view has processed one,
+        // we need to emit our own.
+        bool ret = base.button_press_event(event);
+        button_release_event_done(event);
+        return ret;
+    }
+
     private void on_command_stack_changed(WebKit.JavascriptResult result) {
         try {
             string[] values = WebKitUtil.to_string(result).split(",");
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index d9c0a42..25d2a18 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -508,6 +508,7 @@ public class ComposerWidget : Gtk.EventBox {
         this.reply_to_entry.changed.connect(validate_send_button);
 
         this.editor.command_stack_changed.connect(on_command_state_changed);
+        this.editor.button_release_event_done.connect(on_button_release);
         this.editor.context_menu.connect(on_context_menu);
         this.editor.cursor_context_changed.connect(on_cursor_context_changed);
         this.editor.document_modified.connect(() => { draft_changed(); });
@@ -2213,6 +2214,29 @@ public class ComposerWidget : Gtk.EventBox {
         }
     }
 
+    private bool on_button_release(Gdk.Event event) {
+        // Show the link popover on mouse release (instead of press)
+        // so the user can still select text with a link in it,
+        // without the popover immediately appearing and raining on
+        // their text selection parade.
+        if (this.pointer_url != null &&
+            this.actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean()) {
+            Gdk.EventButton? button = (Gdk.EventButton) event;
+            Gdk.Rectangle location = new Gdk.Rectangle();
+            location.x = (int) button.x;
+            location.y = (int) button.y;
+
+            ComposerLinkPopover popover = new_link_popover(
+                ComposerLinkPopover.Type.EXISTING_LINK,
+                this.pointer_url
+            );
+            popover.set_relative_to(this.editor);
+            popover.set_pointing_to(location);
+            popover.show();
+        }
+        return Gdk.EVENT_PROPAGATE;
+    }
+
     private void on_cursor_context_changed(ComposerWebView.EditContext context) {
         this.cursor_url = context.is_link ? context.link_url : null;
         update_cursor_actions();
diff --git a/ui/composer-web-view.js b/ui/composer-web-view.js
index 9665631..7aefa15 100644
--- a/ui/composer-web-view.js
+++ b/ui/composer-web-view.js
@@ -33,7 +33,7 @@ ComposerPageState.prototype = {
 
         document.addEventListener("click", function(e) {
             if (e.target.tagName == "A") {
-                state.linkClicked(e.target);
+                e.preventDefault();
             }
         }, true);
 
@@ -204,9 +204,6 @@ ComposerPageState.prototype = {
     documentModified: function(element) {
         window.webkit.messageHandlers.documentModified.postMessage(null);
     },
-    linkClicked: function(element) {
-        window.getSelection().selectAllChildren(element);
-    },
     selectionChanged: function() {
         PageState.prototype.selectionChanged.apply(this, []);
 


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