[evolution/wip/tpopela/composer-dnd: 16/17] Fix drag and drop in composer



commit 34a4e0d10057d1657e68141b2241ee9735bfab88
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Mar 9 15:43:01 2017 +0100

    Fix drag and drop in composer
    
    Simplify how we handle the drag and drop. Now the drop is always handled
    by the EContentEditor first and then if the data are processed by the
    editor then it's handed to the EMsgComposer. Also the DOM operations
    are now handled on the web extension side to save some DBus calls.

 src/composer/e-composer-private.c                  |    2 -
 src/composer/e-composer-private.h                  |    4 +-
 src/composer/e-msg-composer.c                      |  295 +++-------------
 src/e-util/e-util-enums.h                          |   24 ++
 src/modules/webkit-editor/e-webkit-editor.c        |  134 ++++++++-
 .../web-extension/e-composer-dom-functions.c       |  244 --------------
 .../web-extension/e-composer-dom-functions.h       |    4 -
 .../web-extension/e-editor-dom-functions.c         |  355 +++++++++++++++++---
 .../web-extension/e-editor-dom-functions.h         |    3 +-
 .../web-extension/e-editor-undo-redo-manager.c     |   12 +-
 .../web-extension/e-editor-web-extension.c         |   40 ---
 11 files changed, 540 insertions(+), 577 deletions(-)
---
diff --git a/src/composer/e-composer-private.c b/src/composer/e-composer-private.c
index 91aef51..caeb272 100644
--- a/src/composer/e-composer-private.c
+++ b/src/composer/e-composer-private.c
@@ -132,8 +132,6 @@ e_composer_private_constructed (EMsgComposer *composer)
        priv->disable_signature = FALSE;
        priv->busy = FALSE;
        priv->saved_editable = FALSE;
-       priv->drop_occured = FALSE;
-       priv->dnd_is_uri = FALSE;
        priv->dnd_history_saved = FALSE;
        priv->check_if_signature_is_changed = FALSE;
        priv->ignore_next_signature_change = FALSE;
