[evolution/wip/webkit2] Enable Undo/Redo for the WebKit editor



commit b208beefa773d2ea4c97bcf5a8dc1f532d029f05
Author: Milan Crha <mcrha redhat com>
Date:   Fri Jun 24 16:01:28 2016 +0200

    Enable Undo/Redo for the WebKit editor

 modules/webkit-editor/e-webkit-editor.c            |   75 ++++++++
 .../e-composer-private-dom-functions.c             |    2 +-
 .../e-html-editor-actions-dom-functions.c          |    4 +-
 .../e-html-editor-cell-dialog-dom-functions.c      |    4 +-
 .../e-html-editor-hrule-dialog-dom-functions.c     |    4 +-
 .../e-html-editor-image-dialog-dom-functions.c     |    4 +-
 .../e-html-editor-page-dialog-dom-functions.c      |    4 +-
 .../e-html-editor-selection-dom-functions.c        |   24 ++--
 .../e-html-editor-table-dialog-dom-functions.c     |    4 +-
 .../e-html-editor-undo-redo-manager.c              |   28 ++--
 .../e-html-editor-undo-redo-manager.h              |    5 +
 .../e-html-editor-view-dom-functions.c             |   44 +++---
 .../web-extension/e-html-editor-web-extension.c    |  186 ++++++++++++++++++--
 .../web-extension/e-html-editor-web-extension.h    |   11 +-
 14 files changed, 321 insertions(+), 78 deletions(-)
---
diff --git a/modules/webkit-editor/e-webkit-editor.c b/modules/webkit-editor/e-webkit-editor.c
index e640054..dcb8fd3 100644
--- a/modules/webkit-editor/e-webkit-editor.c
+++ b/modules/webkit-editor/e-webkit-editor.c
@@ -69,6 +69,7 @@ struct _EWebKitEditorPrivate {
        guint web_extension_watch_name_id;
        guint web_extension_selection_changed_cb_id;
        guint web_extension_content_changed_cb_id;
+       guint web_extension_undo_redo_state_changed_cb_id;
 
        gboolean html_mode;
        gboolean changed;
@@ -258,6 +259,34 @@ webkit_editor_set_changed (EWebKitEditor *wk_editor,
 }
 
 static void
+webkit_editor_set_can_undo (EWebKitEditor *wk_editor,
+                           gboolean can_undo)
+{
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+
+       if ((wk_editor->priv->can_undo ? 1 : 0) == (can_undo ? 1 : 0))
+               return;
+
+       wk_editor->priv->can_undo = can_undo;
+
+       g_object_notify (G_OBJECT (wk_editor), "can-undo");
+}
+
+static void
+webkit_editor_set_can_redo (EWebKitEditor *wk_editor,
+                           gboolean can_redo)
+{
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
+
+       if ((wk_editor->priv->can_redo ? 1 : 0) == (can_redo ? 1 : 0))
+               return;
+
+       wk_editor->priv->can_redo = can_redo;
+
+       g_object_notify (G_OBJECT (wk_editor), "can-redo");
+}
+
+static void
 web_extension_content_changed_cb (GDBusConnection *connection,
                                   const gchar *sender_name,
                                   const gchar *object_path,
@@ -363,6 +392,29 @@ web_extension_selection_changed_cb (GDBusConnection *connection,
 }
 
 static void
+web_extension_undo_redo_state_changed_cb (GDBusConnection *connection,
+                                         const gchar *sender_name,
+                                         const gchar *object_path,
+                                         const gchar *interface_name,
+                                         const gchar *signal_name,
+                                         GVariant *parameters,
+                                         EWebKitEditor *wk_editor)
+{
+       guint64 page_id = 0;
+       gboolean can_undo = FALSE, can_redo = FALSE;
+
+       if (g_strcmp0 (signal_name, "UndoRedoStateChanged") != 0)
+               return;
+
+       g_variant_get (parameters, "(tbb)", &page_id, &can_undo, &can_redo);
+
+       if (page_id == webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (wk_editor))) {
+               webkit_editor_set_can_undo (wk_editor, can_undo);
+               webkit_editor_set_can_redo (wk_editor, can_redo);
+       }
+}
+
+static void
 dispatch_pending_operations (EWebKitEditor *wk_editor)
 {
        if (!wk_editor->priv->web_extension)
@@ -441,6 +493,21 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
                                NULL);
        }
 
