[evolution/wip/webkit2] Composer - Undo/Redo on operations with selection could be wrong



commit d80f932d0211d0ec94b86937eaab642f150fda7e
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Feb 25 12:55:26 2016 +0100

    Composer - Undo/Redo on operations with selection could be wrong

 .../composer/e-html-editor-history-event.h         |    1 +
 .../e-html-editor-selection-dom-functions.c        |   36 +++++-
 .../composer/e-html-editor-undo-redo-manager.c     |   42 +++++-
 .../composer/e-html-editor-view-dom-functions.c    |  136 ++++++++++++++++++--
 4 files changed, 195 insertions(+), 20 deletions(-)
---
diff --git a/web-extensions/composer/e-html-editor-history-event.h 
b/web-extensions/composer/e-html-editor-history-event.h
index 7aed032..1a689c8 100644
--- a/web-extensions/composer/e-html-editor-history-event.h
+++ b/web-extensions/composer/e-html-editor-history-event.h
@@ -25,6 +25,7 @@ G_BEGIN_DECLS
 
 enum EHTMLEditorHistoryEventType {
        HISTORY_ALIGNMENT,
+       HISTORY_AND,
        HISTORY_BLOCK_FORMAT,
        HISTORY_BLOCKQUOTE,
        HISTORY_BOLD,
diff --git a/web-extensions/composer/e-html-editor-selection-dom-functions.c 
b/web-extensions/composer/e-html-editor-selection-dom-functions.c
index 651726a..393be92 100644
--- a/web-extensions/composer/e-html-editor-selection-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-selection-dom-functions.c
@@ -153,14 +153,46 @@ dom_insert_base64_image (WebKitDOMDocument *document,
        WebKitDOMElement *element, *selection_start_marker, *resizable_wrapper;
        WebKitDOMText *text;
 
-       if (!dom_selection_is_collapsed (document))
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+
+       if (!dom_selection_is_collapsed (document)) {
+               EHTMLEditorHistoryEvent *ev;
+               WebKitDOMDocumentFragment *fragment;
+               WebKitDOMRange *range;
+
+               ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+               ev->type = HISTORY_DELETE;
+
+               range = dom_get_current_range (document);
+               fragment = webkit_dom_range_clone_contents (range, NULL);
+               g_object_unref (range);
+               ev->data.fragment = fragment;
+
+               dom_selection_get_coordinates (
+                       document,
+                       &ev->before.start.x,
+                       &ev->before.start.y,
+                       &ev->before.end.x,
+                       &ev->before.end.y);
+
+               ev->after.start.x = ev->before.start.x;
+               ev->after.start.y = ev->before.start.y;
+               ev->after.end.x = ev->before.start.x;
+               ev->after.end.y = ev->before.start.y;
+
+               e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+
+               ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+               ev->type = HISTORY_AND;
+
+               e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
                dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+       }
 
        dom_selection_save (document);
        selection_start_marker = webkit_dom_document_query_selector (
                document, "span#-x-evo-selection-start-marker", NULL);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_IMAGE;
diff --git a/web-extensions/composer/e-html-editor-undo-redo-manager.c 
b/web-extensions/composer/e-html-editor-undo-redo-manager.c
index a790d45..fe87936 100644
--- a/web-extensions/composer/e-html-editor-undo-redo-manager.c
+++ b/web-extensions/composer/e-html-editor-undo-redo-manager.c
@@ -256,6 +256,9 @@ print_history_event (EHTMLEditorHistoryEvent *event)
                case HISTORY_START:
                        printf ("HISTORY START\n");
                        break;
+               case HISTORY_AND:
+                       printf ("HISTORY AND\n");
+                       break;
                default:
                        printf ("Unknown history type\n");
        }
@@ -317,6 +320,12 @@ print_redo_events (EHTMLEditorUndoRedoManager *manager)
 }
 #endif
 