diff --git a/src/composer/e-composer-private.h b/src/composer/e-composer-private.h
index b2c50df..72b4d07 100644
--- a/src/composer/e-composer-private.h
+++ b/src/composer/e-composer-private.h
@@ -100,8 +100,6 @@ struct _EMsgComposerPrivate {
         * This is used to restore the previous editable state. */
        gboolean saved_editable;
        gboolean set_signature_from_message;
-       gboolean drop_occured;
-       gboolean dnd_is_uri;
        gboolean is_sending_message;
        gboolean dnd_history_saved;
        gboolean check_if_signature_is_changed;
@@ -119,6 +117,8 @@ struct _EMsgComposerPrivate {
        gulong notify_signature_uid_handler;
        gulong notify_subject_handler;
        gulong notify_subject_changed_handler;
+
+       gulong drag_data_received_handler_id;
 };
 
 void           e_composer_private_constructed  (EMsgComposer *composer);
diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
index 1268fe1..f7f1e4b 100644
--- a/src/composer/e-msg-composer.c
+++ b/src/composer/e-msg-composer.c
@@ -103,24 +103,14 @@ enum {
        LAST_SIGNAL
 };
 
-enum DndTargetType {
-       DND_TARGET_TYPE_TEXT_URI_LIST,
-       DND_TARGET_TYPE_MOZILLA_URL,
-       DND_TARGET_TYPE_TEXT_HTML,
-       DND_TARGET_TYPE_UTF8_STRING,
-       DND_TARGET_TYPE_TEXT_PLAIN,
-       DND_TARGET_TYPE_STRING,
-       DND_TARGET_TYPE_TEXT_PLAIN_UTF8
-};
-
 static GtkTargetEntry drag_dest_targets[] = {
-       { (gchar *) "text/uri-list", 0, DND_TARGET_TYPE_TEXT_URI_LIST },
-       { (gchar *) "_NETSCAPE_URL", 0, DND_TARGET_TYPE_MOZILLA_URL },
-       { (gchar *) "text/html", 0, DND_TARGET_TYPE_TEXT_HTML },
-       { (gchar *) "UTF8_STRING", 0, DND_TARGET_TYPE_UTF8_STRING },
-       { (gchar *) "text/plain", 0, DND_TARGET_TYPE_TEXT_PLAIN },
-       { (gchar *) "STRING", 0, DND_TARGET_TYPE_STRING },
-       { (gchar *) "text/plain;charset=utf-8", 0, DND_TARGET_TYPE_TEXT_PLAIN_UTF8 },
+       { (gchar *) "text/uri-list", 0, E_DND_TARGET_TYPE_TEXT_URI_LIST },
+       { (gchar *) "_NETSCAPE_URL", 0, E_DND_TARGET_TYPE_MOZILLA_URL },
+       { (gchar *) "text/html", 0, E_DND_TARGET_TYPE_TEXT_HTML },
+       { (gchar *) "UTF8_STRING", 0, E_DND_TARGET_TYPE_UTF8_STRING },
+       { (gchar *) "text/plain", 0, E_DND_TARGET_TYPE_TEXT_PLAIN },
+       { (gchar *) "STRING", 0, E_DND_TARGET_TYPE_STRING },
+       { (gchar *) "text/plain;charset=utf-8", 0, E_DND_TARGET_TYPE_TEXT_PLAIN_UTF8 },
 };
 
 static guint signals[LAST_SIGNAL];
@@ -1783,135 +1773,6 @@ msg_composer_paste_clipboard_cb (EContentEditor *cnt_editor,
 
        return TRUE;
 }
-#if 0 /* FIXME WK2 */
-static gboolean
-msg_composer_drag_motion_cb (GtkWidget *widget,
-                             GdkDragContext *context,
-                             gint x,
-                             gint y,
-                             guint time,
-                             EMsgComposer *composer)
-{
-       GtkWidget *source_widget;
-       EHTMLEditor *editor = e_msg_composer_get_editor (composer);
-       EHTMLEditorView *editor_view = e_html_editor_get_view (editor);
-
-       source_widget = gtk_drag_get_source_widget (context);
-       /* When we are doind DnD just inside the web view, the DnD is supposed
-        * to move things around. */
-       if (E_IS_HTML_EDITOR_VIEW (source_widget)) {
-               if ((gpointer) editor_view == (gpointer) source_widget) {
-                       gdk_drag_status (context, GDK_ACTION_MOVE, time);
-
-                       return FALSE;
-               }
-       }
-
-       gdk_drag_status (context, GDK_ACTION_COPY, time);
-
-       return FALSE;
-}
-
-static gboolean
-msg_composer_drag_drop_cb (GtkWidget *widget,
-                           GdkDragContext *context,
-                           gint x,
-                           gint y,
-                           guint time,
-                           EMsgComposer *composer)
-{
-       GdkAtom target;
-       GtkWidget *source_widget;
-
-       /* When we are doing DnD just inside the web view, the DnD is supposed
-        * to move things around. */
-       source_widget = gtk_drag_get_source_widget (context);
-       if (E_IS_HTML_EDITOR_VIEW (source_widget)) {
-               EHTMLEditor *editor = e_msg_composer_get_editor (composer);
-               EHTMLEditorView *editor_view = e_html_editor_get_view (editor);
-
-               if ((gpointer) editor_view == (gpointer) source_widget) {
-                       GDBusProxy *web_extension;
-
-                       web_extension = e_html_editor_view_get_web_extension_proxy (editor_view);
-                       if (web_extension) {
-                               e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-                                       web_extension,
-                                       "DOMSaveDragAndDropHistory",
-                                       g_variant_new (
-                                               "(t)",
-                                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (editor_view))),
-                                       NULL);
-                       }
-                       return FALSE;
-               }
-       }
-
-       target = gtk_drag_dest_find_target (widget, context, NULL);
-       if (target == GDK_NONE)
-               gdk_drag_status (context, 0, time);
-       else {
-               /* Prevent WebKit from pasting the URI of file into the view. Also
-                * prevent it from inserting the text/plain or text/html content as we
-                * want to insert it ourselves. */
-               if (composer->priv->dnd_is_uri || !E_IS_HTML_EDITOR_VIEW (source_widget))
-                       g_signal_stop_emission_by_name (widget, "drag-drop");
-
-               composer->priv->dnd_is_uri = FALSE;
-
-               if (E_IS_HTML_EDITOR_VIEW (source_widget))
-                       gdk_drag_status (context, GDK_ACTION_MOVE, time);
-               else
-                       gdk_drag_status (context, GDK_ACTION_COPY, time);
-
-               composer->priv->drop_occured = TRUE;
-               gtk_drag_get_data (widget, context, target, time);
-
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-static void
-msg_composer_drag_data_received_after_cb (GtkWidget *widget,
-                                          GdkDragContext *context,
-                                          gint x,
-                                          gint y,
-                                          GtkSelectionData *selection,
-                                          guint info,
-                                          guint time,
-                                          EMsgComposer *composer)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-
-       if (!composer->priv->drop_occured)
-               goto out;
-
-       /* Save just history for events handled by WebKit. */
-       if (composer->priv->dnd_history_saved)
-               goto out;
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               web_extension,
-               "DOMCleanAfterDragAndDrop",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               NULL);
-
- out:
-       composer->priv->drop_occured = FALSE;
-       composer->priv->dnd_history_saved = FALSE;
-}
 
 static gchar *
 next_uri (guchar **uri_list,
@@ -1950,90 +1811,16 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
 {
        EHTMLEditor *editor;
        EContentEditor *cnt_editor;
-       gboolean html_mode, same_widget = FALSE;
-       GtkWidget *source_widget;
+       gboolean html_mode, is_move;
 
        editor = e_msg_composer_get_editor (composer);
        cnt_editor = e_html_editor_get_content_editor (editor);
        html_mode = e_content_editor_get_html_mode (cnt_editor);
 
-       composer->priv->dnd_history_saved = TRUE;
+       g_signal_handler_disconnect (cnt_editor, composer->priv->drag_data_received_handler_id);
+       composer->priv->drag_data_received_handler_id = 0;
 
-       /* When we are doing DnD just inside the web view, the DnD is supposed
-        * to move things around. */
-       source_widget = gtk_drag_get_source_widget (context);
-       if (E_IS_CONTENT_EDITOR (source_widget) &&
-           ((gpointer) cnt_editor == (gpointer) source_widget))
-               same_widget = TRUE;
-
-       /* Leave DnD inside the view on WebKit. */
-       if (composer->priv->drop_occured && same_widget) {
-               gdk_drag_status (context, 0, time);
-               return;
-       }
-
-       if (!composer->priv->drop_occured) {
-               if (!same_widget) {
-                       /* Check if we are DnD'ing some URI, if so WebKit will
-                        * insert the URI into the view and we have to prevent it
-                        * from doing that. */
-                       if (info == DND_TARGET_TYPE_TEXT_URI_LIST) {
-                               gchar **uris;
-
-                               uris = gtk_selection_data_get_uris (selection);
-                               /* I don't know what regressed outside of Evo, but
-                                * this is called twice. Firstly with uris set
-                                * following by one with uris not set. */
-                               if (!composer->priv->dnd_is_uri)
-                                       composer->priv->dnd_is_uri = uris != NULL;
-                               g_strfreev (uris);
-                       }
-               }
-               return;
-       }
-
-       composer->priv->dnd_is_uri = FALSE;
-
-       /* Leave the text on WebKit to handle it. */
-       if (info == DND_TARGET_TYPE_UTF8_STRING ||
-           info == DND_TARGET_TYPE_STRING ||
-           info == DND_TARGET_TYPE_TEXT_PLAIN ||
-           info == DND_TARGET_TYPE_TEXT_PLAIN_UTF8) {
-               composer->priv->dnd_history_saved = FALSE;
-               gdk_drag_status (context, 0, time);
-               return;
-       }
-
-       if (info == DND_TARGET_TYPE_TEXT_HTML) {
-               const guchar *data;
-               gint length;
-               gint list_len, len;
-               gchar *text;
-
-               data = gtk_selection_data_get_data (selection);
-               length = gtk_selection_data_get_length (selection);
-
-               if (!data || length < 0) {
-                       gtk_drag_finish (context, FALSE, FALSE, time);
-                       return;
-               }
-
-               e_content_editor_move_caret_on_coordinates (cnt_editor, x, y, FALSE);
-
-               list_len = length;
-               do {
-                       text = next_uri ((guchar **) &data, &len, &list_len);
-                       e_content_editor_insert_content (
-                               cnt_editor,
-                               text,
-                               E_CONTENT_EDITOR_INSERT_TEXT_HTML);
-                       g_free (text);
-               } while (list_len);
-
-               gtk_drag_finish (context, TRUE, FALSE, time);
-
-               return;
-       }
+       is_move = gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE;
 
        /* HTML mode has a few special cases for drops... */
        /* If we're receiving URIs and -all- the URIs point to
@@ -2064,7 +1851,7 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        g_free (uri);
                } while (list_len);
 
-               gtk_drag_finish (context, TRUE, FALSE, time);
+               gtk_drag_finish (context, TRUE, is_move, time);
        } else {
                EAttachmentView *attachment_view =
                        e_msg_composer_get_attachment_view (composer);
@@ -2077,7 +1864,43 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        context, x, y, selection, info, time);
        }
 }
-#endif
+
+static gboolean
+msg_composer_drag_drop_cb (GtkWidget *widget,
+                           GdkDragContext *context,
+                           gint x,
+                           gint y,
+                           guint time,
+                           EMsgComposer *composer)
+{
+       GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
+
+       if (target == GDK_NONE) {
+               gdk_drag_status (context, 0, time);
+       } else {
+               composer->priv->drag_data_received_handler_id = g_signal_connect (
+                       E_CONTENT_EDITOR (widget), "drag-data-received",
+                       G_CALLBACK (msg_composer_drag_data_received_cb), composer);
+
+               gtk_drag_get_data (widget, context, target, time);
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static void
+msg_composer_drag_begin_cb (GtkWidget *widget,
+                            GdkDragContext *context,
+                            EMsgComposer *composer)
+{
+       if (composer->priv->drag_data_received_handler_id != 0) {
+               g_signal_handler_disconnect (E_CONTENT_EDITOR( widget), 
composer->priv->drag_data_received_handler_id);
+               composer->priv->drag_data_received_handler_id = 0;
+       }
+}
+
 static void
 msg_composer_notify_header_cb (EMsgComposer *composer)
 {
@@ -2466,28 +2289,14 @@ msg_composer_constructed (GObject *object)
                G_CALLBACK (msg_composer_paste_primary_clipboard_cb), composer);
 
        /* Drag-and-Drop Support */
-#if 0 /* FIXME WK2 */
-       EHTMLEditorView *view;
-
-       view = e_html_editor_get_view (editor);
-
        g_signal_connect (
-               view, "drag-motion",
-               G_CALLBACK (msg_composer_drag_motion_cb), composer);
-
-        g_signal_connect (
-               view, "drag-drop",
+               cnt_editor, "drag-drop",
                G_CALLBACK (msg_composer_drag_drop_cb), composer);
 
        g_signal_connect (
-               view, "drag-data-received",
-               G_CALLBACK (msg_composer_drag_data_received_cb), composer);
+               cnt_editor, "drag-begin",
+               G_CALLBACK (msg_composer_drag_begin_cb), composer);
 
-       /* Used for fixing various stuff after WebKit processed the DnD data. */
-       g_signal_connect_after (
-               view, "drag-data-received",
-               G_CALLBACK (msg_composer_drag_data_received_after_cb), composer);
-#endif
        g_signal_connect (
                composer->priv->gallery_icon_view, "drag-data-get",
                G_CALLBACK (msg_composer_gallery_drag_data_get), NULL);
diff --git a/src/e-util/e-util-enums.h b/src/e-util/e-util-enums.h
index 6078cb9..75eeeee 100644
--- a/src/e-util/e-util-enums.h
+++ b/src/e-util/e-util-enums.h
@@ -548,6 +548,30 @@ typedef enum {
        E_CLIPBOARD_CAN_PASTE   = 1 << 2 */
 } EClipboardFlags;
 
+/**
+ * EDnDTargetType:
+ * DND_TARGET_TYPE_TEXT_URI_LIST: text/uri-list
+ * DND_TARGET_TYPE_MOZILLA_URL: _NETSCAPE_URL
+ * DND_TARGET_TYPE_TEXT_HTML: text/html
+ * DND_TARGET_TYPE_UTF8_STRING: UTF8_STRING
+ * DND_TARGET_TYPE_TEXT_PLAIN: text/plain
+ * DND_TARGET_TYPE_STRING: STRING
+ * DND_TARGET_TYPE_TEXT_PLAIN_UTF8: text/plain;charser=utf-8
+ *
+ * Drag and drop targets supported by EContentEditor.
+ *
+ * Since: 3.26
+ **/
+typedef enum {
+       E_DND_TARGET_TYPE_TEXT_URI_LIST = 0,
+       E_DND_TARGET_TYPE_MOZILLA_URL,
+       E_DND_TARGET_TYPE_TEXT_HTML,
+       E_DND_TARGET_TYPE_UTF8_STRING,
+       E_DND_TARGET_TYPE_TEXT_PLAIN,
+       E_DND_TARGET_TYPE_STRING,
+       E_DND_TARGET_TYPE_TEXT_PLAIN_UTF8
+} EDnDTargetType;
+
 G_END_DECLS
 
 #endif /* E_UTIL_ENUMS_H */
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 00906e1..c9d5bd7 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -132,6 +132,9 @@ struct _EWebKitEditorPrivate {
        gulong found_text_handler_id;
        gulong failed_to_find_text_handler_id;
 
+       gboolean performing_drag;
+       gulong drag_data_received_handler_id;
+
        gchar *last_hover_uri;
 };
 
@@ -5772,10 +5775,127 @@ webkit_editor_context_menu_cb (EWebKitEditor *wk_editor,
 }
 
 static void
+webkit_editor_drag_begin_cb (EWebKitEditor *wk_editor,
+                             GdkDragContext *context)
+{
+       wk_editor->priv->performing_drag = TRUE;
+}
+
+static void
+webkit_editor_drag_failed_cb (EWebKitEditor *wk_editor,
+                              GdkDragContext *context,
+                              GtkDragResult result)
+{
+       wk_editor->priv->performing_drag = FALSE;
+}
+
+static void
 webkit_editor_drag_end_cb (EWebKitEditor *wk_editor,
                            GdkDragContext *context)
 {
-       webkit_editor_call_simple_extension_function (wk_editor, "DOMDragAndDropEnd");
+       wk_editor->priv->performing_drag = FALSE;
+}
+
+static gchar *
+next_uri (guchar **uri_list,
+          gint *len,
+          gint *list_len)
+{
+       guchar *uri, *begin;
+
+       begin = *uri_list;
+       *len = 0;
+       while (**uri_list && **uri_list != '\n' && **uri_list != '\r' && *list_len) {
+               (*uri_list) ++;
+               (*len) ++;
+               (*list_len) --;
+       }
+
+       uri = (guchar *) g_strndup ((gchar *) begin, *len);
+
+       while ((!**uri_list || **uri_list == '\n' || **uri_list == '\r') && *list_len) {
+               (*uri_list) ++;
+               (*list_len) --;
+       }
+
+       return (gchar *) uri;
+}
+
+static void
+webkit_editor_drag_data_received_cb (GtkWidget *widget,
+                                     GdkDragContext *context,
+                                     gint x,
+                                     gint y,
+                                     GtkSelectionData *selection,
+                                     guint info,
+                                     guint time)
+{
+       EWebKitEditor *wk_editor = E_WEBKIT_EDITOR (widget);
+       gboolean is_move = FALSE;
+
+       g_signal_handler_disconnect (wk_editor, wk_editor->priv->drag_data_received_handler_id);
+       wk_editor->priv->drag_data_received_handler_id = 0;
+
+       /* Leave DnD inside the view on WebKit */
+       /* Leave the text on WebKit to handle it. */
+       if (wk_editor->priv->performing_drag ||
+           info == E_DND_TARGET_TYPE_UTF8_STRING || info == E_DND_TARGET_TYPE_STRING ||
+           info == E_DND_TARGET_TYPE_TEXT_PLAIN || info == E_DND_TARGET_TYPE_TEXT_PLAIN_UTF8) {
+               gdk_drag_status (context, gdk_drag_context_get_selected_action(context), time);
+               GTK_WIDGET_CLASS (e_webkit_editor_parent_class)->drag_drop (widget, context, x, y, time);
+               g_signal_stop_emission_by_name (widget, "drag-data-received");
+               return;
+       }
+
+       is_move = gdk_drag_context_get_selected_action(context) == GDK_ACTION_MOVE;
+
+       if (info == E_DND_TARGET_TYPE_TEXT_HTML) {
+               const guchar *data;
+               gint length;
+               gint list_len, len;
+               gchar *text;
+
+               data = gtk_selection_data_get_data (selection);
+               length = gtk_selection_data_get_length (selection);
+
+               if (!data || length < 0) {
+                       gtk_drag_finish (context, FALSE, is_move, time);
+                       g_signal_stop_emission_by_name (widget, "drag-data-received");
+                       return;
+               }
+
+               webkit_editor_move_caret_on_coordinates (E_CONTENT_EDITOR (widget), x, y, FALSE);
+
+               list_len = length;
+               do {
+                       text = next_uri ((guchar **) &data, &len, &list_len);
+                       webkit_editor_insert_content (
+                               E_CONTENT_EDITOR (wk_editor),
+                               text,
+                               E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+                       g_free (text);
+               } while (list_len);
+
+               gtk_drag_finish (context, TRUE, is_move, time);
+               g_signal_stop_emission_by_name (widget, "drag-data-received");
+               return;
+       }
+}
+
+static gboolean
+webkit_editor_drag_drop_cb (EWebKitEditor *wk_editor,
+                            GdkDragContext *context,
+                            gint x,
+                            gint y,
+                            guint time)
+{
+       wk_editor->priv->drag_data_received_handler_id = g_signal_connect (
+               wk_editor, "drag-data-received",
+               G_CALLBACK (webkit_editor_drag_data_received_cb), NULL);
+
+       webkit_editor_set_changed (wk_editor, TRUE);
+
+       return FALSE;
 }
 
 static void
@@ -6079,10 +6199,22 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
                G_CALLBACK (webkit_editor_mouse_target_changed_cb), NULL);
 
        g_signal_connect (
+               wk_editor, "drag-begin",
+               G_CALLBACK (webkit_editor_drag_begin_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "drag-failed",
+               G_CALLBACK (webkit_editor_drag_failed_cb), NULL);
+
+       g_signal_connect (
                wk_editor, "drag-end",
                G_CALLBACK (webkit_editor_drag_end_cb), NULL);
 
        g_signal_connect (
+               wk_editor, "drag-drop",
+               G_CALLBACK (webkit_editor_drag_drop_cb), NULL);
+
+       g_signal_connect (
                wk_editor, "web-process-crashed",
                G_CALLBACK (webkit_editor_web_process_crashed_cb), NULL);
 
diff --git a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c 
b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
index a200680..1544081 100644
--- a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.c
@@ -589,247 +589,3 @@ e_composer_dom_get_raw_body_content (EEditorPage *editor_page)
 
        return  webkit_dom_html_element_get_inner_text (body);
 }
-
-static void
-insert_nbsp_history_event (WebKitDOMDocument *document,
-                           EEditorUndoRedoManager *manager,
-                           gboolean delete,
-                           guint x,
-                           guint y)
-{
-       EEditorHistoryEvent *event;
-       WebKitDOMDocumentFragment *fragment;
-
-       event = g_new0 (EEditorHistoryEvent, 1);
-       event->type = HISTORY_AND;
-       e_editor_undo_redo_manager_insert_history_event (manager, event);
-
-       fragment = webkit_dom_document_create_document_fragment (document);
-       webkit_dom_node_append_child (
-               WEBKIT_DOM_NODE (fragment),
-               WEBKIT_DOM_NODE (
-                       webkit_dom_document_create_text_node (document, UNICODE_NBSP)),
-               NULL);
-
-       event = g_new0 (EEditorHistoryEvent, 1);
-       event->type = HISTORY_DELETE;
-
-       if (delete)
-               g_object_set_data (G_OBJECT (fragment), "history-delete-key", GINT_TO_POINTER (1));
-
-       event->data.fragment = fragment;
-
-       event->before.start.x = x;
-       event->before.start.y = y;
-       event->before.end.x = x;
-       event->before.end.y = y;
-
-       event->after.start.x = x;
-       event->after.start.y = y;
-       event->after.end.x = x;
-       event->after.end.y = y;
-
-       e_editor_undo_redo_manager_insert_history_event (manager, event);
-}
-
-void
-e_composer_dom_save_drag_and_drop_history (EEditorPage *editor_page)
-{
-       WebKitDOMDocument *document;
-       WebKitDOMDocumentFragment *fragment;
-       WebKitDOMDOMSelection *dom_selection = NULL;
-       WebKitDOMDOMWindow *dom_window = NULL;
-       WebKitDOMRange *beginning_of_line = NULL;
-       WebKitDOMRange *range = NULL, *range_clone = NULL;
-       EEditorHistoryEvent *event;
-       EEditorUndoRedoManager *manager;
-       gboolean start_to_start, end_to_end;
-       gchar *range_text;
-       guint x, y;
-
-       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
-
-       document = e_editor_page_get_document (editor_page);
-       manager = e_editor_page_get_undo_redo_manager (editor_page);
-
-       if (!(dom_window = webkit_dom_document_get_default_view (document)))
-               return;
-
-       if (!(dom_selection = webkit_dom_dom_window_get_selection (dom_window))) {
-               g_clear_object (&dom_window);
-               return;
-       }
-
-       g_clear_object (&dom_window);
-
-       if (webkit_dom_dom_selection_get_range_count (dom_selection) < 1) {
-               g_clear_object (&dom_selection);
-               return;
-       }
-
-       /* Obtain the dragged content. */
-       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       range_clone = webkit_dom_range_clone_range (range, NULL);
-
-       /* Create the history event for the content that will
-        * be removed by DnD. */
-       event = g_new0 (EEditorHistoryEvent, 1);
-       event->type = HISTORY_DELETE;
-
-       e_editor_dom_selection_get_coordinates (editor_page,
-               &event->before.start.x,
-               &event->before.start.y,
-               &event->before.end.x,
-               &event->before.end.y);
-
-       x = event->before.start.x;
-       y = event->before.start.y;
-
-       event->after.start.x = x;
-       event->after.start.y = y;
-       event->after.end.x = x;
-       event->after.end.y = y;
-
-       /* Save the content that will be removed. */
-       fragment = webkit_dom_range_clone_contents (range_clone, NULL);
-
-       /* Extend the cloned range to point one character after
-        * the selection ends to later check if there is a whitespace
-        * after it. */
-       webkit_dom_range_set_end (
-               range_clone,
-               webkit_dom_range_get_end_container (range_clone, NULL),
-               webkit_dom_range_get_end_offset (range_clone, NULL) + 1,
-               NULL);
-       range_text = webkit_dom_range_get_text (range_clone);
-
-       /* Check if the current selection starts on the beginning
-        * of line. */
-       webkit_dom_dom_selection_modify (
-               dom_selection, "extend", "left", "lineboundary");
-       beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       start_to_start = webkit_dom_range_compare_boundary_points (
-               beginning_of_line, 0 /* START_TO_START */, range, NULL) == 0;
-
-       /* Restore the selection to state before the check. */
-       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
-       webkit_dom_dom_selection_add_range (dom_selection, range);
-       g_clear_object (&beginning_of_line);
-
-       /* Check if the current selection end on the end of the line. */
-       webkit_dom_dom_selection_modify (
-               dom_selection, "extend", "right", "lineboundary");
-       beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       end_to_end = webkit_dom_range_compare_boundary_points (
-               beginning_of_line, 2 /* END_TO_END */, range, NULL) == 0;
-
-       /* Dragging the whole line. */
-       if (start_to_start && end_to_end) {
-               WebKitDOMNode *container, *actual_block, *tmp_block;
-
-               /* Select the whole line (to the beginning of the next
-                * one so we can reuse the undo code while undoing this.
-                * Because of this we need to special mark the event
-                * with history-drag-and-drop to correct the selection
-                * after undoing it (otherwise the beginning of the next
-                * line will be selected as well. */
-               webkit_dom_dom_selection_modify (
-                       dom_selection, "extend", "right", "character");
-               g_clear_object (&beginning_of_line);
-               beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-
-               container = webkit_dom_range_get_end_container (range, NULL);
-               actual_block = e_editor_dom_get_parent_block_node_from_child (container);
-
-               tmp_block = webkit_dom_range_get_end_container (beginning_of_line, NULL);
-               if ((tmp_block = e_editor_dom_get_parent_block_node_from_child (tmp_block))) {
-                       e_editor_dom_selection_get_coordinates (editor_page,
-                               &event->before.start.x,
-                               &event->before.start.y,
-                               &event->before.end.x,
-                               &event->before.end.y);
-
-                       /* Create the right content for the history event. */
-                       fragment = webkit_dom_document_create_document_fragment (document);
-                       /* The removed line. */
-                       webkit_dom_node_append_child (
-                               WEBKIT_DOM_NODE (fragment),
-                               webkit_dom_node_clone_node_with_error (actual_block, TRUE, NULL),
-                               NULL);
-                       /* The following block, but empty. */
-                       webkit_dom_node_append_child (
-                               WEBKIT_DOM_NODE (fragment),
-                               webkit_dom_node_clone_node_with_error (tmp_block, FALSE, NULL),
-                               NULL);
-                       g_object_set_data (
-                               G_OBJECT (fragment),
-                               "history-drag-and-drop",
-                               GINT_TO_POINTER (1));
-                       /* It should act as a Delete key press. */
-                       g_object_set_data (
-                               G_OBJECT (fragment),
-                               "history-delete-key",
-                               GINT_TO_POINTER (1));
-               }
-       }
-
-       event->data.fragment = fragment;
-       e_editor_undo_redo_manager_insert_history_event (manager, event);
-
-       /* Selection is ending on the end of the line, check if
-        * there is a space before the selection start. If so, it
-        * will be removed and we need create the history event
-        * for it. */
-       if (end_to_end) {
-               gchar *range_text_start;
-               glong start_offset;
-
-               start_offset = webkit_dom_range_get_start_offset (range_clone, NULL);
-               webkit_dom_range_set_start (
-                       range_clone,
-                       webkit_dom_range_get_start_container (range_clone, NULL),
-                       start_offset > 0 ? start_offset - 1 : 0,
-                       NULL);
-
-               range_text_start = webkit_dom_range_get_text (range_clone);
-               if (g_str_has_prefix (range_text_start, " ") ||
-                   g_str_has_prefix (range_text_start, UNICODE_NBSP))
-                       insert_nbsp_history_event (document, manager, FALSE, x, y);
-
-               g_free (range_text_start);
-       }
-
-       /* WebKit removes the space (if presented) after selection and
-        * we need to create a new history event for it. */
-       if (g_str_has_suffix (range_text, " ") ||
-           g_str_has_suffix (range_text, UNICODE_NBSP))
-               insert_nbsp_history_event (document, manager, TRUE, x, y);
-
-       g_free (range_text);
-
-       /* Restore the selection to original state. */
-       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
-       webkit_dom_dom_selection_add_range (dom_selection, range);
-       g_clear_object (&beginning_of_line);
-
-       /* All the things above were about removing the content,
-        * create an AND event to continue later with inserting
-        * the dropped content. */
-       event = g_new0 (EEditorHistoryEvent, 1);
-       event->type = HISTORY_AND;
-       e_editor_undo_redo_manager_insert_history_event (manager, event);
-
-       g_clear_object (&dom_selection);
-
-       g_clear_object (&range);
-       g_clear_object (&range_clone);
-}
-
-void
-e_composer_dom_clean_after_drag_and_drop (EEditorPage *editor_page)
-{
-       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
-
-       e_editor_dom_save_history_for_drop (editor_page);
-       e_editor_dom_check_magic_links (editor_page, FALSE);
-}
diff --git a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.h 
b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.h
index 8e0f934..a204346 100644
--- a/src/modules/webkit-editor/web-extension/e-composer-dom-functions.h
+++ b/src/modules/webkit-editor/web-extension/e-composer-dom-functions.h
@@ -38,10 +38,6 @@ gchar *              e_composer_dom_get_raw_body_content_without_signature
                                                (EEditorPage *editor_page);
 gchar *                e_composer_dom_get_raw_body_content
                                                (EEditorPage *editor_page);
-void           e_composer_dom_save_drag_and_drop_history
-                                               (EEditorPage *editor_page);
-void           e_composer_dom_clean_after_drag_and_drop
-                                               (EEditorPage *editor_page);
 
 G_END_DECLS
 
diff --git a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c 
b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
index c840194..74ef796 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.c
@@ -5752,6 +5752,69 @@ body_compositionend_event_cb (WebKitDOMElement *element,
 }
 
 static void
+body_drop_event_cb (WebKitDOMElement *element,
+                    WebKitDOMUIEvent *event,
+                    EEditorPage *editor_page)
+{
+       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
+
+       if (e_editor_page_is_pasting_content_from_itself (editor_page))
+               e_editor_dom_save_history_for_drop (editor_page);
+}
+
+static void
+body_dragstart_event_cb (WebKitDOMElement *element,
+                         WebKitDOMUIEvent *event,
+                         EEditorPage *editor_page)
+{
+       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
+
+       e_editor_dom_remove_input_event_listener_from_body (editor_page);
+       e_editor_page_set_pasting_content_from_itself (editor_page, TRUE);
+       e_editor_dom_save_history_for_drag (editor_page);
+}
+
+static void
+body_dragend_event_cb (WebKitDOMElement *element,
+                       WebKitDOMUIEvent *event,
+                       EEditorPage *editor_page)
+{
+       EEditorHistoryEvent *ev;
+       EEditorUndoRedoManager *manager;
+
+       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
+
+       manager = e_editor_page_get_undo_redo_manager (editor_page);
+       if (e_editor_page_is_pasting_content_from_itself (editor_page) &&
+          (ev = e_editor_undo_redo_manager_get_current_history_event (manager))) {
+               if (ev->type == HISTORY_INSERT_HTML &&
+                   ev->after.start.x == 0 && ev->after.start.y == 0 &&
+                   ev->after.end.x == 0 && ev->after.end.y == 0) {
+                       e_editor_dom_selection_get_coordinates (editor_page,
+                               &ev->after.start.x,
+                               &ev->after.start.y,
+                               &ev->after.end.x,
+                               &ev->after.end.y);
+                       ev->before.start.x = ev->after.start.x;
+                       ev->before.start.y = ev->after.start.y;
+                       ev->before.end.x = ev->after.start.x;
+                       ev->before.end.y = ev->after.start.y;
+                       e_editor_dom_force_spell_check_in_viewport (editor_page);
+               } else {
+                       /* Drag and Drop was cancelled */
+                       while (ev && ev->type == HISTORY_AND) {
+                               e_editor_undo_redo_manager_remove_current_history_event (manager);
+                               e_editor_undo_redo_manager_remove_current_history_event (manager);
+                               ev = e_editor_undo_redo_manager_get_current_history_event (manager);
+                       }
+               }
+       }
+
+       e_editor_page_set_pasting_content_from_itself (editor_page, FALSE);
+       e_editor_dom_register_input_event_listener_on_body (editor_page);
+}
+
+static void
 register_html_events_handlers (EEditorPage *editor_page,
                                WebKitDOMHTMLElement *body)
 {
@@ -5791,6 +5854,27 @@ register_html_events_handlers (EEditorPage *editor_page,
                G_CALLBACK (body_compositionend_event_cb),
                FALSE,
                editor_page);
+
+       webkit_dom_event_target_add_event_listener (
+               WEBKIT_DOM_EVENT_TARGET (body),
+               "drop",
+               G_CALLBACK (body_drop_event_cb),
+               FALSE,
+               editor_page);
+
+       webkit_dom_event_target_add_event_listener (
+               WEBKIT_DOM_EVENT_TARGET (body),
+               "dragstart",
+               G_CALLBACK (body_dragstart_event_cb),
+               FALSE,
+               editor_page);
+
+       webkit_dom_event_target_add_event_listener (
+               WEBKIT_DOM_EVENT_TARGET (body),
+               "dragend",
+               G_CALLBACK (body_dragend_event_cb),
+               FALSE,
+               editor_page);
 }
 
 void
@@ -10841,6 +10925,236 @@ e_editor_dom_get_caret_position (EEditorPage *editor_page)
        return ret_val;
 }
 