+       if (wk_editor->priv->web_extension_undo_redo_state_changed_cb_id == 0) {
+               wk_editor->priv->web_extension_undo_redo_state_changed_cb_id =
+                       g_dbus_connection_signal_subscribe (
+                               g_dbus_proxy_get_connection (wk_editor->priv->web_extension),
+                               g_dbus_proxy_get_name (wk_editor->priv->web_extension),
+                               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+                               "UndoRedoStateChanged",
+                               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+                               NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE,
+                               (GDBusSignalCallback) web_extension_undo_redo_state_changed_cb,
+                               wk_editor,
+                               NULL);
+       }
+
        dispatch_pending_operations (wk_editor);
 
        if (wk_editor->priv->emit_load_finished_when_extension_is_ready) {
@@ -5021,6 +5088,13 @@ webkit_editor_dispose (GObject *object)
                priv->web_extension_selection_changed_cb_id = 0;
        }
 
+       if (priv->web_extension_undo_redo_state_changed_cb_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_undo_redo_state_changed_cb_id);
+               priv->web_extension_undo_redo_state_changed_cb_id = 0;
+       }
+
        if (priv->web_extension_watch_name_id > 0) {
                g_bus_unwatch_name (priv->web_extension_watch_name_id);
                priv->web_extension_watch_name_id = 0;
@@ -5908,6 +5982,7 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
 
        wk_editor->priv->web_extension_selection_changed_cb_id = 0;
        wk_editor->priv->web_extension_content_changed_cb_id = 0;
+       wk_editor->priv->web_extension_undo_redo_state_changed_cb_id = 0;
 }
 
 static void
diff --git a/modules/webkit-editor/web-extension/e-composer-private-dom-functions.c 
b/modules/webkit-editor/web-extension/e-composer-private-dom-functions.c
index 1dabd2e..147840f 100644
--- a/modules/webkit-editor/web-extension/e-composer-private-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-composer-private-dom-functions.c
@@ -650,7 +650,7 @@ dom_save_drag_and_drop_history (WebKitDOMDocument *document,
        WebKitDOMRange *beginning_of_line = NULL;
        WebKitDOMRange *range = NULL, *range_clone = NULL;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!(dom_window = webkit_dom_document_get_default_view (document)))
                return;
diff --git a/modules/webkit-editor/web-extension/e-html-editor-actions-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-actions-dom-functions.c
index 29a25af..ddbcf00 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-actions-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-actions-dom-functions.c
@@ -71,7 +71,7 @@ save_history_for_table (WebKitDOMDocument *document,
        dom_selection_get_coordinates (
                document, &ev->after.start.x, &ev->after.start.y, &ev->after.end.x, &ev->after.end.y);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
 }
 
@@ -411,6 +411,6 @@ dom_save_history_for_cut (WebKitDOMDocument *document,
        g_object_unref (dom_selection);
        ev->data.fragment = g_object_ref (fragment);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
 }