+static gboolean
+event_selection_was_collapsed (EHTMLEditorHistoryEvent *ev)
+{
+       return (ev->before.start.x == ev->before.end.x) && (ev->before.start.y == ev->before.end.y);
+}
+
 static void
 undo_delete (WebKitDOMDocument *document,
              EHTMLEditorWebExtension *extension,
@@ -511,12 +520,6 @@ undo_delete (WebKitDOMDocument *document,
        g_object_unref (dom_selection);
 }
 
-static gboolean
-event_selection_was_collapsed (EHTMLEditorHistoryEvent *ev)
-{
-       return (ev->before.start.x == ev->before.end.x) && (ev->before.start.y == ev->before.end.y);
-}
-
 static void
 redo_delete (WebKitDOMDocument *document,
              EHTMLEditorWebExtension *extension,
@@ -1722,7 +1725,7 @@ e_html_editor_undo_redo_manager_insert_dash_history_event (EHTMLEditorUndoRedoMa
 
                                diff = event->after.start.x - item->after.start.x;
 
-                               /* We need to move the coordinater of the last
+                               /* We need to move the coordinate of the last
                                 * event by one character. */
                                last->after.start.x += diff;
                                last->after.end.x += diff;
@@ -1852,11 +1855,22 @@ e_html_editor_undo_redo_manager_undo (EHTMLEditorUndoRedoManager *manager)
                case HISTORY_UNQUOTE:
                        undo_redo_unquote (document, extension, event, TRUE);
                        break;
+               case HISTORY_AND:
+                       g_warning ("Unhandled HISTORY_AND event!");
+                       break;
                default:
                        g_object_unref (extension);
                        return;
        }
 
+       /* FIXME WK2 - history->next can be NULL! */
+       event = history->next->data;
+       if (event->type == HISTORY_AND) {
+               manager->priv->history = history->next->next;
+               e_html_editor_undo_redo_manager_undo (manager);
+               return;
+       }
+
        if (history->next)
                manager->priv->history = manager->priv->history->next;
 
@@ -1921,6 +1935,7 @@ e_html_editor_undo_redo_manager_redo (EHTMLEditorUndoRedoManager *manager)
                        break;
                case HISTORY_INPUT:
                        undo_delete (document, extension, event);
+                       dom_check_magic_smileys (document, extension);
                        break;
                case HISTORY_REMOVE_LINK:
                        undo_redo_remove_link (document, extension, event, FALSE);
@@ -1969,11 +1984,24 @@ e_html_editor_undo_redo_manager_redo (EHTMLEditorUndoRedoManager *manager)
                case HISTORY_UNQUOTE:
                        undo_redo_unquote (document, extension, event, FALSE);
                        break;
+               case HISTORY_AND:
+                       g_warning ("Unhandled HISTORY_AND event!");
+                       break;
                default:
                        g_object_unref (extension);
                        return;
        }
 
+       /* FIXME WK2 - what if history->prev is NULL? */
+       if (history->prev->prev) {
+               event = history->prev->prev->data;
+               if (event->type == HISTORY_AND) {
+                       manager->priv->history = manager->priv->history->prev->prev;
+                       e_html_editor_undo_redo_manager_redo (manager);
+                       return;
+               }
+       }
+
        manager->priv->history = manager->priv->history->prev;
 
        d (print_history (manager));
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.c 
b/web-extensions/composer/e-html-editor-view-dom-functions.c
index de2519b..bf0f887 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.c
@@ -1115,6 +1115,46 @@ dom_remove_embed_style_sheet (WebKitDOMDocument *document)
        remove_node (WEBKIT_DOM_NODE (sheet));
 }
 
+static void
+insert_delete_event (WebKitDOMDocument *document,
+                    EHTMLEditorWebExtension *extension,
+                     WebKitDOMRange *range)
+{
+       EHTMLEditorHistoryEvent *ev;
+       WebKitDOMDocumentFragment *fragment;
+       EHTMLEditorUndoRedoManager *manager;
+
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+
+       if (e_html_editor_undo_redo_manager_is_operation_in_progress (manager))
+               return;
+
+       ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+       ev->type = HISTORY_DELETE;
+
+       fragment = webkit_dom_range_clone_contents (range, NULL);
+       ev->data.fragment = fragment;
+
+       dom_selection_get_coordinates (
+               document,
+               &ev->before.start.x,
+               &ev->before.start.y,
+               &ev->before.end.x,
+               &ev->before.end.y);
+
+       ev->after.start.x = ev->before.start.x;
+       ev->after.start.y = ev->before.start.y;
+       ev->after.end.x = ev->before.start.x;
+       ev->after.end.y = ev->before.start.y;
+
+       e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+
+       ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+       ev->type = HISTORY_AND;
+
+       e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+}
+
 /* Based on original use_pictograms() from GtkHTML */
 static const gchar *emoticons_chars =
        /*  0 */ "DO)(|/PQ*!"