+static void
+insert_nbsp_history_event (WebKitDOMDocument *document,
+                           EEditorUndoRedoManager *manager,
+                           gboolean delete,
+                           guint x,
+                           guint y)
+{
+       EEditorHistoryEvent *event;
+       WebKitDOMDocumentFragment *fragment;
+
+       event = g_new0 (EEditorHistoryEvent, 1);
+       event->type = HISTORY_AND;
+       e_editor_undo_redo_manager_insert_history_event (manager, event);
+
+       fragment = webkit_dom_document_create_document_fragment (document);
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (fragment),
+               WEBKIT_DOM_NODE (
+                       webkit_dom_document_create_text_node (document, UNICODE_NBSP)),
+               NULL);
+
+       event = g_new0 (EEditorHistoryEvent, 1);
+       event->type = HISTORY_DELETE;
+
+       if (delete)
+               g_object_set_data (G_OBJECT (fragment), "history-delete-key", GINT_TO_POINTER (1));
+
+       event->data.fragment = fragment;
+
+       event->before.start.x = x;
+       event->before.start.y = y;
+       event->before.end.x = x;
+       event->before.end.y = y;
+
+       event->after.start.x = x;
+       event->after.start.y = y;
+       event->after.end.x = x;
+       event->after.end.y = y;
+
+       e_editor_undo_redo_manager_insert_history_event (manager, event);
+}
+void
+e_editor_dom_save_history_for_drag (EEditorPage *editor_page)
+{
+       WebKitDOMDocument *document;
+       WebKitDOMDocumentFragment *fragment;
+       WebKitDOMDOMSelection *dom_selection = NULL;
+       WebKitDOMDOMWindow *dom_window = NULL;
+       WebKitDOMRange *beginning_of_line = NULL;
+       WebKitDOMRange *range = NULL, *range_clone = NULL;
+       EEditorHistoryEvent *event;
+       EEditorUndoRedoManager *manager;
+       gboolean start_to_start, end_to_end;
+       gchar *range_text;
+       guint x, y;
+
+       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
+
+       document = e_editor_page_get_document (editor_page);
+       manager = e_editor_page_get_undo_redo_manager (editor_page);
+
+       if (!(dom_window = webkit_dom_document_get_default_view (document)))
+               return;
+
+       if (!(dom_selection = webkit_dom_dom_window_get_selection (dom_window))) {
+               g_clear_object (&dom_window);
+               return;
+       }
+
+       g_clear_object (&dom_window);
+
+       if (webkit_dom_dom_selection_get_range_count (dom_selection) < 1) {
+               g_clear_object (&dom_selection);
+               return;
+       }
+
+       /* Obtain the dragged content. */
+       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       range_clone = webkit_dom_range_clone_range (range, NULL);
+
+       /* Create the history event for the content that will
+        * be removed by DnD. */
+       event = g_new0 (EEditorHistoryEvent, 1);
+       event->type = HISTORY_DELETE;
+
+       e_editor_dom_selection_get_coordinates (editor_page,
+               &event->before.start.x,
+               &event->before.start.y,
+               &event->before.end.x,
+               &event->before.end.y);
+
+       x = event->before.start.x;
+       y = event->before.start.y;
+
+       event->after.start.x = x;
+       event->after.start.y = y;
+       event->after.end.x = x;
+       event->after.end.y = y;
+
+       /* Save the content that will be removed. */
+       fragment = webkit_dom_range_clone_contents (range_clone, NULL);
+
+       /* Extend the cloned range to point one character after
+        * the selection ends to later check if there is a whitespace
+        * after it. */
+       webkit_dom_range_set_end (
+               range_clone,
+               webkit_dom_range_get_end_container (range_clone, NULL),
+               webkit_dom_range_get_end_offset (range_clone, NULL) + 1,
+               NULL);
+       range_text = webkit_dom_range_get_text (range_clone);
+
+       /* Check if the current selection starts on the beginning of line. */
+       webkit_dom_dom_selection_modify (
+               dom_selection, "extend", "left", "lineboundary");
+       beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       start_to_start = webkit_dom_range_compare_boundary_points (
+               beginning_of_line, WEBKIT_DOM_RANGE_START_TO_START, range, NULL) == 0;
+
+       /* Restore the selection to state before the check. */
+       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+       webkit_dom_dom_selection_add_range (dom_selection, range);
+       g_clear_object (&beginning_of_line);
+
+       /* Check if the current selection end on the end of the line. */
+       webkit_dom_dom_selection_modify (
+               dom_selection, "extend", "right", "lineboundary");
+       beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+       end_to_end = webkit_dom_range_compare_boundary_points (
+               beginning_of_line, WEBKIT_DOM_RANGE_END_TO_END, range, NULL) == 0;
+
+       /* Dragging the whole line. */
+       if (start_to_start && end_to_end) {
+               WebKitDOMNode *container, *actual_block, *tmp_block;
+
+               /* Select the whole line (to the beginning of the next
+                * one so we can reuse the undo code while undoing this.
+                * Because of this we need to special mark the event
+                * with history-drag-and-drop to correct the selection
+                * after undoing it (otherwise the beginning of the next
+                * line will be selected as well. */
+               webkit_dom_dom_selection_modify (
+                       dom_selection, "extend", "right", "character");
+               g_clear_object (&beginning_of_line);
+               beginning_of_line = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+
+               container = webkit_dom_range_get_end_container (range, NULL);
+               actual_block = e_editor_dom_get_parent_block_node_from_child (container);
+
+               tmp_block = webkit_dom_range_get_end_container (beginning_of_line, NULL);
+               if ((tmp_block = e_editor_dom_get_parent_block_node_from_child (tmp_block))) {
+                       e_editor_dom_selection_get_coordinates (editor_page,
+                               &event->before.start.x,
+                               &event->before.start.y,
+                               &event->before.end.x,
+                               &event->before.end.y);
+
+                       /* Create the right content for the history event. */
+                       fragment = webkit_dom_document_create_document_fragment (document);
+                       /* The removed line. */
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (fragment),
+                               webkit_dom_node_clone_node_with_error (actual_block, TRUE, NULL),
+                               NULL);
+                       /* The following block, but empty. */
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (fragment),
+                               webkit_dom_node_clone_node_with_error (tmp_block, FALSE, NULL),
+                               NULL);
+                       g_object_set_data (
+                               G_OBJECT (fragment),
+                               "history-drag-and-drop",
+                               GINT_TO_POINTER (1));
+               }
+       }
+       /* It should act as a Delete key press. */
+       g_object_set_data (G_OBJECT (fragment), "history-delete-key", GINT_TO_POINTER (1));
+
+       event->data.fragment = fragment;
+       e_editor_undo_redo_manager_insert_history_event (manager, event);
+
+       /* Selection is ending on the end of the line, check if
+        * there is a space before the selection start. If so, it
+        * will be removed and we need create the history event
+        * for it. */
+       if (end_to_end) {
+               gchar *range_text_start;
+               glong start_offset;
+
+               start_offset = webkit_dom_range_get_start_offset (range_clone, NULL);
+               webkit_dom_range_set_start (
+                       range_clone,
+                       webkit_dom_range_get_start_container (range_clone, NULL),
+                       start_offset > 0 ? start_offset - 1 : 0,
+                       NULL);
+
+               range_text_start = webkit_dom_range_get_text (range_clone);
+               if (g_str_has_prefix (range_text_start, " ") ||
+                   g_str_has_prefix (range_text_start, UNICODE_NBSP))
+                       insert_nbsp_history_event (document, manager, FALSE, x, y);
+
+               g_free (range_text_start);
+       }
+
+       /* WebKit removes the space (if presented) after selection and
+        * we need to create a new history event for it. */
+       if (g_str_has_suffix (range_text, " ") ||
+           g_str_has_suffix (range_text, UNICODE_NBSP))
+               insert_nbsp_history_event (document, manager, TRUE, x, y);
+
+       g_free (range_text);
+
+       /* Restore the selection to original state. */
+       webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+       webkit_dom_dom_selection_add_range (dom_selection, range);
+       g_clear_object (&beginning_of_line);
+
+       /* All the things above were about removing the content,
+        * create an AND event to continue later with inserting
+        * the dropped content. */
+       event = g_new0 (EEditorHistoryEvent, 1);
+       event->type = HISTORY_AND;
+       e_editor_undo_redo_manager_insert_history_event (manager, event);
+
+       g_clear_object (&dom_selection);
+
+       g_clear_object (&range);
+       g_clear_object (&range_clone);
+}
+
 void
 e_editor_dom_save_history_for_drop (EEditorPage *editor_page)
 {
@@ -10888,14 +11202,6 @@ e_editor_dom_save_history_for_drop (EEditorPage *editor_page)
 
        range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
 
-       /* Remove the last inserted history event as this one was inserted in
-        * body_input_event_cb and is wrong as its type is HISTORY_INPUT. */
-       /* FIXME we could probably disable the HTML input event callback while
-        * doing DnD within the view */
-       event = e_editor_undo_redo_manager_get_current_history_event (manager);
-       if (event && event->type == HISTORY_INPUT)
-               e_editor_undo_redo_manager_remove_current_history_event (manager);
-
        event = g_new0 (EEditorHistoryEvent, 1);
        event->type = HISTORY_INSERT_HTML;
 
@@ -10905,28 +11211,8 @@ e_editor_dom_save_history_for_drop (EEditorPage *editor_page)
        /* Get the HTML content of the dropped content. */
        event->data.string.to = dom_get_node_inner_html (WEBKIT_DOM_NODE (fragment));
 
-       e_editor_dom_selection_get_coordinates (editor_page,
-               &event->before.start.x,
-               &event->before.start.y,
-               &event->before.end.x,
-               &event->before.end.y);
-
-       event->before.end.x = event->before.start.x;
-       event->before.end.y = event->before.start.y;
-
-       if (length > 0)
-               webkit_dom_dom_selection_collapse_to_start (dom_selection, NULL);
-       else
-               webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL);
-
-       e_editor_dom_selection_get_coordinates (editor_page,
-               &event->after.start.x,
-               &event->after.start.y,
-               &event->after.end.x,
-               &event->after.end.y);
-
        e_editor_undo_redo_manager_insert_history_event (manager, event);