diff --git a/modules/webkit-editor/web-extension/e-html-editor-cell-dialog-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-cell-dialog-dom-functions.c
index 5928469..0a4f31f 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-cell-dialog-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-cell-dialog-dom-functions.c
@@ -247,7 +247,7 @@ e_html_editor_cell_dialog_mark_current_cell_element (WebKitDOMDocument *document
        if (element)
                webkit_dom_element_remove_attribute (element, "id");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
                WebKitDOMElement *table;
@@ -289,7 +289,7 @@ e_html_editor_cell_dialog_save_history_on_exit (WebKitDOMDocument *document,
 
        webkit_dom_element_remove_attribute (cell, "id");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
        ev->data.dom.to = webkit_dom_node_clone_node_with_error (
                WEBKIT_DOM_NODE (table), TRUE, NULL);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-hrule-dialog-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-hrule-dialog-dom-functions.c
index b711864..a92372a 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-hrule-dialog-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-hrule-dialog-dom-functions.c
@@ -76,7 +76,7 @@ e_html_editor_hrule_dialog_find_hrule (WebKitDOMDocument *document,
                created = TRUE;
        }
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
 
@@ -110,7 +110,7 @@ e_html_editor_hrule_dialog_save_history_on_exit (WebKitDOMDocument *document,
 
        webkit_dom_element_remove_attribute (element, "id");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
        ev->data.dom.to = webkit_dom_node_clone_node_with_error (
                WEBKIT_DOM_NODE (element), TRUE, NULL);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-image-dialog-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-image-dialog-dom-functions.c
index f5d16b9..4af3806 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-image-dialog-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-image-dialog-dom-functions.c
@@ -45,7 +45,7 @@ e_html_editor_image_dialog_mark_image (WebKitDOMDocument *document,
 
        webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (node_under_mouse_click), "-x-evo-current-img");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
 
@@ -73,7 +73,7 @@ e_html_editor_image_dialog_save_history_on_exit (WebKitDOMDocument *document,
 
        webkit_dom_element_remove_attribute (element, "id");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
        ev->data.dom.to = webkit_dom_node_clone_node_with_error (
                WEBKIT_DOM_NODE (element), TRUE, NULL);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-page-dialog-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-page-dialog-dom-functions.c
index b234743..7d01482 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-page-dialog-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-page-dialog-dom-functions.c
@@ -33,7 +33,7 @@ e_html_editor_page_dialog_save_history (WebKitDOMDocument *document,
 {
        EHTMLEditorUndoRedoManager *manager;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
                WebKitDOMHTMLElement *body;
@@ -58,7 +58,7 @@ e_html_editor_page_dialog_save_history_on_exit (WebKitDOMDocument *document,
        EHTMLEditorUndoRedoManager *manager;
        WebKitDOMHTMLElement *body;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
        body = webkit_dom_document_get_body (document);
        ev->data.dom.to = webkit_dom_node_clone_node_with_error (WEBKIT_DOM_NODE (body), FALSE, NULL);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-selection-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-selection-dom-functions.c
index e49b881..0d304bb 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-selection-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-selection-dom-functions.c
@@ -157,7 +157,7 @@ dom_insert_base64_image (WebKitDOMDocument *document,
        WebKitDOMElement *element, *selection_start_marker, *resizable_wrapper;
        WebKitDOMText *text;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!dom_selection_is_collapsed (document)) {
                EHTMLEditorHistoryEvent *ev;
@@ -638,7 +638,7 @@ dom_selection_unlink (WebKitDOMDocument *document,
        if (!link)
                return;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
                WebKitDOMDocumentFragment *fragment;
@@ -1300,7 +1300,7 @@ dom_selection_indent (WebKitDOMDocument *document,
 
        dom_selection_save (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        selection_start_marker = webkit_dom_document_query_selector (
                document, "span#-x-evo-selection-start-marker", NULL);
@@ -1657,7 +1657,7 @@ dom_selection_unindent (WebKitDOMDocument *document,
                        &selection_end_marker);
        }
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_INDENT;
@@ -3367,7 +3367,7 @@ dom_selection_wrap (WebKitDOMDocument *document,
                        &selection_end_marker);
        }
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_WRAP;
@@ -3917,7 +3917,7 @@ selection_set_font_style (WebKitDOMDocument *document,
 
        dom_selection_save (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                if (command == E_CONTENT_EDITOR_COMMAND_BOLD)
@@ -4573,7 +4573,7 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
        if (!range)
                return;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_MONOSPACE;
@@ -4991,7 +4991,7 @@ dom_selection_set_font_size (WebKitDOMDocument *document,
 
        dom_selection_save (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_FONT_SIZE;
@@ -5119,7 +5119,7 @@ dom_selection_set_font_color (WebKitDOMDocument *document,
        EHTMLEditorUndoRedoManager *manager;
        EHTMLEditorHistoryEvent *ev = NULL;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_FONT_COLOR;
@@ -6075,7 +6075,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
 
        dom_selection_save (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_BLOCK_FORMAT;
@@ -6322,7 +6322,7 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
        if (!selection_start_marker)
                return;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_ALIGNMENT;
@@ -6408,7 +6408,7 @@ dom_selection_replace (WebKitDOMDocument *document,
        EHTMLEditorHistoryEvent *ev = NULL;
        EHTMLEditorUndoRedoManager *manager;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                WebKitDOMDOMWindow *dom_window;
diff --git a/modules/webkit-editor/web-extension/e-html-editor-table-dialog-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-table-dialog-dom-functions.c
index 4e0509f..70ab799 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-table-dialog-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-table-dialog-dom-functions.c
@@ -264,7 +264,7 @@ e_html_editor_table_dialog_show (WebKitDOMDocument *document,
                }
        }
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                EHTMLEditorHistoryEvent *ev;
 
@@ -300,7 +300,7 @@ e_html_editor_table_dialog_save_history_on_exit (WebKitDOMDocument *document,
 
        webkit_dom_element_remove_attribute (element, "id");
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
        ev->data.dom.to = webkit_dom_node_clone_node_with_error (
                WEBKIT_DOM_NODE (element), TRUE, NULL);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.c 
b/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.c
index c9693b5..e7a24b9 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.c
@@ -43,8 +43,6 @@ struct _EHTMLEditorUndoRedoManagerPrivate {
        WebKitDOMDocument *document;
        GWeakRef extension;
 
-       gboolean can_undo;
-       gboolean can_redo;
        gboolean operation_in_progress;
 
        GList *history;
@@ -68,6 +66,16 @@ G_DEFINE_TYPE (
        G_TYPE_OBJECT
 );
 
+EHTMLEditorUndoRedoManager *
+e_html_editor_undo_redo_manager_new (EHTMLEditorWebExtension *extension)
+{
+       g_return_val_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension), NULL);
+
+       return g_object_new (E_TYPE_HTML_EDITOR_UNDO_REDO_MANAGER,
+               "html-editor-web-extension", extension,
+               NULL);
+}
+
 void
 e_html_editor_undo_redo_manager_set_document (EHTMLEditorUndoRedoManager *manager,
                                               WebKitDOMDocument *document)
@@ -895,7 +903,7 @@ redo_delete (WebKitDOMDocument *document,
        WebKitDOMDocumentFragment *fragment = event->data.fragment;
        WebKitDOMNode *node;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        restore_selection_to_history_event_state (document, event->before);
 
        delete_key = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (event->data.fragment), 
"history-delete-key"));
@@ -2200,7 +2208,6 @@ e_html_editor_undo_redo_manager_insert_history_event (EHTMLEditorUndoRedoManager
 
        manager->priv->history = g_list_prepend (manager->priv->history, event);
        manager->priv->history_size++;
-       manager->priv->can_undo = TRUE;
 
        d (print_history (manager));
 
@@ -2438,6 +2445,9 @@ e_html_editor_undo_redo_manager_undo (EHTMLEditorUndoRedoManager *manager)
        manager->priv->operation_in_progress = FALSE;
 
        g_object_unref (extension);
+
+       g_object_notify (G_OBJECT (manager), "can-undo");
+       g_object_notify (G_OBJECT (manager), "can-redo");
 }
 
 gboolean
@@ -2584,6 +2594,9 @@ e_html_editor_undo_redo_manager_redo (EHTMLEditorUndoRedoManager *manager)
        manager->priv->operation_in_progress = FALSE;
 
        g_object_unref (extension);
+
+       g_object_notify (G_OBJECT (manager), "can-undo");
+       g_object_notify (G_OBJECT (manager), "can-redo");
 }
 
 void
@@ -2610,9 +2623,7 @@ e_html_editor_undo_redo_manager_clean_history (EHTMLEditorUndoRedoManager *manag
        ev->type = HISTORY_START;
        manager->priv->history = g_list_append (manager->priv->history, ev);
 
-       manager->priv->can_undo = FALSE;
        g_object_notify (G_OBJECT (manager), "can-undo");
-       manager->priv->can_redo = FALSE;
        g_object_notify (G_OBJECT (manager), "can-redo");
 }
 
@@ -2629,7 +2640,6 @@ static void
 html_editor_undo_redo_manager_dispose (GObject *object)
 {
        EHTMLEditorUndoRedoManagerPrivate *priv;
-       EHTMLEditorWebExtension *extension;
 
        priv = E_HTML_EDITOR_UNDO_REDO_MANAGER_GET_PRIVATE (object);
 
@@ -2638,8 +2648,6 @@ html_editor_undo_redo_manager_dispose (GObject *object)
                priv->history = NULL;
        }
 
-       extension = g_weak_ref_get (&priv->extension);
-       g_clear_object (&extension);
        g_weak_ref_set (&priv->extension, NULL);
 
        /* Chain up to parent's dispose() method. */
@@ -2753,6 +2761,4 @@ e_html_editor_undo_redo_manager_init (EHTMLEditorUndoRedoManager *manager)
        manager->priv->operation_in_progress = FALSE;
        manager->priv->history = NULL;
        manager->priv->history_size = 0;
-       manager->priv->can_undo = FALSE;
-       manager->priv->can_redo = FALSE;
 }
diff --git a/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.h 
b/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.h
index 098efff..b7ecc25 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.h
+++ b/modules/webkit-editor/web-extension/e-html-editor-undo-redo-manager.h
@@ -44,6 +44,8 @@
 
 G_BEGIN_DECLS
 
+struct _EHTMLEditorWebExtension;
+
 typedef struct _EHTMLEditorUndoRedoManager EHTMLEditorUndoRedoManager;
 typedef struct _EHTMLEditorUndoRedoManagerClass EHTMLEditorUndoRedoManagerClass;
 typedef struct _EHTMLEditorUndoRedoManagerPrivate EHTMLEditorUndoRedoManagerPrivate;
@@ -61,6 +63,9 @@ struct _EHTMLEditorUndoRedoManagerClass
 GType          e_html_editor_undo_redo_manager_get_type
                                                (void) G_GNUC_CONST;
 
+EHTMLEditorUndoRedoManager *
+               e_html_editor_undo_redo_manager_new
+                                               (struct _EHTMLEditorWebExtension *extension);
 void           e_html_editor_undo_redo_manager_set_document
                                                (EHTMLEditorUndoRedoManager *manager,
                                                 WebKitDOMDocument *document);
diff --git a/modules/webkit-editor/web-extension/e-html-editor-view-dom-functions.c 
b/modules/webkit-editor/web-extension/e-html-editor-view-dom-functions.c
index efa128d..954a48e 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-view-dom-functions.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-view-dom-functions.c
@@ -1253,7 +1253,7 @@ insert_delete_event (WebKitDOMDocument *document,
        WebKitDOMDocumentFragment *fragment;
        EHTMLEditorUndoRedoManager *manager;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (e_html_editor_undo_redo_manager_is_operation_in_progress (manager))
                return;
@@ -1378,7 +1378,7 @@ emoticon_insert_span (EEmoticon *emoticon,
        WebKitDOMRange *range;
 
        smiley_written = e_html_editor_web_extension_get_is_smiley_written (extension);
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (dom_selection_is_collapsed (document)) {
                dom_selection_save (document);
@@ -2176,7 +2176,7 @@ save_history_before_event_in_table (WebKitDOMDocument *document,
                        &ev->before.end.x,
                        &ev->before.end.y);
 
-               manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
                e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
 
                return TRUE;
@@ -2193,7 +2193,7 @@ insert_tabulator (WebKitDOMDocument *document,
        EHTMLEditorHistoryEvent *ev = NULL;
        gboolean success;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
@@ -2399,7 +2399,7 @@ body_keydown_event_cb (WebKitDOMElement *element,
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_INPUT;
 
-               manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
                dom_selection_get_coordinates (
                        document,
@@ -2445,7 +2445,7 @@ save_history_after_event_in_table (WebKitDOMDocument *document,
        g_object_unref (dom_selection);
        g_object_unref (range);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        /* If writing to table we have to create different history event. */
        if (WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (element)) {
                ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
@@ -2483,7 +2483,7 @@ save_history_for_input (WebKitDOMDocument *document,
        WebKitDOMRange *range, *range_clone;
        WebKitDOMNode *start_container;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        dom_window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
@@ -2682,7 +2682,7 @@ body_input_event_process (WebKitDOMDocument *document,
 
        range = dom_get_current_range (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        html_mode = e_html_editor_web_extension_get_html_mode (extension);
        e_html_editor_web_extension_set_content_changed (extension);
@@ -3381,7 +3381,7 @@ body_keyup_event_cb (WebKitDOMElement *element,
                        EHTMLEditorHistoryEvent *ev = NULL;
                        EHTMLEditorUndoRedoManager *manager;
 
-                       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+                       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
                        ev = e_html_editor_undo_redo_manager_get_current_history_event (manager);
                        dom_selection_get_coordinates (
                                document,
@@ -3449,7 +3449,7 @@ delete_hidden_space (WebKitDOMDocument *document,
                WebKitDOMNode *node;
                WebKitDOMDocumentFragment *fragment;
 
-               manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
                node = webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (selection_start_marker));
                if (!(WEBKIT_DOM_IS_ELEMENT (node) &&
@@ -3506,7 +3506,7 @@ dom_move_quoted_block_level_up (WebKitDOMDocument *document,
        WebKitDOMNode *block;
        EHTMLEditorUndoRedoManager *manager;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        html_mode = e_html_editor_web_extension_get_html_mode (extension);
 
        selection_start_marker = webkit_dom_document_query_selector (
@@ -5057,7 +5057,7 @@ dom_quote_and_insert_text_into_selection (WebKitDOMDocument *document,
 
        dom_selection_save (document);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
                ev->type = HISTORY_PASTE_QUOTED;
@@ -5666,7 +5666,7 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
        if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (current_block))
                current_block = NULL;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                gboolean collapsed;
 
@@ -8196,7 +8196,7 @@ dom_insert_html (WebKitDOMDocument *document,
 
        g_return_if_fail (html_text != NULL);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                gboolean collapsed;
 
@@ -8762,7 +8762,7 @@ save_history_for_delete_or_backspace (WebKitDOMDocument *document,
 
        ev->data.fragment = fragment;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
 }
 
@@ -8915,7 +8915,7 @@ split_citation (WebKitDOMDocument *document,
        EHTMLEditorUndoRedoManager *manager;
        WebKitDOMElement *element;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                WebKitDOMElement *selection_end;
@@ -9098,7 +9098,7 @@ delete_last_character_from_previous_line_in_quoted_block (WebKitDOMDocument *doc
 
                ev->data.fragment = fragment;
 
-               manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
                e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
        }
 
@@ -9247,7 +9247,7 @@ return_pressed_in_image_wrapper (WebKitDOMDocument *document,
                return FALSE;
        }
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
@@ -9332,7 +9332,7 @@ return_pressed_in_empty_list_item (WebKitDOMDocument *document,
                WebKitDOMElement *paragraph;
                WebKitDOMNode *list;
 
-               manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
                if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
                        ev = g_new0 (EHTMLEditorHistoryEvent, 1);
@@ -9537,7 +9537,7 @@ remove_empty_bulleted_list_item (WebKitDOMDocument *document,
        WebKitDOMElement *selection_start;
        WebKitDOMNode *parent;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        dom_selection_save (document);
 
        selection_start = webkit_dom_document_get_element_by_id (
@@ -9966,7 +9966,7 @@ dom_process_content_after_mode_change (WebKitDOMDocument *document,
 
        set_monospace_font_family_on_body (WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)), 
html_mode);
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
        e_html_editor_undo_redo_manager_clean_history (manager);
 }
 
@@ -10074,7 +10074,7 @@ dom_save_history_for_drop (WebKitDOMDocument *document,
        WebKitDOMNodeList *list;
        WebKitDOMRange *range;
 
-       manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
 
        /* When the image is DnD inside the view WebKit removes the wrapper that
         * is used for resizing the image, so we have to recreate it again. */
diff --git a/modules/webkit-editor/web-extension/e-html-editor-web-extension.c 
b/modules/webkit-editor/web-extension/e-html-editor-web-extension.c
index 6596e0d..f8f994c 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-web-extension.c
+++ b/modules/webkit-editor/web-extension/e-html-editor-web-extension.c
@@ -97,7 +97,9 @@ struct _EHTMLEditorWebExtensionPrivate {
 
        EContentEditorContentFlags content_flags;
 
-       EHTMLEditorUndoRedoManager *undo_redo_manager;
+       GHashTable *undo_redo_managers /* EHTMLEditorUndoRedoManager * ~> WebKitWebPage * */;
+       GSList *web_pages;
+
        ESpellChecker *spell_checker;
 };
 
@@ -126,6 +128,11 @@ static const char introspection_xml[] =
 "    </signal>"
 "    <signal name='ContentChanged'>"
 "    </signal>"
+"    <signal name='UndoRedoStateChanged'>"
+"      <arg type='t' name='page_id' direction='out'/>"
+"      <arg type='b' name='can_undo' direction='out'/>"
+"      <arg type='b' name='can_redo' direction='out'/>"
+"    </signal>"
 "<!-- ********************************************************* -->"
 "<!--                          METHODS                          -->"
 "<!-- ********************************************************* -->"
@@ -483,6 +490,12 @@ static const char introspection_xml[] =
 "    <method name='DOMRestoreSelection'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
+"    <method name='DOMUndo'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"    <method name='DOMRedo'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
 "    <method name='DOMQuoteAndInsertTextIntoSelection'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='text' direction='in'/>"
@@ -1780,6 +1793,36 @@ handle_method_call (GDBusConnection *connection,
                document = webkit_web_page_get_dom_document (web_page);
                dom_selection_restore (document);
                g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "DOMUndo") == 0) {
+               EHTMLEditorUndoRedoManager *manager;
+
+               g_variant_get (parameters, "(t)", &page_id);
+
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       goto error;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
+
+               e_html_editor_undo_redo_manager_undo (manager);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "DOMRedo") == 0) {
+               EHTMLEditorUndoRedoManager *manager;
+
+               g_variant_get (parameters, "(t)", &page_id);
+
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+               if (!web_page)
+                       goto error;
+
+               document = webkit_web_page_get_dom_document (web_page);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension, document);
+
+               e_html_editor_undo_redo_manager_redo (manager);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMTurnSpellCheckOff") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -2455,14 +2498,18 @@ handle_method_call (GDBusConnection *connection,
                        invocation,
                        value ? g_variant_new_uint32 (value) : NULL);
        } else if (g_strcmp0 (method_name, "DOMClearUndoRedoHistory") == 0) {
+               EHTMLEditorUndoRedoManager *manager;
+
                g_variant_get (parameters, "(t)", &page_id);
 
-               web_page = get_webkit_web_page_or_return_dbus_error (
-                       invocation, web_extension, page_id);
+               web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
                if (!web_page)
                        goto error;
 
-               e_html_editor_undo_redo_manager_clean_history (extension->priv->undo_redo_manager);
+               manager = e_html_editor_web_extension_get_undo_redo_manager (extension,
+                       webkit_web_page_get_dom_document (web_page));
+               if (manager)
+                       e_html_editor_undo_redo_manager_clean_history (manager);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else {
@@ -2475,6 +2522,27 @@ handle_method_call (GDBusConnection *connection,
        g_warning ("Cannot obtain WebKitWebPage for '%ld'", page_id);
 }
 
+static void
+web_page_gone_cb (gpointer user_data,
+                 GObject *gone_web_page)
+{
+       EHTMLEditorWebExtension *extension = user_data;
+       GHashTableIter iter;
+       gpointer key, value;
+
+       g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
+
+       extension->priv->web_pages = g_slist_remove (extension->priv->web_pages, gone_web_page);
+
+       g_hash_table_iter_init (&iter, extension->priv->undo_redo_managers);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               if (value == gone_web_page) {
+                       g_hash_table_remove (extension->priv->undo_redo_managers, key);
+                       break;
+               }
+       }
+}
+
 static const GDBusInterfaceVTable interface_vtable = {
        handle_method_call,
        NULL,
@@ -2519,9 +2587,25 @@ e_html_editor_web_extension_dispose (GObject *object)
                extension->priv->text = NULL;
        }
 
-       if (extension->priv->undo_redo_manager != NULL) {
-               g_object_unref (extension->priv->undo_redo_manager);
-               extension->priv->undo_redo_manager = NULL;
+       if (extension->priv->undo_redo_managers != NULL) {
+               g_hash_table_destroy (extension->priv->undo_redo_managers);
+               extension->priv->undo_redo_managers = NULL;
+       }
+
+       if (extension->priv->web_pages) {
+               GSList *link;
+
+               for (link = extension->priv->web_pages; link; link = g_slist_next (link)) {
+                       WebKitWebPage *page = link->data;
+
+                       if (!page)
+                               continue;
+
+                       g_object_weak_unref (G_OBJECT (page), web_page_gone_cb, extension);
+               }
+
+               g_slist_free (extension->priv->web_pages);
+               extension->priv->web_pages = NULL;
        }
 
        if (extension->priv->mail_settings != NULL) {
@@ -2605,10 +2689,7 @@ e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
        extension->priv->word_wrap_length = g_settings_get_int (
                extension->priv->mail_settings, "composer-word-wrap-length");
 
-       extension->priv->undo_redo_manager = g_object_new (
-               E_TYPE_HTML_EDITOR_UNDO_REDO_MANAGER,
-               "html-editor-web-extension", extension,
-               NULL);
+       extension->priv->undo_redo_managers = g_hash_table_new_full (g_direct_hash, g_direct_equal, 
g_object_unref, NULL);
 
        extension->priv->inline_images = g_hash_table_new_full (
                g_str_hash, g_str_equal,
@@ -2744,11 +2825,13 @@ web_page_document_loaded_cb (WebKitWebPage *web_page,
                              EHTMLEditorWebExtension *web_extension)
 {
        WebKitDOMDocument *document;
+       EHTMLEditorUndoRedoManager *manager;
 
        document = webkit_web_page_get_dom_document (web_page);
+       manager = e_html_editor_web_extension_get_undo_redo_manager (web_extension, document);
 
-       e_html_editor_undo_redo_manager_set_document (
-               web_extension->priv->undo_redo_manager, document);
+       g_warn_if_fail (manager != NULL);
+       e_html_editor_undo_redo_manager_set_document (manager, document);
 
        web_extension->priv->body_input_event_removed = TRUE;
 
@@ -2881,12 +2964,53 @@ web_editor_selection_changed_cb (WebKitWebEditor *editor,
 }
 
 static void
+web_editor_can_undo_redo_notify_cb (EHTMLEditorUndoRedoManager *manager,
+                                   GParamSpec *param,
+                                   EHTMLEditorWebExtension *extension)
+{
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
+
+       g_dbus_connection_emit_signal (
+               extension->priv->dbus_connection,
+               NULL,
+               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+               "UndoRedoStateChanged",
+               g_variant_new ("(tbb)",
+                       e_html_editor_web_extension_get_undo_redo_manager_page_id (extension, manager),
+                       e_html_editor_undo_redo_manager_can_undo (manager),
+                       e_html_editor_undo_redo_manager_can_redo (manager)),
+               &error);
+
+       if (error)
+               g_warning ("%s: Failed to emit signal: %s", G_STRFUNC, error->message);
+       g_clear_error (&error);
+}
+
+static void
 web_page_created_cb (WebKitWebExtension *wk_extension,
                      WebKitWebPage *web_page,
                      EHTMLEditorWebExtension *extension)
 {
+       EHTMLEditorUndoRedoManager *manager;
        WebKitWebEditor *web_editor;
 
+       extension->priv->web_pages = g_slist_prepend (extension->priv->web_pages, web_page);
+       g_object_weak_ref (G_OBJECT (web_page), web_page_gone_cb, extension);
+
+       manager = e_html_editor_undo_redo_manager_new (extension);
+       g_hash_table_insert (extension->priv->undo_redo_managers, manager, web_page);
+
+       g_signal_connect (
+               manager, "notify::can-undo",
+               G_CALLBACK (web_editor_can_undo_redo_notify_cb), extension);
+
+       g_signal_connect (
+               manager, "notify::can-redo",
+               G_CALLBACK (web_editor_can_undo_redo_notify_cb), extension);
+
        g_signal_connect (
                web_page, "send-request",
                G_CALLBACK (web_page_send_request_cb), extension);
@@ -3223,12 +3347,44 @@ e_html_editor_web_extension_set_renew_history_after_coordinates (EHTMLEditorWebE
        extension->priv->renew_history_after_coordinates = renew_history_after_coordinates;
 }
 
+guint64
+e_html_editor_web_extension_get_undo_redo_manager_page_id (EHTMLEditorWebExtension *extension,
+                                                          EHTMLEditorUndoRedoManager *manager)
+{
+       WebKitWebPage *web_page;
+
+       g_return_val_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension), 0);
+       g_return_val_if_fail (E_IS_HTML_EDITOR_UNDO_REDO_MANAGER (manager), 0);
+
+       web_page = g_hash_table_lookup (extension->priv->undo_redo_managers, manager);
+       g_return_val_if_fail (web_page != NULL, 0);
+       g_return_val_if_fail (WEBKIT_IS_WEB_PAGE (web_page), 0);
+
+       return webkit_web_page_get_id (web_page);
+}
+
 EHTMLEditorUndoRedoManager *
-e_html_editor_web_extension_get_undo_redo_manager (EHTMLEditorWebExtension *extension)
+e_html_editor_web_extension_get_undo_redo_manager (EHTMLEditorWebExtension *extension,
+                                                  WebKitDOMDocument *document)
 {
+       GHashTableIter iter;
+       gpointer key, value;
+
        g_return_val_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension), NULL);
+       g_return_val_if_fail (WEBKIT_DOM_IS_DOCUMENT (document), NULL);
+
+       g_hash_table_iter_init (&iter, extension->priv->undo_redo_managers);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               g_warn_if_fail (E_IS_HTML_EDITOR_UNDO_REDO_MANAGER (key));
+               g_warn_if_fail (WEBKIT_IS_WEB_PAGE (value));
+
+               if (document == webkit_web_page_get_dom_document (value))
+                       return key;
+       }
+
+       g_warn_if_reached ();
 
-       return extension->priv->undo_redo_manager;
+       return NULL;
 }
 
 gboolean
diff --git a/modules/webkit-editor/web-extension/e-html-editor-web-extension.h 
b/modules/webkit-editor/web-extension/e-html-editor-web-extension.h
index fc65c08..4a24d8f 100644
--- a/modules/webkit-editor/web-extension/e-html-editor-web-extension.h
+++ b/modules/webkit-editor/web-extension/e-html-editor-web-extension.h
@@ -50,8 +50,6 @@
 
 G_BEGIN_DECLS
 
-struct _EHTMLEditorUndoRedoManager;
-
 typedef struct _EHTMLEditorWebExtension EHTMLEditorWebExtension;
 typedef struct _EHTMLEditorWebExtensionClass EHTMLEditorWebExtensionClass;
 typedef struct _EHTMLEditorWebExtensionPrivate EHTMLEditorWebExtensionPrivate;
@@ -217,10 +215,13 @@ gboolean  e_html_editor_web_extension_get_renew_history_after_coordinates
 void           e_html_editor_web_extension_set_renew_history_after_coordinates
                                                (EHTMLEditorWebExtension *extension,
                                                 gboolean renew_history_after_coordinates);
-
-struct _EHTMLEditorUndoRedoManager *
+guint64                e_html_editor_web_extension_get_undo_redo_manager_page_id
+                                               (EHTMLEditorWebExtension *extension,
+                                                EHTMLEditorUndoRedoManager *manager);
+EHTMLEditorUndoRedoManager *
                e_html_editor_web_extension_get_undo_redo_manager
-                                               (EHTMLEditorWebExtension *extension);
+                                               (EHTMLEditorWebExtension *extension,
+                                                WebKitDOMDocument *document);
 
 gboolean       e_html_editor_web_extension_is_composition_in_progress
                                                (EHTMLEditorWebExtension *extension);



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