@@ -1233,6 +1273,14 @@ emoticon_insert_span (EEmoticon *emoticon,
                        }
                }
        } else {
+               WebKitDOMRange *tmp_range;
+
+               tmp_range = dom_get_current_range (document);
+               insert_delete_event (document, extension, tmp_range);
+               g_object_unref (tmp_range);
+
+               dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+
                if (!smiley_written) {
                        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
@@ -1247,8 +1295,6 @@ emoticon_insert_span (EEmoticon *emoticon,
                        }
                }
 
-               dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
-
                dom_selection_save (document);
 
                selection_start_marker = webkit_dom_document_get_element_by_id (
@@ -1871,17 +1917,19 @@ body_keypress_event_cb (WebKitDOMElement *element,
                return;
        }
 
-       if (!webkit_dom_range_get_collapsed (range, NULL)) {
+       if (!webkit_dom_range_get_collapsed (range, NULL))
+               insert_delete_event (document, extension, range);
+
+       if (e_html_editor_web_extension_get_return_key_pressed (extension)) {
                EHTMLEditorHistoryEvent *ev;
                EHTMLEditorUndoRedoManager *manager;
-               WebKitDOMDocumentFragment *fragment;
 
+               /* Insert new hiisvent for Return to have the right coordinates.
+                * The fragment will be added later. */
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
-               ev->type = HISTORY_DELETE;
+               ev->type = HISTORY_INPUT;
 
                manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
-               fragment = webkit_dom_range_clone_contents (range, NULL);
-               ev->data.fragment = fragment;
 
                dom_selection_get_coordinates (
                        document,
@@ -1965,6 +2013,8 @@ save_history_for_input (WebKitDOMDocument *document,
        WebKitDOMRange *range, *range_clone;
        WebKitDOMNode *start_container;
 
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+
        dom_window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
        g_object_unref (dom_window);
@@ -1974,8 +2024,16 @@ save_history_for_input (WebKitDOMDocument *document,
                return;
        }
 
-       ev = g_new0 (EHTMLEditorHistoryEvent, 1);
-       ev->type = HISTORY_INPUT;
+       if (e_html_editor_web_extension_get_return_key_pressed (extension)) {
+               ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
+               if (ev->type != HISTORY_INPUT) {
+                       g_object_unref (dom_selection);
+                       return;
+               }
+       } else {
+               ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+               ev->type = HISTORY_INPUT;
+       }
 
        e_html_editor_web_extension_block_selection_changed_callback (extension);
 
@@ -2080,8 +2138,8 @@ save_history_for_input (WebKitDOMDocument *document,
 
        ev->data.fragment = fragment;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
-       e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+       if (!e_html_editor_web_extension_get_return_key_pressed (extension))
+               e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
 }
 
 typedef struct _TimeoutContext TimeoutContext;
@@ -4708,11 +4766,14 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
 
        manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
+               gboolean collapsed;
+
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_PASTE;
 /* FIXME WK2
                ev->type = HISTORY_PASTE_AS_TEXT;*/
 
+               collapsed = dom_selection_is_collapsed (document);
                dom_selection_get_coordinates (
                        document,
                        &ev->before.start.x,
@@ -4720,6 +4781,11 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
                        &ev->before.end.x,
                        &ev->before.end.y);
 
+               if (!collapsed) {
+                       ev->before.end.x = ev->before.start.x;
+                       ev->before.end.y = ev->before.start.y;
+               }
+
                ev->data.string.from = NULL;
                ev->data.string.to = g_strdup (html);
        }
@@ -4745,6 +4811,13 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
        g_free (inner_html);
 
        has_selection = !dom_selection_is_collapsed (document);
+       if (has_selection) {
+               WebKitDOMRange *range;
+
+               range = dom_get_current_range (document);
+               insert_delete_event (document, extension, range);
+               g_object_unref (range);
+       }
 
        citation_level = get_citation_level (WEBKIT_DOM_NODE (selection_end_marker), FALSE);
        /* Pasting into the citation */
@@ -7007,9 +7080,12 @@ dom_insert_html (WebKitDOMDocument *document,
 
        manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
+               gboolean collapsed;
+
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_INSERT_HTML;
 
+               collapsed = dom_selection_is_collapsed (document);
                dom_selection_get_coordinates (
                        document,
                        &ev->before.start.x,
@@ -7017,11 +7093,49 @@ dom_insert_html (WebKitDOMDocument *document,
                        &ev->before.end.x,
                        &ev->before.end.y);
 
+               if (!collapsed) {
+                       ev->before.end.x = ev->before.start.x;
+                       ev->before.end.y = ev->before.start.y;
+               }
+
                ev->data.string.from = NULL;
                ev->data.string.to = g_strdup (html_text);
        }
 
        if (e_html_editor_web_extension_get_html_mode (extension)) {
+               if (!dom_selection_is_collapsed (document)) {
+                       EHTMLEditorHistoryEvent *ev;
+                       WebKitDOMDocumentFragment *fragment;
+                       WebKitDOMRange *range;
+
+                       ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+                       ev->type = HISTORY_DELETE;
+
+                       range = dom_get_current_range (document);
+                       fragment = webkit_dom_range_clone_contents (range, NULL);
+                       g_object_unref (range);
+                       ev->data.fragment = fragment;
+
+                       dom_selection_get_coordinates (
+                               document,
+                               &ev->before.start.x,
+                               &ev->before.start.y,
+                               &ev->before.end.x,
+                               &ev->before.end.y);
+
+                       ev->after.start.x = ev->before.start.x;
+                       ev->after.start.y = ev->before.start.y;
+                       ev->after.end.x = ev->before.start.x;
+                       ev->after.end.y = ev->before.start.y;
+
+                       e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+
+                       ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+                       ev->type = HISTORY_AND;
+
+                       e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+               }
+
                dom_exec_command (
                        document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html_text);
                if (strstr (html_text, "id=\"-x-evo-selection-start-marker\""))


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