-
+#if 0 /* FIXME Not exactly sure if it is still needed */
        if (!e_editor_page_get_html_mode (editor_page)) {
                list = webkit_dom_document_query_selector_all (
                        document, "span[style^=font-family]", NULL);
@@ -10952,21 +11238,12 @@ e_editor_dom_save_history_for_drop (EEditorPage *editor_page)
                if (length > 0)
                        e_editor_dom_selection_restore (editor_page);
        }
-
-       e_editor_dom_force_spell_check_in_viewport (editor_page);
+#endif
 
        g_clear_object (&range);
        g_clear_object (&dom_selection);
 }
 
-void
-e_editor_dom_drag_and_drop_end (EEditorPage *editor_page)
-{
-       g_return_if_fail (E_IS_EDITOR_PAGE (editor_page));
-
-       e_editor_dom_save_history_for_drop (editor_page);
-}
-
 static void
 dom_set_link_color_in_document (EEditorPage *editor_page,
                                 const gchar *color,
diff --git a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h 
b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
index 518a409..3cb2085 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
+++ b/src/modules/webkit-editor/web-extension/e-editor-dom-functions.h
@@ -158,7 +158,6 @@ void                e_editor_dom_process_content_after_mode_change
                                                (EEditorPage *editor_page);
 guint          e_editor_dom_get_caret_offset   (EEditorPage *editor_page);
 guint          e_editor_dom_get_caret_position (EEditorPage *editor_page);
-void           e_editor_dom_drag_and_drop_end  (EEditorPage *editor_page);
 void           e_editor_dom_set_link_color     (EEditorPage *editor_page,
                                                 const gchar *color);
 void           e_editor_dom_set_visited_link_color
@@ -208,6 +207,8 @@ WebKitDOMElement *
                                                 WebKitDOMElement *element);
 gint           e_editor_dom_get_citation_level (WebKitDOMNode *node,
                                                 gboolean set_plaintext_quoted);
+void           e_editor_dom_save_history_for_drag
+                                               (EEditorPage *editor_page);
 void           e_editor_dom_save_history_for_drop
                                                (EEditorPage *editor_page);
 void           e_editor_dom_fix_file_uri_images
diff --git a/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c 
b/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
index 51d1c8b..5420ca1 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-undo-redo-manager.c
@@ -1571,7 +1571,9 @@ undo_redo_paste (EEditorPage *editor_page,
                                NULL);
 
                        e_editor_dom_selection_restore (editor_page);
-               } else {
+               } else if (event->after.start.x == event->after.end.x &&
+                          event->after.start.y == event->after.end.y) {
+                       /* Selection was collapsed after the event */
                        WebKitDOMDOMWindow *dom_window = NULL;
                        WebKitDOMDOMSelection *dom_selection = NULL;
                        WebKitDOMElement *element, *tmp;
@@ -1620,6 +1622,12 @@ undo_redo_paste (EEditorPage *editor_page,
                        e_editor_dom_exec_command (editor_page, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
 
                        e_editor_dom_force_spell_check_for_current_paragraph (editor_page);
+               } else {
+                       restore_selection_to_history_event_state (editor_page, event->after);
+
+                       e_editor_dom_exec_command (editor_page, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
+
+                       e_editor_dom_force_spell_check_for_current_paragraph (editor_page);
                }
        } else {
                restore_selection_to_history_event_state (editor_page, event->before);
@@ -1633,6 +1641,8 @@ undo_redo_paste (EEditorPage *editor_page,
                else
                        e_editor_dom_convert_and_insert_html_into_selection (editor_page, 
event->data.string.to, FALSE);
                        /* e_editor_selection_insert_as_text (selection, event->data.string.to); */
+
+               restore_selection_to_history_event_state (editor_page, event->after);
        }
 }
 
diff --git a/src/modules/webkit-editor/web-extension/e-editor-web-extension.c 
b/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
index 15db265..bdb4274 100644
--- a/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
+++ b/src/modules/webkit-editor/web-extension/e-editor-web-extension.c
@@ -478,9 +478,6 @@ static const gchar *introspection_xml =
 "      <arg type='s' name='selector' direction='in'/>"
 "      <arg type='s' name='uri' direction='in'/>"
 "    </method>"
-"    <method name='DOMDragAndDropEnd'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"    </method>"
 "    <method name='DOMMoveSelectionOnPoint'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='i' name='x' direction='in'/>"
@@ -579,12 +576,6 @@ static const gchar *introspection_xml =
 "      <arg type='b' name='out_check_if_signature_is_changed' direction='out'/>"
 "      <arg type='b' name='out_ignore_next_signature_change' direction='out'/>"
 "    </method>"
-"    <method name='DOMSaveDragAndDropHistory'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"    </method>"
-"    <method name='DOMCleanAfterDragAndDrop'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"    </method>"
 "    <method name='DOMGetActiveSignatureUid'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='uid' direction='out'/>"
@@ -1857,15 +1848,6 @@ handle_method_call (GDBusConnection *connection,
                e_editor_dom_replace_image_src (editor_page, selector, uri);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMDragAndDropEnd") == 0) {
-               g_variant_get (parameters, "(t)", &page_id);
-
-               editor_page = get_editor_page_or_return_dbus_error (invocation, extension, page_id);
-               if (!editor_page)
-                       goto error;
-
-               e_editor_dom_drag_and_drop_end (editor_page);
-               g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMInsertSmiley") == 0) {
                const gchar *smiley_name;
 
@@ -2153,28 +2135,6 @@ handle_method_call (GDBusConnection *connection,
                                ignore_next_signature_change));
 
                g_free (new_signature_id);
-       } else if (g_strcmp0 (method_name, "DOMSaveDragAndDropHistory") == 0) {
-               g_variant_get (
-                       parameters, "(t)", &page_id);
-
-               editor_page = get_editor_page_or_return_dbus_error (invocation, extension, page_id);
-               if (!editor_page)
-                       goto error;
-
-               e_composer_dom_save_drag_and_drop_history (editor_page);
-
-               g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMCleanAfterDragAndDrop") == 0) {
-               g_variant_get (
-                       parameters, "(t)", &page_id);
-
-               editor_page = get_editor_page_or_return_dbus_error (invocation, extension, page_id);
-               if (!editor_page)
-                       goto error;
-
-               e_composer_dom_clean_after_drag_and_drop (editor_page);
-
-               g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMGetActiveSignatureUid") == 0) {
                gchar *value;
 


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