[evolution/wip/webkit2] Introduce the EContentEditor



commit b74937606c54b51f1944fa0e15d0b9f951f5a215
Author: Tomas Popela <tpopela redhat com>
Date:   Mon May 30 11:27:59 2016 +0200

    Introduce the EContentEditor
    
    It is a replacement for the EHTMLEditorView and EHTMLEditorSelection. It defines
    an interface with all the content operations that are used across the composer.
    There is a new module webkit-content-editor that implements this interface and
    it is based on WebKit.

 composer/e-composer-actions.c                      |   79 +-
 composer/e-composer-private.c                      |  376 +-
 composer/e-composer-private.h                      |    8 +-
 composer/e-msg-composer.c                          |  602 +--
 composer/e-msg-composer.h                          |    3 -
 configure.ac                                       |    1 +
 .../evolution-util/evolution-util-sections.txt     |   10 +-
 e-util/Makefile.am                                 |   10 +-
 e-util/e-content-editor-enums.h                    |  281 +
 e-util/e-content-editor-find-controller.c          |  190 +
 e-util/e-content-editor-find-controller.h          |   98 +
 e-util/e-content-editor.c                          | 3457 +++++++++++
 e-util/e-content-editor.h                          | 1129 ++++
 e-util/e-focus-tracker.c                           |   12 +-
 e-util/e-html-editor-actions.c                     |  392 +-
 e-util/e-html-editor-actions.h                     |    2 +
 e-util/e-html-editor-cell-dialog.c                 |  572 +--
 e-util/e-html-editor-defines.h                     |   34 -
 e-util/e-html-editor-dialog.h                      |   10 +
 e-util/e-html-editor-find-dialog.c                 |   52 +-
 e-util/e-html-editor-hrule-dialog.c                |  290 +-
 e-util/e-html-editor-image-dialog.c                |  488 +--
 e-util/e-html-editor-link-dialog.c                 |   92 +-
 e-util/e-html-editor-page-dialog.c                 |  251 +-
 e-util/e-html-editor-private.h                     |    6 +-
 e-util/e-html-editor-replace-dialog.c              |  119 +-
 e-util/e-html-editor-selection.c                   |  282 +-
 e-util/e-html-editor-selection.h                   |   32 +-
 e-util/e-html-editor-spell-check-dialog.c          |  183 +-
 e-util/e-html-editor-table-dialog.c                |  574 +--
 e-util/e-html-editor-text-dialog.c                 |   78 +-
 e-util/e-html-editor-view.c                        |  634 +--
 e-util/e-html-editor-view.h                        |   12 +-
 e-util/e-html-editor.c                             |  211 +-
 e-util/e-html-editor.h                             |   10 +-
 e-util/e-mail-signature-editor.c                   |   69 +-
 e-util/e-mail-signature-manager.c                  |    7 +-
 e-util/e-marshal.list                              |    1 +
 e-util/e-misc-utils.c                              |   54 +
 e-util/e-misc-utils.h                              |    2 +
 e-util/e-util-enums.h                              |  203 -
 e-util/e-util.h                                    |    6 +-
 mail/e-mail-display.c                              |    1 -
 mail/e-mail-notes.c                                |  113 +-
 mail/em-composer-utils.c                           |   63 +-
 modules/Makefile.am                                |    1 +
 modules/composer-autosave/e-composer-autosave.c    |   12 +-
 modules/mail/e-mail-shell-backend.c                |    6 +-
 modules/settings/Makefile.am                       |    4 +-
 ...l-editor-view.c => e-settings-content-editor.c} |   95 +-
 modules/settings/e-settings-content-editor.h       |   64 +
 modules/settings/e-settings-html-editor-view.h     |   64 -
 modules/settings/evolution-module-settings.c       |    4 +-
 modules/webkit-content-editor/Makefile.am          |   31 +
 .../e-webkit-content-editor-find-controller.c      |  354 ++
 .../e-webkit-content-editor-find-controller.h      |   62 +
 .../e-webkit-content-editor.c                      | 6059 ++++++++++++++++++++
 .../e-webkit-content-editor.h                      |   68 +
 .../e-webkit-editor-extension.c                    |  101 +
 .../e-webkit-editor-extension.h                    |   62 +
 .../evolution-module-webkit-content-editor.c       |   36 +
 plugins/external-editor/external-editor.c          |  125 +-
 .../composer/e-composer-private-dom-functions.c    |  317 +-
 .../composer/e-composer-private-dom-functions.h    |   12 +-
 .../e-html-editor-cell-dialog-dom-functions.c      |   33 +-
 .../e-html-editor-link-dialog-dom-functions.c      |   79 +-
 .../e-html-editor-selection-dom-functions.c        |  661 ++-
 .../e-html-editor-selection-dom-functions.h        |   19 +-
 .../composer/e-html-editor-undo-redo-manager.c     |   20 +-
 .../composer/e-html-editor-view-dom-functions.c    |  381 +-
 .../composer/e-html-editor-view-dom-functions.h    |   22 +-
 .../composer/e-html-editor-web-extension.c         | 1331 ++---
 .../composer/e-html-editor-web-extension.h         |   26 +-
 .../composer/e-msg-composer-dom-functions.c        |   26 +-
 web-extensions/e-dom-utils.c                       |   34 +-
 web-extensions/e-dom-utils.h                       |    5 +-
 76 files changed, 15218 insertions(+), 5995 deletions(-)
---
diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c
index 5995ef0..cf31d23 100644
--- a/composer/e-composer-actions.c
+++ b/composer/e-composer-actions.c
@@ -78,27 +78,29 @@ action_new_message_cb (GtkAction *action,
 }
 
 static void
-action_pgp_encrypt_cb (GtkToggleAction *action,
-                       EMsgComposer *composer)
+composer_set_content_editor_changed (EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_changed (cnt_editor, TRUE);
+
+}
+
+static void
+action_pgp_encrypt_cb (GtkToggleAction *action,
+                       EMsgComposer *composer)
+{
+       composer_set_content_editor_changed (composer);
 }
 
 static void
 action_pgp_sign_cb (GtkToggleAction *action,
                     EMsgComposer *composer)
 {
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       composer_set_content_editor_changed (composer);
 }
 
 static void
@@ -150,7 +152,6 @@ action_save_cb (GtkAction *action,
                 EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
        const gchar *filename;
        gint fd;
        GError *error = NULL;
@@ -195,8 +196,7 @@ action_save_cb (GtkAction *action,
                return;
        }
 
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       composer_set_content_editor_changed (composer);
 }
 
 static void
@@ -256,37 +256,14 @@ static void
 action_smime_encrypt_cb (GtkToggleAction *action,
                          EMsgComposer *composer)
 {
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       composer_set_content_editor_changed (composer);
 }
 
 static void
 action_smime_sign_cb (GtkToggleAction *action,
                       EMsgComposer *composer)
 {
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
-}
-
-static void
-action_unicode_smileys_cb (GtkToggleAction *action,
-                           EMsgComposer *composer)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_unicode_smileys (view,
-               gtk_toggle_action_get_active (action));
+       composer_set_content_editor_changed (composer);
 }
 
 static void
@@ -518,14 +495,6 @@ static GtkToggleActionEntry toggle_entries[] = {
          NULL,
          FALSE },
 
-       { "unicode-smileys",
-         NULL,
-         N_("Unicode emoticons"),
-         NULL,
-         N_("Use Unicode characters for emoticons."),
-         G_CALLBACK (action_unicode_smileys_cb),
-         FALSE },
-
        { "view-bcc",
          NULL,
          N_("_Bcc Field"),
@@ -566,14 +535,14 @@ e_composer_actions_init (EMsgComposer *composer)
        GtkAccelGroup *accel_group;
        GtkUIManager *ui_manager;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        gboolean visible;
        GIcon *gcr_gnupg_icon;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
        ui_manager = e_html_editor_get_ui_manager (editor);
 
        /* Composer Actions */
@@ -678,32 +647,32 @@ e_composer_actions_init (EMsgComposer *composer)
        }
 
        e_binding_bind_property (
-               view, "html-mode",
+               cnt_editor, "html-mode",
                ACTION (PICTURE_GALLERY), "sensitive",
                G_BINDING_SYNC_CREATE);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                e_html_editor_get_action (editor, "edit-menu"), "sensitive",
                G_BINDING_SYNC_CREATE);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                e_html_editor_get_action (editor, "format-menu"), "sensitive",
                G_BINDING_SYNC_CREATE);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                e_html_editor_get_action (editor, "insert-menu"), "sensitive",
                G_BINDING_SYNC_CREATE);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                e_html_editor_get_action (editor, "options-menu"), "sensitive",
                G_BINDING_SYNC_CREATE);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                e_html_editor_get_action (editor, "picture-gallery"), "sensitive",
                G_BINDING_SYNC_CREATE);
 
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index a9c40e0..93d4ca3 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -64,14 +64,14 @@ static void
 composer_update_gallery_visibility (EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkToggleAction *toggle_action;
        gboolean gallery_active;
        gboolean is_html;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       is_html = e_html_editor_view_get_html_mode (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       is_html = e_content_editor_get_html_mode (cnt_editor);
 
        toggle_action = GTK_TOGGLE_ACTION (ACTION (PICTURE_GALLERY));
        gallery_active = gtk_toggle_action_get_active (toggle_action);
@@ -94,7 +94,7 @@ e_composer_private_constructed (EMsgComposer *composer)
        EShell *shell;
        EClientCache *client_cache;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkUIManager *ui_manager;
        GtkAction *action;
        GtkWidget *container;
@@ -109,7 +109,7 @@ e_composer_private_constructed (EMsgComposer *composer)
 
        editor = e_msg_composer_get_editor (composer);
        ui_manager = e_html_editor_get_ui_manager (editor);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        settings = e_util_ref_settings ("org.gnome.evolution.mail");
 
@@ -130,7 +130,6 @@ e_composer_private_constructed (EMsgComposer *composer)
 
        priv->charset = e_composer_get_default_charset ();
 
-       priv->is_from_new_message = FALSE;
        priv->set_signature_from_message = FALSE;
        priv->disable_signature = FALSE;
        priv->busy = FALSE;
@@ -138,6 +137,9 @@ e_composer_private_constructed (EMsgComposer *composer)
        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;
+       priv->ignore_next_paste_clipboard_signals_emission = FALSE;
 
        priv->focused_entry = NULL;
 
@@ -212,7 +214,7 @@ e_composer_private_constructed (EMsgComposer *composer)
                E_COMPOSER_HEADER_TABLE (widget),
                E_COMPOSER_HEADER_SUBJECT);
        e_binding_bind_property (
-               view, "spell-checker",
+               cnt_editor, "spell-checker",
                header->input_widget, "spell-checker",
                G_BINDING_SYNC_CREATE);
 
@@ -230,11 +232,10 @@ e_composer_private_constructed (EMsgComposer *composer)
        priv->attachment_paned = g_object_ref_sink (widget);
        gtk_widget_show (widget);
 
-/* FIXME WK2
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                widget, "sensitive",
-               G_BINDING_SYNC_CREATE);*/
+               G_BINDING_SYNC_CREATE);
 
        container = e_attachment_paned_get_content_area (
                E_ATTACHMENT_PANED (priv->attachment_paned));
@@ -254,7 +255,7 @@ e_composer_private_constructed (EMsgComposer *composer)
        priv->gallery_scrolled_window = g_object_ref (widget);
        gtk_widget_show (widget);
 
-       widget = GTK_WIDGET (view);
+       widget = GTK_WIDGET (cnt_editor);
        gtk_widget_reparent (widget, container);
 
        /* Construct the picture gallery. */
@@ -270,7 +271,7 @@ e_composer_private_constructed (EMsgComposer *composer)
        g_free (gallery_path);
 
        e_signal_connect_notify_swapped (
-               view, "notify::mode",
+               cnt_editor, "notify::html-mode",
                G_CALLBACK (composer_update_gallery_visibility), composer);
 
        g_signal_connect_swapped (
@@ -491,133 +492,32 @@ e_composer_get_default_charset (void)
 }
 
 gboolean
-e_composer_paste_html (EMsgComposer *composer,
-                       GtkClipboard *clipboard)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *html;
-
-       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
-       g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
-
-       if (!(html = e_clipboard_wait_for_html (clipboard)))
-               return FALSE;
-
-       g_return_val_if_fail (html != NULL, FALSE);
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       /* If Web View doesn't have focus, focus it */
-       if (!gtk_widget_has_focus (GTK_WIDGET (view)))
-               gtk_widget_grab_focus (GTK_WIDGET (view));
-       e_html_editor_view_insert_html (view, html);
-
-       g_free (html);
-
-       return TRUE;
-}
-
-gboolean
 e_composer_paste_image (EMsgComposer *composer,
                         GtkClipboard *clipboard)
 {
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GdkPixbuf *pixbuf = NULL;
-       gchar *filename = NULL;
-       gchar *uri = NULL;
-       gboolean success = FALSE;
-       GError *error = NULL;
+       EAttachment *attachment;
+       EAttachmentStore *store;
+       EAttachmentView *view;
+       gchar *uri;
 
        g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
        g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
 
-       /* Extract the image data from the clipboard. */
-       pixbuf = gtk_clipboard_wait_for_image (clipboard);
-       g_return_val_if_fail (pixbuf != NULL, FALSE);
-
-       /* Reserve a temporary file. */
-       filename = e_mktemp (NULL);
-       if (filename == NULL) {
-               g_set_error (
-                       &error, G_FILE_ERROR,
-                       g_file_error_from_errno (errno),
-                       "Could not create temporary file: %s",
-                       g_strerror (errno));
-               goto exit;
-       }
-
-       /* Save the pixbuf as a temporary file in image/png format. */
-       if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL))
-               goto exit;
-
-       /* Convert the filename to a URI. */
-       uri = g_filename_to_uri (filename, NULL, &error);
-       if (uri == NULL)
-               goto exit;
-
-       /* In HTML mode, paste the image into the message body.
-        * In text mode, add the image to the attachment store. */
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       if (e_html_editor_view_get_html_mode (view)) {
-               e_html_editor_view_insert_image (view, uri);
-               e_html_editor_view_scroll_to_caret (view);
-       } else {
-               EAttachment *attachment;
-               EAttachmentStore *store;
-               EAttachmentView *attachment_view;
-
-               attachment_view = e_msg_composer_get_attachment_view (composer);
-               store = e_attachment_view_get_store (attachment_view);
-
-               attachment = e_attachment_new_for_uri (uri);
-               e_attachment_store_add_attachment (store, attachment);
-               e_attachment_load_async (
-                       attachment, (GAsyncReadyCallback)
-                       e_attachment_load_handle_error, composer);
-               g_object_unref (attachment);
-       }
-
-       success = TRUE;
-
-exit:
-       if (error != NULL) {
-               g_warning ("%s", error->message);
-               g_error_free (error);
-       }
-
-       g_object_unref (pixbuf);
-       g_free (filename);
-       g_free (uri);
-
-       return success;
-}
-
-gboolean
-e_composer_paste_text (EMsgComposer *composer,
-                       GtkClipboard *clipboard)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *text;
-
-       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
-       g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
+       view = e_msg_composer_get_attachment_view (composer);
+       store = e_attachment_view_get_store (view);
 
-       if (!(text = gtk_clipboard_wait_for_text (clipboard)))
+       if (!(uri = e_util_save_image_from_clipboard (clipboard)))
                return FALSE;
 
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       /* If WebView doesn't have focus, focus it */
-       if (!gtk_widget_has_focus (GTK_WIDGET (view)))
-               gtk_widget_grab_focus (GTK_WIDGET (view));
+       attachment = e_attachment_new_for_uri (uri);
+       e_attachment_store_add_attachment (store, attachment);
+       e_attachment_load_async (
+               attachment, (GAsyncReadyCallback)
+               e_attachment_load_handle_error, composer);
+       g_object_unref (attachment);
 
-       e_html_editor_view_insert_text (view, text);
 
-       g_free (text);
+       g_free (uri);
 
        return TRUE;
 }
@@ -757,55 +657,17 @@ e_composer_selection_is_image_uris (EMsgComposer *composer,
        return all_image_uris;
 }
 
-static gboolean
-add_signature_delimiter (EMsgComposer *composer)
-{
-       GSettings *settings;
-       gboolean signature_delim;
-
-       /* FIXME This should be an EMsgComposer property. */
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       signature_delim = !g_settings_get_boolean (
-               settings, "composer-no-signature-delim");
-       g_object_unref (settings);
-
-       return signature_delim;
-}
-
-static gboolean
-use_top_signature (EMsgComposer *composer)
-{
-       GSettings *settings;
-       gboolean top_signature;
-
-       /* FIXME This should be an EMsgComposer property. */
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       top_signature = g_settings_get_boolean (
-               settings, "composer-top-signature");
-       g_object_unref (settings);
-
-       return top_signature;
-}
-
 static void
 composer_load_signature_cb (EMailSignatureComboBox *combo_box,
                             GAsyncResult *result,
                             EMsgComposer *composer)
 {
-       GString *html_buffer = NULL;
-       gchar *contents = NULL;
+       gchar *contents = NULL, *new_signature_id;
        gsize length = 0;
-       const gchar *active_id;
-       gboolean top_signature;
        gboolean is_html;
        GError *error = NULL;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GSettings *settings;
-       gboolean start_bottom;
-       gboolean is_message_from_edit_as_new;
-       GDBusProxy *web_extension;
-       GVariant *extension_result;
+       EContentEditor *cnt_editor;
 
        e_mail_signature_combo_box_load_selected_finish (
                combo_box, result, &contents, &length, &is_html, &error);
@@ -814,160 +676,42 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
        if (error != NULL) {
                g_warning ("%s: %s", G_STRFUNC, error->message);
                g_error_free (error);
-               goto exit;
+               g_object_unref (composer);
+               return;
        }
 
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       is_message_from_edit_as_new =
-               e_html_editor_view_is_message_from_edit_as_new (view);
-
-       /* "Edit as New Message" sets is_message_from_edit_as_new.
-        * Always put the signature at the bottom for that case. */
-       top_signature =
-               use_top_signature (composer) &&
-               !is_message_from_edit_as_new &&
-               !composer->priv->is_from_new_message;
-
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
-       g_object_unref (settings);
-
-       if (contents == NULL)
-               goto insert;
-
-       if (!is_html) {
-               gchar *html;
-
-               html = camel_text_to_html (contents, 0, 0);
-               if (html) {
-                       g_free (contents);
-
-                       contents = html;
-                       length = strlen (contents);
-               }
+       if (composer->priv->ignore_next_signature_change) {
+               composer->priv->ignore_next_signature_change = FALSE;
+               g_object_unref (composer);
+               return;
        }
 
-       /* Generate HTML code for the signature. */
-
-       html_buffer = g_string_sized_new (1024);
-
-       /* The combo box active ID is the signature's ESource UID. */
-       active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
-
-       g_string_append_printf (
-               html_buffer,
-               "<SPAN class=\"-x-evo-signature\" id=\"1\" name=\"%s\">",
-               (active_id != NULL) ? active_id : "");
-
-       if (!is_html)
-               g_string_append (html_buffer, "<PRE>");
-
-       /* The signature dash convention ("-- \n") is specified
-        * in the "Son of RFC 1036", section 4.3.2.
-        * http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html
-        */
-       if (add_signature_delimiter (composer)) {
-               const gchar *delim;
-               const gchar *delim_nl;
-
-               if (is_html) {
-                       delim = "-- <BR>";
-                       delim_nl = "\n-- <BR>";
-               } else {
-                       delim = "-- \n";
-                       delim_nl = "\n-- \n";
-               }
-
-               /* Skip the delimiter if the signature already has one. */
-               if (g_ascii_strncasecmp (contents, delim, strlen (delim)) == 0)
-                       ;  /* skip */
-               else if (e_util_strstrcase (contents, delim_nl) != NULL)
-                       ;  /* skip */
-               else
-                       g_string_append (html_buffer, delim);
-       }
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       g_string_append_len (html_buffer, contents, length);
+       new_signature_id = e_content_editor_insert_signature (
+               cnt_editor,
+               contents,
+               is_html,
+               gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)),
+               &composer->priv->set_signature_from_message,
+               &composer->priv->check_if_signature_is_changed,
+               &composer->priv->ignore_next_signature_change);
 
-       if (!is_html)
-               g_string_append (html_buffer, "</PRE>");
+       if (new_signature_id && *new_signature_id)
+               gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), new_signature_id);
 
-       g_string_append (html_buffer, "</SPAN>");
+       g_free (new_signature_id);
        g_free (contents);
-
-insert:
-       /* Remove the old signature and insert the new one. */
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       extension_result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMRemoveSignatures",
-               g_variant_new (
-                       "(tb)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       top_signature),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (is_message_from_edit_as_new && composer->priv->set_signature_from_message && extension_result) {
-               const gchar *id;
-               gsize length = 0;
-
-               id = g_variant_get_string (extension_result, &length);
-               if (length > 0 && id && *id) {
-                       composer->priv->set_signature_from_message = FALSE;
-                       gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), id);
-               }
-               g_object_unref (extension_result);
-       }
-
-       if (html_buffer && html_buffer->str && *html_buffer->str) {
-               g_dbus_proxy_call (
-                       web_extension,
-                       "DOMInsertSignature",
-                       g_variant_new (
-                               "(tsbb)",
-                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                               html_buffer->str,
-                               top_signature,
-                               start_bottom),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
-
-               g_string_free (html_buffer, TRUE);
-       }
-
-       if (start_bottom)
-               e_html_editor_view_scroll_to_caret (view);
-exit:
-       /* Make sure the flag will be unset and won't influence user's choice */
-       composer->priv->set_signature_from_message = FALSE;
-
        g_object_unref (composer);
 }
 
 static void
-composer_web_view_load_changed_cb (WebKitWebView *webkit_web_view,
-                                   WebKitLoadEvent load_event,
-                                   EMsgComposer *composer)
+content_editor_load_finished_cb (EContentEditor *cnt_editor,
+                                 EMsgComposer *composer)
 {
-       g_return_if_fail (E_IS_MSG_COMPOSER (composer));
-
-       if (load_event != WEBKIT_LOAD_FINISHED)
-               return;
-
        g_signal_handlers_disconnect_by_func (
-               webkit_web_view,
-               G_CALLBACK (composer_web_view_load_changed_cb),
-               NULL);
+               cnt_editor, G_CALLBACK (content_editor_load_finished_cb), composer);
 
        e_composer_update_signature (composer);
 }
@@ -978,7 +722,7 @@ e_composer_update_signature (EMsgComposer *composer)
        EComposerHeaderTable *table;
        EMailSignatureComboBox *combo_box;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
@@ -990,18 +734,12 @@ e_composer_update_signature (EMsgComposer *composer)
        table = e_msg_composer_get_header_table (composer);
        combo_box = e_composer_header_table_get_signature_combo_box (table);
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-
-       /* If document is not loaded, we will wait for him */
-       if (webkit_web_view_is_loading (WEBKIT_WEB_VIEW (view))) {
-               /* Disconnect previous handlers */
-               g_signal_handlers_disconnect_by_func (
-                       WEBKIT_WEB_VIEW (view),
-                       G_CALLBACK (composer_web_view_load_changed_cb),
-                       composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       if (!e_content_editor_is_ready (cnt_editor)) {
                g_signal_connect (
-                       WEBKIT_WEB_VIEW(view), "load-changed",
-                       G_CALLBACK (composer_web_view_load_changed_cb),
+                       cnt_editor, "load-finished",
+                       G_CALLBACK (content_editor_load_finished_cb),
                        composer);
                return;
        }
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index 7586d3f..fbf4a91 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -104,6 +104,10 @@ struct _EMsgComposerPrivate {
        gboolean dnd_is_uri;
        gboolean is_sending_message;
        gboolean dnd_history_saved;
+       gboolean check_if_signature_is_changed;
+       gboolean ignore_next_signature_change;
+       gboolean ignore_next_paste_clipboard_signals_emission;
+       gboolean last_signal_was_paste_primary;
 
        gint focused_entry_selection_start;
        gint focused_entry_selection_end;
@@ -129,12 +133,8 @@ gchar *            e_composer_find_data_file       (const gchar *basename);
 gchar *                e_composer_get_default_charset  (void);
 gchar *                e_composer_decode_clue_value    (const gchar *encoded_value);
 gchar *                e_composer_encode_clue_value    (const gchar *decoded_value);
-gboolean       e_composer_paste_html           (EMsgComposer *composer,
-                                                GtkClipboard *clipboard);
 gboolean       e_composer_paste_image          (EMsgComposer *composer,
                                                 GtkClipboard *clipboard);
-gboolean       e_composer_paste_text           (EMsgComposer *composer,
-                                                GtkClipboard *clipboard);
 gboolean       e_composer_paste_uris           (EMsgComposer *composer,
                                                 GtkClipboard *clipboard);
 gboolean       e_composer_selection_is_base64_uris
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index d2b7ee9..defb4da 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -1041,11 +1041,11 @@ composer_add_evolution_composer_mode_header (CamelMedium *medium,
 {
        gboolean html_mode;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       html_mode = e_html_editor_view_get_html_mode (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       html_mode = e_content_editor_get_html_mode (cnt_editor);
 
        camel_medium_add_header (
                medium,
@@ -1260,12 +1260,18 @@ composer_build_message (EMsgComposer *composer,
        } else {
                gchar *text;
                EHTMLEditor *editor;
-               EHTMLEditorView *view;
+               EContentEditor *cnt_editor;
 
                editor = e_msg_composer_get_editor (composer);
-               view = e_html_editor_get_view (editor);
+               cnt_editor = e_html_editor_get_content_editor (editor);
                data = g_byte_array_new ();
-               text = e_html_editor_view_get_text_plain (view);
+
+               text = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
+
                g_byte_array_append (data, (guint8 *) text, strlen (text));
                g_free (text);
 
@@ -1332,21 +1338,17 @@ composer_build_message (EMsgComposer *composer,
                gsize length;
                gboolean pre_encode;
                EHTMLEditor *editor;
-               EHTMLEditorView *view;
-               GList *inline_images = NULL;
+               EContentEditor *cnt_editor;
+               EContentEditorInlineImages *inline_images;
 
                editor = e_msg_composer_get_editor (composer);
-               view = e_html_editor_get_view (editor);
+               cnt_editor = e_html_editor_get_content_editor (editor);
+
+               inline_images = g_new0 (EContentEditorInlineImages, 1);
+               inline_images->from_domain = (gchar *) from_domain;
 
                data = g_byte_array_new ();
                if ((flags & COMPOSER_FLAG_SAVE_DRAFT) != 0) {
-                       gboolean selection_saved;
-                       EHTMLEditor *editor;
-                       EHTMLEditorView *html_view;
-
-                       editor = e_msg_composer_get_editor (composer);
-                       html_view = e_html_editor_get_view (editor);
-
                        /* X-Evolution-Format */
                        composer_add_evolution_format_header (
                                CAMEL_MEDIUM (context->message), flags);
@@ -1355,25 +1357,20 @@ composer_build_message (EMsgComposer *composer,
                        composer_add_evolution_composer_mode_header (
                                CAMEL_MEDIUM (context->message), composer);
 
-                       e_html_editor_view_embed_styles (html_view);
-                       selection_saved = e_html_editor_view_is_selection_saved (html_view);
-                       if (!selection_saved)
-                               e_html_editor_view_save_selection (html_view);
-
-                       text = e_html_editor_view_get_text_html_for_drafts (html_view);
-
-                       e_html_editor_view_remove_embed_styles (html_view);
-                       e_html_editor_view_restore_selection (html_view);
-                       e_html_editor_view_force_spell_check (html_view);
-
-                       if (selection_saved)
-                               e_html_editor_view_save_selection (html_view);
-
-                       length = strlen (text);
-               } else {
-                       text = e_html_editor_view_get_text_html (view, from_domain, &inline_images);
-                       length = strlen (text);
-               }
+                       text = e_content_editor_get_content (
+                               cnt_editor,
+                               E_CONTENT_EDITOR_GET_TEXT_HTML |
+                               E_CONTENT_EDITOR_GET_INLINE_IMAGES,
+                               &inline_images);
+               } else
+                       text = e_content_editor_get_content (
+                               cnt_editor,
+                               E_CONTENT_EDITOR_GET_TEXT_HTML |
+                               E_CONTENT_EDITOR_GET_PROCESSED |
+                               E_CONTENT_EDITOR_GET_INLINE_IMAGES,
+                               &inline_images);
+
+               length = strlen (text);
                g_byte_array_append (data, (guint8 *) text, (guint) length);
                pre_encode = text_requires_quoted_printable (text, length);
                g_free (text);
@@ -1427,7 +1424,7 @@ composer_build_message (EMsgComposer *composer,
 
                /* If there are inlined images, construct a multipart/related
                 * containing the multipart/alternative and the images. */
-               count = g_list_length (inline_images);
+               count = g_list_length (inline_images->images);
                if (count > 0) {
                        guint ii;
                        CamelMultipart *html_with_images;
@@ -1449,7 +1446,7 @@ composer_build_message (EMsgComposer *composer,
                        g_object_unref (body);
 
                        for (ii = 0; ii < count; ii++) {
-                               CamelMimePart *part = g_list_nth_data (inline_images, ii);
+                               CamelMimePart *part = g_list_nth_data (inline_images->images, ii);
                                camel_multipart_add_part (
                                        html_with_images, part);
                        }
@@ -1460,7 +1457,8 @@ composer_build_message (EMsgComposer *composer,
                        context->top_level_part =
                                CAMEL_DATA_WRAPPER (body);
                }
-               g_list_free_full (inline_images, g_object_unref);
+               g_list_free_full (inline_images->images, g_object_unref);
+               g_free (inline_images);
        }
 
        /* If there are attachments, wrap what we've built so far
@@ -1571,18 +1569,26 @@ set_editor_text (EMsgComposer *composer,
                  gboolean set_signature)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
        g_return_if_fail (text != NULL);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (is_html)
-               e_html_editor_view_set_text_html (view, text);
+               e_content_editor_insert_content (
+                       cnt_editor,
+                       text,
+                       E_CONTENT_EDITOR_INSERT_TEXT_HTML |
+                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
        else
-               e_html_editor_view_set_text_plain (view, text);
+               e_content_editor_insert_content (
+                       cnt_editor,
+                       text,
+                       E_CONTENT_EDITOR_INSERT_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
 
        if (set_signature)
                e_composer_update_signature (composer);
@@ -1594,14 +1600,15 @@ static void
 attachment_store_changed_cb (EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
 
        /* Mark the editor as changed so it prompts about unsaved
         * changes on close. */
        editor = e_msg_composer_get_editor (composer);
        if (editor) {
-               view = e_html_editor_get_view (editor);
-               e_html_editor_view_set_changed (view, TRUE);
+               EContentEditor *cnt_editor;
+
+               cnt_editor = e_html_editor_get_content_editor (editor);
+               e_content_editor_set_changed (cnt_editor, TRUE);
        }
 }
 
@@ -1711,8 +1718,8 @@ msg_composer_paste_clipboard_targets_cb (GtkClipboard *clipboard,
                                          gint n_targets,
                                          EMsgComposer *composer)
 {
-       EHTMLEditor *editor = e_msg_composer_get_editor (composer);
-       EHTMLEditorView *editor_view = e_html_editor_get_view (editor);
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
 
        if (targets == NULL || n_targets < 0)
                return;
@@ -1725,67 +1732,65 @@ msg_composer_paste_clipboard_targets_cb (GtkClipboard *clipboard,
                return;
        }
 
-       /* Prefer plain text over HTML when in the plain text mode, but only
-        * when pasting content from outside the editor view. */
-       if (e_html_editor_view_get_html_mode (editor_view) ||
-           e_html_editor_view_is_pasting_content_from_itself (editor_view)) {
-               if (e_targets_include_html (targets, n_targets)) {
-                       e_composer_paste_html (composer, clipboard);
-                       return;
-               }
-
-               if (gtk_targets_include_text (targets, n_targets)) {
-                       e_composer_paste_text (composer, clipboard);
-                       return;
-               }
-       } else {
-               if (gtk_targets_include_text (targets, n_targets)) {
-                       e_composer_paste_text (composer, clipboard);
-                       return;
-               }
-
-               if (e_targets_include_html (targets, n_targets)) {
-                       e_composer_paste_html (composer, clipboard);
-                       return;
-               }
-       }
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (gtk_targets_include_image (targets, n_targets, TRUE)) {
+       if (!e_content_editor_get_html_mode (cnt_editor) &&
+           gtk_targets_include_image (targets, n_targets, TRUE)) {
                e_composer_paste_image (composer, clipboard);
                return;
        }
+
+       composer->priv->ignore_next_paste_clipboard_signals_emission = TRUE;
+
+       g_signal_emit_by_name (
+               cnt_editor,
+               composer->priv->last_signal_was_paste_primary ?
+                       "paste-primary-clipboard" : "paste-clipboard");
 }
 
 static void
-msg_composer_paste_primary_clipboard_cb (EHTMLEditorView *view,
+msg_composer_paste_primary_clipboard_cb (EContentEditor *cnt_editor,
                                          EMsgComposer *composer)
 {
-       GtkClipboard *clipboard;
+       if (composer->priv->ignore_next_paste_clipboard_signals_emission)
+               composer->priv->ignore_next_paste_clipboard_signals_emission = FALSE;
+       else {
+               GtkClipboard *clipboard;
 
-       clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+               clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
 
-       gtk_clipboard_request_targets (
-               clipboard, (GtkClipboardTargetsReceivedFunc)
-               msg_composer_paste_clipboard_targets_cb, composer);
+               composer->priv->last_signal_was_paste_primary = TRUE;
 
-       g_signal_stop_emission_by_name (view, "paste-primary-clipboard");
+               gtk_clipboard_request_targets (
+                       clipboard, (GtkClipboardTargetsReceivedFunc)
+                       msg_composer_paste_clipboard_targets_cb, composer);
+
+               g_signal_stop_emission_by_name (cnt_editor, "paste-primary-clipboard");
+       }
 }
-/* FIXME WK2
+
 static void
-msg_composer_paste_clipboard_cb (EHTMLEditorView *view,
+msg_composer_paste_clipboard_cb (EContentEditor *cnt_editor,
                                  EMsgComposer *composer)
 {
-       GtkClipboard *clipboard;
+       if (composer->priv->ignore_next_paste_clipboard_signals_emission)
+               composer->priv->ignore_next_paste_clipboard_signals_emission = FALSE;
+       else {
+               GtkClipboard *clipboard;
+
+               clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 
-       clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+               composer->priv->last_signal_was_paste_primary = FALSE;
 
-       gtk_clipboard_request_targets (
-               clipboard, (GtkClipboardTargetsReceivedFunc)
-               msg_composer_paste_clipboard_targets_cb, composer);
+               gtk_clipboard_request_targets (
+                       clipboard, (GtkClipboardTargetsReceivedFunc)
+                       msg_composer_paste_clipboard_targets_cb, composer);
 
-       g_signal_stop_emission_by_name (view, "paste-clipboard");
+               g_signal_stop_emission_by_name (cnt_editor, "paste-clipboard");
+       }
 }
-*/
+#if 0
 static gboolean
 msg_composer_drag_motion_cb (GtkWidget *widget,
                              GdkDragContext *context,
@@ -1957,26 +1962,22 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                                     EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        gboolean html_mode, same_widget = FALSE;
        GtkWidget *source_widget;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       html_mode = e_html_editor_view_get_html_mode (view);
+       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;
 
        /* 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)
-                       same_widget = TRUE;
-       }
+       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) {
@@ -2030,21 +2031,20 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        return;
                }
 
-               e_html_editor_view_move_selection_on_point (view, x, y, FALSE);
+               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_html_editor_view_insert_html (view, text);
+                       e_content_editor_insert_content (
+                               cnt_editor,
+                               text,
+                               E_CONTENT_EDITOR_INSERT_TEXT_HTML);
                        g_free (text);
                } while (list_len);
 
-               e_html_editor_view_check_magic_links (view);
-               e_html_editor_view_force_spell_check (view);
-
-               e_html_editor_view_scroll_to_caret (view);
-
                gtk_drag_finish (context, TRUE, FALSE, time);
+
                return;
        }
 
@@ -2052,7 +2052,9 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
        /* If we're receiving URIs and -all- the URIs point to
         * image files, we want the image(s) to be inserted in
         * the message body. */
-       if (html_mode && e_composer_selection_is_image_uris (composer, selection)) {
+       if (html_mode &&
+           (e_composer_selection_is_image_uris (composer, selection) ||
+            e_composer_selection_is_base64_uris (composer, selection))) {
                const guchar *data;
                gint length;
                gint list_len, len;
@@ -2066,36 +2068,12 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        return;
                }
 
-               e_html_editor_view_move_selection_on_point (view, x, y, FALSE);
+               e_content_editor_move_caret_on_coordinates (cnt_editor, x, y, FALSE);
 
                list_len = length;
                do {
                        uri = next_uri ((guchar **) &data, &len, &list_len);
-                       e_html_editor_view_insert_image (view, uri);
-                       g_free (uri);
-               } while (list_len);
-
-               gtk_drag_finish (context, TRUE, FALSE, time);
-       } else if (html_mode && e_composer_selection_is_base64_uris (composer, selection)) {
-               const guchar *data;
-               gint length;
-               gint list_len, len;
-               gchar *uri;
-
-               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_html_editor_view_move_selection_on_point (view, x, y, FALSE);
-
-               list_len = length;
-               do {
-                       uri = next_uri ((guchar **) &data, &len, &list_len);
-                       e_html_editor_view_insert_image (view, uri);
+                       e_content_editor_insert_image (cnt_editor, uri);
                        g_free (uri);
                } while (list_len);
 
@@ -2112,16 +2090,16 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        context, x, y, selection, info, time);
        }
 }
-
+#endif
 static void
 msg_composer_notify_header_cb (EMsgComposer *composer)
 {
+       EContentEditor *cnt_editor;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_changed (cnt_editor, TRUE);
 }
 
 static gboolean
@@ -2368,8 +2346,7 @@ composer_notify_activity_cb (EActivityBar *activity_bar,
                              EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       WebKitWebView *web_view;
+       EContentEditor *cnt_editor;
        gboolean editable = TRUE;
        gboolean busy;
 
@@ -2384,16 +2361,15 @@ composer_notify_activity_cb (EActivityBar *activity_bar,
                e_msg_composer_save_focused_widget (composer);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       web_view = WEBKIT_WEB_VIEW (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (busy) {
-               editable = webkit_web_view_is_editable (web_view);
-               webkit_web_view_set_editable (web_view, FALSE);
+               editable = e_content_editor_is_editable (cnt_editor);
+               e_content_editor_set_editable (cnt_editor, FALSE);
                composer->priv->saved_editable = editable;
        } else {
                editable = composer->priv->saved_editable;
-               webkit_web_view_set_editable (web_view, editable);
+               e_content_editor_set_editable (cnt_editor, editable);
        }
 
        g_object_notify (G_OBJECT (composer), "busy");
@@ -2412,7 +2388,7 @@ msg_composer_constructed (GObject *object)
        EAttachmentStore *store;
        EComposerHeaderTable *table;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkUIManager *ui_manager;
        GtkToggleAction *action;
        GtkTargetList *target_list;
@@ -2429,7 +2405,7 @@ msg_composer_constructed (GObject *object)
        e_composer_private_constructed (composer);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
        ui_manager = e_html_editor_get_ui_manager (editor);
        attachment_view = e_msg_composer_get_attachment_view (composer);
        table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table);
@@ -2484,16 +2460,22 @@ msg_composer_constructed (GObject *object)
        g_object_unref (settings);
 
        /* Clipboard Support */
-/* FIXME WK2
+
        g_signal_connect (
-               view, "paste-clipboard",
+               cnt_editor, "paste-clipboard",
                G_CALLBACK (msg_composer_paste_clipboard_cb), composer);
-*/
+
        g_signal_connect (
-               view, "paste-primary-clipboard",
+               cnt_editor, "paste-primary-clipboard",
                G_CALLBACK (msg_composer_paste_primary_clipboard_cb), composer);
 
+       e_content_editor_reconnect_paste_clipboard_signals (cnt_editor);
+
        /* Drag-and-Drop Support */
+#if 0 /* FIXME WK2 */
+       EHTMLEditorView *view;
+
+       view = e_html_editor_get_view (editor);
 
        g_signal_connect (
                view, "drag-motion",
@@ -2511,7 +2493,7 @@ msg_composer_constructed (GObject *object)
        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);
@@ -2558,12 +2540,12 @@ msg_composer_constructed (GObject *object)
                G_CALLBACK (attachment_store_changed_cb), composer);
 
        /* Initialization may have tripped the "changed" state. */
-       e_html_editor_view_set_changed (view, FALSE);
+       e_content_editor_set_changed (cnt_editor, FALSE);
 
        target_list = e_attachment_view_get_target_list (attachment_view);
        targets = gtk_target_table_new_from_list (target_list, &n_targets);
 
-       target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (view));
+       target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (cnt_editor));
 
        gtk_target_list_add_table (target_list, drag_dest_targets, G_N_ELEMENTS (drag_dest_targets));
        gtk_target_list_add_table (target_list, targets, n_targets);
@@ -2635,7 +2617,7 @@ msg_composer_map (GtkWidget *widget)
        EComposerHeaderTable *table;
        GtkWidget *input_widget;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *text;
 
        /* Chain up to parent's map() method. */
@@ -2666,8 +2648,8 @@ msg_composer_map (GtkWidget *widget)
        }
 
        /* Jump to the editor as a last resort. */
-       view = e_html_editor_get_view (editor);
-       gtk_widget_grab_focus (GTK_WIDGET (view));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
 }
 
 static gboolean
@@ -2677,11 +2659,11 @@ msg_composer_key_press_event (GtkWidget *widget,
        EMsgComposer *composer;
        GtkWidget *input_widget;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        composer = E_MSG_COMPOSER (widget);
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        input_widget =
                e_composer_header_table_get_header (
@@ -2701,56 +2683,21 @@ msg_composer_key_press_event (GtkWidget *widget,
        }
 
        if (event->keyval == GDK_KEY_Tab && gtk_widget_is_focus (input_widget)) {
-               gtk_widget_grab_focus (GTK_WIDGET (view));
+               gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
                return TRUE;
        }
 
-       if (gtk_widget_is_focus (GTK_WIDGET (view))) {
+       if (gtk_widget_is_focus (GTK_WIDGET (cnt_editor))) {
                if (event->keyval == GDK_KEY_ISO_Left_Tab) {
                        gboolean view_processed = FALSE;
 
-                       g_signal_emit_by_name (view, "key-press-event", event, &view_processed);
+                       g_signal_emit_by_name (cnt_editor, "key-press-event", event, &view_processed);
 
                        if (!view_processed)
                                gtk_widget_grab_focus (input_widget);
 
                        return TRUE;
                }
-
-               if ((((event)->state & GDK_SHIFT_MASK) &&
-                   ((event)->keyval == GDK_KEY_Insert)) ||
-                   (((event)->state & GDK_CONTROL_MASK) &&
-                   ((event)->keyval == GDK_KEY_v))) {
-                       g_signal_emit_by_name (
-                               WEBKIT_WEB_VIEW (view), "paste-clipboard");
-                       return TRUE;
-               }
-
-               if (((event)->state & GDK_CONTROL_MASK) &&
-                   ((event)->keyval == GDK_KEY_Insert)) {
-                       g_signal_emit_by_name (
-                               WEBKIT_WEB_VIEW (view), "copy-clipboard");
-                       return TRUE;
-               }
-
-               if (((event)->state & GDK_CONTROL_MASK) &&
-                   ((event)->keyval == GDK_KEY_z)) {
-                       e_html_editor_view_undo (view);
-                       return TRUE;
-               }
-
-               if (((event)->state & (GDK_CONTROL_MASK)) &&
-                   ((event)->keyval == GDK_KEY_Z)) {
-                       e_html_editor_view_redo (view);
-                       return TRUE;
-               }
-
-               if (((event)->state & GDK_SHIFT_MASK) &&
-                   ((event)->keyval == GDK_KEY_Delete)) {
-                       g_signal_emit_by_name (
-                               WEBKIT_WEB_VIEW (view), "cut-clipboard");
-                       return TRUE;
-               }
        }
 
        /* Chain up to parent's key_press_event() method. */
@@ -2907,13 +2854,17 @@ e_msg_composer_class_init (EMsgComposerClass *class)
 static void
 e_msg_composer_init (EMsgComposer *composer)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
+       EContentEditorContentFlags flags;
 
        composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
 
        composer->priv->editor = g_object_ref_sink (e_html_editor_new ());
-       view = e_html_editor_get_view (composer->priv->editor);
-       e_html_editor_view_set_is_editting_message (view, TRUE);
+       cnt_editor = e_html_editor_get_content_editor (composer->priv->editor);
+
+       flags = e_content_editor_get_current_content_flags (cnt_editor);
+       flags |= E_CONTENT_EDITOR_MESSAGE_EDITTING;
+       e_content_editor_set_current_content_flags (cnt_editor, flags);
 }
 
 /**
@@ -2998,7 +2949,7 @@ add_attachments_handle_mime_part (EMsgComposer *composer,
        CamelContentType *content_type;
        CamelDataWrapper *wrapper;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        if (!mime_part)
                return;
@@ -3006,7 +2957,7 @@ add_attachments_handle_mime_part (EMsgComposer *composer,
        content_type = camel_mime_part_get_content_type (mime_part);
        wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (CAMEL_IS_MULTIPART (wrapper)) {
                /* another layer of multipartness... */
@@ -3016,10 +2967,10 @@ add_attachments_handle_mime_part (EMsgComposer *composer,
        } else if (just_inlines) {
                if (camel_mime_part_get_content_id (mime_part) ||
                    camel_mime_part_get_content_location (mime_part))
-                       e_html_editor_view_add_inline_image_from_mime_part (
-                               view, mime_part);
+                       e_content_editor_insert_image_from_mime_part (
+                               cnt_editor, mime_part);
        } else if (related && camel_content_type_is (content_type, "image", "*")) {
-               e_html_editor_view_add_inline_image_from_mime_part (view, mime_part);
+               e_content_editor_insert_image_from_mime_part (cnt_editor, mime_part);
        } else if (camel_content_type_is (content_type, "text", "*") &&
                camel_mime_part_get_filename (mime_part) == NULL) {
                /* Do nothing if this is a text/anything without a
@@ -3414,13 +3365,17 @@ handle_multipart (EMsgComposer *composer,
 
                } else if (depth == 0 && i == 0) {
                        EHTMLEditor *editor;
+                       EContentEditor *cnt_editor;
+                       EContentEditorContentFlags flags;
                        gboolean is_message_from_draft, is_html = FALSE;
                        gchar *html = NULL;
                        gssize length = 0;
 
                        editor = e_msg_composer_get_editor (composer);
-                       is_message_from_draft = e_html_editor_view_is_message_from_draft (
-                               e_html_editor_get_view (editor));
+                       cnt_editor = e_html_editor_get_content_editor (editor);
+
+                       flags = e_content_editor_get_current_content_flags (cnt_editor);
+                       is_message_from_draft = (flags & E_CONTENT_EDITOR_MESSAGE_DRAFT);
                        is_html = camel_content_type_is (content_type, "text", "html");
 
                        /* Since the first part is not multipart/alternative,
@@ -3458,11 +3413,12 @@ handle_multipart (EMsgComposer *composer,
                           camel_mime_part_get_content_location (mime_part)) {
                        /* special in-line attachment */
                        EHTMLEditor *editor;
+                       EContentEditor *cnt_editor;
 
                        editor = e_msg_composer_get_editor (composer);
-                       e_html_editor_view_add_inline_image_from_mime_part (
-                               e_html_editor_get_view (editor), mime_part);
+                       cnt_editor = e_html_editor_get_content_editor (editor);
 
+                       e_content_editor_insert_image_from_mime_part (cnt_editor, mime_part);
                } else {
                        /* normal attachment */
                        e_msg_composer_attach (composer, mime_part);
@@ -3474,44 +3430,20 @@ static void
 set_signature_gui (EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EComposerHeaderTable *table;
        EMailSignatureComboBox *combo_box;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       gchar *uid = NULL;
 
        table = e_msg_composer_get_header_table (composer);
        combo_box = e_composer_header_table_get_signature_combo_box (table);
 
        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)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMGetActiveSignatureUid",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               const gchar *uid;
-               gsize length = 0;
-
-               uid = g_variant_get_string (result, &length);
-
-               if (uid && *uid && length > 0) {
-                       /* The combo box active ID is the signature's ESource UID. */
-                       gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid);
-               }
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-               g_object_unref (result);
+       if ((uid = e_content_editor_get_current_signature_uid (cnt_editor))) {
+               /* The combo box active ID is the signature's ESource UID. */
+               gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid);
        }
 }
 
@@ -3595,7 +3527,8 @@ e_msg_composer_new_with_message (EShell *shell,
        EComposerHeaderTable *table;
        ESource *source = NULL;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
+       EContentEditorContentFlags flags;
        GtkToggleAction *action;
        struct _camel_header_raw *xev;
        gchar *identity_uid;
@@ -3618,9 +3551,9 @@ e_msg_composer_new_with_message (EShell *shell,
 
        composer = e_msg_composer_new (shell);
        priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
-       editor = e_msg_composer_get_editor (composer);
        table = e_msg_composer_get_header_table (composer);
-       view = e_html_editor_get_view (editor);
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (postto) {
                e_composer_header_table_set_post_to_list (table, postto);
@@ -3783,9 +3716,13 @@ e_msg_composer_new_with_message (EShell *shell,
        composer_mode = camel_medium_get_header (
                CAMEL_MEDIUM (message), "X-Evolution-Composer-Mode");
 
+       flags = e_content_editor_get_current_content_flags (cnt_editor);
+
        if (composer_mode && *composer_mode) {
                is_message_from_draft = TRUE;
-               e_html_editor_view_set_is_message_from_draft (view, TRUE);
+
+               flags |= E_CONTENT_EDITOR_MESSAGE_DRAFT;
+               e_content_editor_set_current_content_flags (cnt_editor, flags);
        }
 
        if (format != NULL) {
@@ -3796,22 +3733,12 @@ e_msg_composer_new_with_message (EShell *shell,
 
                flags = g_strsplit (format, ", ", 0);
                for (i = 0; flags[i]; i++) {
-                       if (g_ascii_strcasecmp (flags[i], "text/html") == 0) {
-                               if (composer_mode && g_ascii_strcasecmp (composer_mode, "text/html") == 0) {
-                                       e_html_editor_view_set_html_mode (
-                                               view, TRUE);
-                               } else {
-                                       e_html_editor_view_set_html_mode (
-                                               view, FALSE);
-                               }
-                       } else if (g_ascii_strcasecmp (flags[i], "text/plain") == 0) {
-                               if (composer_mode && g_ascii_strcasecmp (composer_mode, "text/html") == 0) {
-                                       e_html_editor_view_set_html_mode (
-                                               view, TRUE);
-                               } else {
-                                       e_html_editor_view_set_html_mode (
-                                               view, FALSE);
-                               }
+                       if (g_ascii_strcasecmp (flags[i], "text/html") == 0 ||
+                           g_ascii_strcasecmp (flags[i], "text/plain") == 0) {
+                               gboolean html_mode;
+
+                               html_mode = composer_mode && !g_ascii_strcasecmp (composer_mode, "text/html");
+                               e_content_editor_set_html_mode (cnt_editor, html_mode);
                        } else if (g_ascii_strcasecmp (flags[i], "pgp-sign") == 0) {
                                action = GTK_TOGGLE_ACTION (ACTION (PGP_SIGN));
                                gtk_toggle_action_set_active (action, TRUE);
@@ -3945,7 +3872,9 @@ e_msg_composer_new_with_message (EShell *shell,
                e_msg_composer_set_pending_body (composer, html, length, is_html);
        }
 
-       e_html_editor_view_set_is_message_from_edit_as_new (view, TRUE);
+       flags |= E_CONTENT_EDITOR_MESSAGE_EDIT_AS_NEW;
+       e_content_editor_set_current_content_flags (cnt_editor, flags);
+
        priv->set_signature_from_message = TRUE;
 
        /* We wait until now to set the body text because we need to
@@ -3976,7 +3905,7 @@ e_msg_composer_new_redirect (EShell *shell,
        EMsgComposer *composer;
        EComposerHeaderTable *table;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *subject;
 
        g_return_val_if_fail (E_IS_SHELL (shell), NULL);
@@ -3994,8 +3923,8 @@ e_msg_composer_new_redirect (EShell *shell,
        e_composer_header_table_set_subject (table, subject);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), FALSE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_editable (cnt_editor, FALSE);
 
        return composer;
 }
@@ -4054,7 +3983,7 @@ msg_composer_send_cb (EMsgComposer *composer,
        CamelMimeMessage *message;
        EAlertSink *alert_sink;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GError *error = NULL;
 
        alert_sink = e_activity_get_alert_sink (context->activity);
@@ -4087,8 +4016,8 @@ msg_composer_send_cb (EMsgComposer *composer,
 
        /* The callback can set editor 'changed' if anything failed. */
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, TRUE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_changed (cnt_editor, TRUE);
 
        composer->priv->is_sending_message = TRUE;
 
@@ -4148,7 +4077,7 @@ msg_composer_save_to_drafts_cb (EMsgComposer *composer,
        CamelMimeMessage *message;
        EAlertSink *alert_sink;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GError *error = NULL;
 
        alert_sink = e_activity_get_alert_sink (context->activity);
@@ -4190,8 +4119,8 @@ msg_composer_save_to_drafts_cb (EMsgComposer *composer,
 
        /* The callback can set editor 'changed' if anything failed. */
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, FALSE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_changed (cnt_editor, TRUE);
 
        g_signal_emit (
                composer, signals[SAVE_TO_DRAFTS],
@@ -4243,7 +4172,7 @@ msg_composer_save_to_outbox_cb (EMsgComposer *composer,
        CamelMimeMessage *message;
        EAlertSink *alert_sink;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GError *error = NULL;
 
        alert_sink = e_activity_get_alert_sink (context->activity);
@@ -4279,8 +4208,8 @@ msg_composer_save_to_outbox_cb (EMsgComposer *composer,
        async_context_free (context);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_changed (view, FALSE);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_changed (cnt_editor, TRUE);
 }
 
 /**
@@ -4763,7 +4692,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
        EMsgComposerPrivate *priv = composer->priv;
        EComposerHeaderTable *table;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        ESource *source;
        const gchar *identity_uid;
        const gchar *content;
@@ -4771,7 +4700,7 @@ e_msg_composer_set_body (EMsgComposer *composer,
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
        table = e_msg_composer_get_header_table (composer);
 
        /* Disable signature */
@@ -4783,8 +4712,8 @@ e_msg_composer_set_body (EMsgComposer *composer,
        content = _("The composer contains a non-text message body, which cannot be edited.");
        set_editor_text (composer, content, TRUE, FALSE);
 
-       e_html_editor_view_set_html_mode (view, FALSE);
-       webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), FALSE);
+       e_content_editor_set_html_mode (cnt_editor, FALSE);
+       e_content_editor_set_editable (cnt_editor, FALSE);
 
        g_free (priv->mime_body);
        priv->mime_body = g_strdup (body);
@@ -5084,12 +5013,12 @@ e_msg_composer_get_message (EMsgComposer *composer,
        GtkAction *action;
        ComposerFlags flags = 0;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        simple = g_simple_async_result_new (
                G_OBJECT (composer), callback,
@@ -5097,7 +5026,7 @@ e_msg_composer_get_message (EMsgComposer *composer,
 
        g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       if (e_html_editor_view_get_html_mode (view))
+       if (e_content_editor_get_html_mode (cnt_editor))
                flags |= COMPOSER_FLAG_HTML_CONTENT;
 
        action = ACTION (PRIORITIZE_MESSAGE);
@@ -5215,7 +5144,7 @@ e_msg_composer_get_message_draft (EMsgComposer *composer,
                                   gpointer user_data)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GSimpleAsyncResult *simple;
        ComposerFlags flags = COMPOSER_FLAG_SAVE_DRAFT;
        GtkAction *action;
@@ -5229,9 +5158,9 @@ e_msg_composer_get_message_draft (EMsgComposer *composer,
        g_simple_async_result_set_check_cancellable (simple, cancellable);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
        /* We need to remember composer mode */
-       if (e_html_editor_view_get_html_mode (view))
+       if (e_content_editor_get_html_mode (cnt_editor))
                flags |= COMPOSER_FLAG_HTML_MODE;
        /* We want to save HTML content everytime when we save as draft */
        flags |= COMPOSER_FLAG_SAVE_DRAFT;
@@ -5355,52 +5284,6 @@ e_msg_composer_get_reply_to (EMsgComposer *composer)
        return address;
 }
 
-static GByteArray *
-msg_composer_get_content (EMsgComposer *composer,
-                          const gchar *dom_function)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GByteArray *array;
-       GDBusProxy *web_extension;
-       GVariant *result;
-
-       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
-
-       editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       array = g_byte_array_new ();
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return array;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               dom_function,
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               const gchar *content;
-               gsize length = 0;
-
-               /* FIXME WK2 do it better */
-               content = g_variant_get_string (result, &length);
-               if (content && *content && length > 0)
-                       g_byte_array_append (array, (guint8 *) content, length);
-
-               g_object_unref (result);
-       }
-
-       return array;
-}
-
 /**
  * e_msg_composer_get_raw_message_text_without_signature:
  *
@@ -5409,8 +5292,23 @@ msg_composer_get_content (EMsgComposer *composer,
 GByteArray *
 e_msg_composer_get_raw_message_text_without_signature (EMsgComposer *composer)
 {
-       return msg_composer_get_content (composer, "DOMGetRawBodyContentWithoutSignature");
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
+       gchar *content;
+
+       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
+
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       content = e_content_editor_get_content (
+               cnt_editor,
+               E_CONTENT_EDITOR_GET_BODY |
+               E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+               E_CONTENT_EDITOR_GET_EXCLUDE_SIGNATURE,
+               NULL);
 
+       return g_byte_array_new_take ((guint8 *) content, strlen (content));
 }
 
 /**
@@ -5421,7 +5319,22 @@ e_msg_composer_get_raw_message_text_without_signature (EMsgComposer *composer)
 GByteArray *
 e_msg_composer_get_raw_message_text (EMsgComposer *composer)
 {
-       return msg_composer_get_content (composer, "DOMGetRawBodyContent");
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
+       gchar *content;
+
+       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
+
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       content = e_content_editor_get_content (
+               cnt_editor,
+               E_CONTENT_EDITOR_GET_BODY |
+               E_CONTENT_EDITOR_GET_TEXT_PLAIN,
+               NULL);
+
+       return g_byte_array_new_take ((guint8 *) content, strlen (content));
 }
 
 gboolean
@@ -5452,7 +5365,7 @@ e_msg_composer_can_close (EMsgComposer *composer,
 {
        gboolean res = FALSE;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EComposerHeaderTable *table;
        GdkWindow *window;
        GtkWidget *widget;
@@ -5461,14 +5374,14 @@ e_msg_composer_can_close (EMsgComposer *composer,
 
        widget = GTK_WIDGET (composer);
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* this means that there is an async operation running,
         * in which case the composer cannot be closed */
        if (!gtk_action_group_get_sensitive (composer->priv->async_actions))
                return FALSE;
 
-       if (!e_html_editor_view_get_changed (view))
+       if (!e_content_editor_get_changed (cnt_editor))
                return TRUE;
 
        window = gtk_widget_get_window (widget);
@@ -5530,7 +5443,7 @@ e_save_spell_languages (const GList *spell_dicts)
 
        /* Build a list of spell check language codes. */
        lang_array = g_ptr_array_new ();
-/* FIXME WK2
+
        while (spell_dicts != NULL) {
                ESpellDictionary *dict = spell_dicts->data;
                const gchar *language_code;
@@ -5539,7 +5452,7 @@ e_save_spell_languages (const GList *spell_dicts)
                g_ptr_array_add (lang_array, (gpointer) language_code);
 
                spell_dicts = g_list_next (spell_dicts);
-       }*/
+       }
 
        g_ptr_array_add (lang_array, NULL);
 
@@ -5554,15 +5467,6 @@ e_save_spell_languages (const GList *spell_dicts)
 }
 
 void
-e_msg_composer_is_from_new_message (EMsgComposer *composer,
-                                    gboolean is_from_new_message)
-{
-       g_return_if_fail (composer != NULL);
-
-       composer->priv->is_from_new_message = is_from_new_message;
-}
-
-void
 e_msg_composer_save_focused_widget (EMsgComposer *composer)
 {
        GtkWidget *widget;
@@ -5572,8 +5476,8 @@ e_msg_composer_save_focused_widget (EMsgComposer *composer)
        widget = gtk_window_get_focus (GTK_WINDOW (composer));
        composer->priv->focused_entry = widget;
 
-       if (E_IS_HTML_EDITOR_VIEW (widget))
-               e_html_editor_view_save_selection (E_HTML_EDITOR_VIEW (widget));
+       if (E_IS_CONTENT_EDITOR (widget))
+               e_content_editor_selection_save (E_CONTENT_EDITOR (widget));
 
        if (GTK_IS_EDITABLE (widget)) {
                gtk_editable_get_selection_bounds (
@@ -5602,11 +5506,11 @@ e_msg_composer_restore_focus_on_composer (EMsgComposer *composer)
                        composer->priv->focused_entry_selection_end);
        }
 
-       if (E_IS_HTML_EDITOR_VIEW (widget)) {
-               EHTMLEditorView *view = E_HTML_EDITOR_VIEW (widget);
-
-               e_html_editor_view_force_spell_check (view);
-               e_html_editor_view_restore_selection (view);
+       if (E_IS_CONTENT_EDITOR (widget)) {
+               EContentEditor *cnt_editor = E_CONTENT_EDITOR (widget);
+               /* FIXME WK2
+               e_html_editor_view_force_spell_check (view);*/
+               e_content_editor_selection_restore (cnt_editor);
        }
 
        composer->priv->focused_entry = NULL;
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index cf055d6..daaca2b 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -193,9 +193,6 @@ GByteArray *        e_msg_composer_get_raw_message_text
 gboolean       e_msg_composer_is_exiting       (EMsgComposer *composer);
 
 void           e_save_spell_languages          (const GList *spell_languages);
-void           e_msg_composer_is_from_new_message
-                                               (EMsgComposer *composer,
-                                                gboolean is_from_new_message);
 void           e_msg_composer_save_focused_widget
                                                (EMsgComposer *composer);
 void           e_msg_composer_restore_focus_on_composer
diff --git a/configure.ac b/configure.ac
index d725d58..6ed90ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1617,6 +1617,7 @@ modules/text-highlight/Makefile
 modules/tnef-attachment/Makefile
 modules/vcard-inline/Makefile
 modules/web-inspector/Makefile
+modules/webkit-content-editor/Makefile
 plugins/Makefile
 plugins/attachment-reminder/Makefile
 plugins/bbdb/Makefile
diff --git a/doc/reference/evolution-util/evolution-util-sections.txt 
b/doc/reference/evolution-util/evolution-util-sections.txt
index 0ab4883..128bc99 100644
--- a/doc/reference/evolution-util/evolution-util-sections.txt
+++ b/doc/reference/evolution-util/evolution-util-sections.txt
@@ -2194,7 +2194,7 @@ e_html_editor_selection_ref_html_html_editor_view
 e_html_editor_selection_has_text
 e_html_editor_selection_get_caret_word
 e_html_editor_selection_replace_caret_word
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
 e_html_editor_selection_get_alignment
 e_html_editor_selection_set_alignment
 e_html_editor_selection_get_background_color
@@ -2203,10 +2203,10 @@ e_html_editor_selection_get_font_color
 e_html_editor_selection_set_font_color
 e_html_editor_selection_get_font_name
 e_html_editor_selection_set_font_name
-EHTMLEditorSelectionFontSize
+EContentEditorFontSize
 e_html_editor_selection_get_font_size
 e_html_editor_selection_set_font_size
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
 e_html_editor_selection_get_block_format
 e_html_editor_selection_set_block_format
 e_html_editor_selection_is_citation
@@ -2237,7 +2237,7 @@ e_html_editor_selection_insert_text
 e_html_editor_selection_wrap_lines
 e_html_editor_selection_save
 e_html_editor_selection_restore
-EHTMLEditorSelectionGranularity
+EContentEditorGranularity
 e_html_editor_selection_move
 e_html_editor_selection_extend
 <SUBSECTION Standard>
@@ -2314,7 +2314,7 @@ EEditorTextDialogPrivate
 EHTMLEditorView
 e_html_editor_view_new
 e_html_editor_view_get_selection
-EHTMLEditorViewCommand
+EContentEditorCommand
 e_html_editor_view_exec_command
 e_html_editor_view_get_changed
 e_html_editor_view_set_changed
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 161ef22..8f9deb9 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -174,6 +174,9 @@ evolution_util_include_HEADERS =  \
        e-config.h \
        e-conflict-search-selector.h \
        e-contact-store.h \
+       e-content-editor.h \
+       e-content-editor-find-controller.h \
+       e-content-editor-enums.h \
        e-content-request.h \
        e-data-capture.h \
        e-dateedit.h \
@@ -202,7 +205,6 @@ evolution_util_include_HEADERS =  \
        e-focus-tracker.h \
        e-html-editor-actions.h \
        e-html-editor-cell-dialog.h \
-       e-html-editor-defines.h \
        e-html-editor-dialog.h \
        e-html-editor-find-dialog.h \
        e-html-editor-hrule-dialog.h \
@@ -211,11 +213,9 @@ evolution_util_include_HEADERS =  \
        e-html-editor-page-dialog.h \
        e-html-editor-paragraph-dialog.h \
        e-html-editor-replace-dialog.h \
-       e-html-editor-selection.h \
        e-html-editor-spell-check-dialog.h \
        e-html-editor-table-dialog.h \
        e-html-editor-text-dialog.h \
-       e-html-editor-view.h \
        e-html-editor.h \
        e-html-utils.h \
        e-icon-factory.h \
@@ -450,6 +450,8 @@ libevolution_util_la_SOURCES = \
        e-config.c \
        e-conflict-search-selector.c \
        e-contact-store.c \
+       e-content-editor.c \
+       e-content-editor-find-controller.c \
        e-content-request.c \
        e-data-capture.c \
        e-dateedit.c \
@@ -487,11 +489,9 @@ libevolution_util_la_SOURCES = \
        e-html-editor-paragraph-dialog.c \
        e-html-editor-private.h \
        e-html-editor-replace-dialog.c \
-       e-html-editor-selection.c \
        e-html-editor-spell-check-dialog.c \
        e-html-editor-table-dialog.c \
        e-html-editor-text-dialog.c \
-       e-html-editor-view.c \
        e-html-editor.c \
        e-html-utils.c \
        e-icon-factory.c \
diff --git a/e-util/e-content-editor-enums.h b/e-util/e-content-editor-enums.h
new file mode 100644
index 0000000..1c9eb62
--- /dev/null
+++ b/e-util/e-content-editor-enums.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_CONTENT_EDITOR_ENUMS_H
+#define E_CONTENT_EDITOR_ENUMS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+       E_CONTENT_EDITOR_INSERT_CONVERT = 1 << 0,
+       E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT = 1 << 1,
+       E_CONTENT_EDITOR_INSERT_REPLACE_ALL = 1 << 2,
+       E_CONTENT_EDITOR_INSERT_TEXT_HTML = 1 << 3,
+       E_CONTENT_EDITOR_INSERT_TEXT_PLAIN = 1 << 4,
+} EContentEditorInsertContentFlags;
+
+typedef enum {
+       E_CONTENT_EDITOR_GET_BODY = 1 << 0,
+       E_CONTENT_EDITOR_GET_INLINE_IMAGES = 1 << 1,
+       E_CONTENT_EDITOR_GET_PROCESSED = 1 << 2, /* raw or processed */
+       E_CONTENT_EDITOR_GET_TEXT_HTML = 1 << 3,
+       E_CONTENT_EDITOR_GET_TEXT_PLAIN = 1 << 4,
+       E_CONTENT_EDITOR_GET_EXCLUDE_SIGNATURE = 1 << 5
+} EContentEditorGetContentFlags;
+
+typedef enum {
+       E_CONTENT_EDITOR_MESSAGE_DRAFT = 1 << 0,
+       E_CONTENT_EDITOR_MESSAGE_EDIT_AS_NEW = 1 << 1,
+       E_CONTENT_EDITOR_MESSAGE_EDITTING = 1 << 2,
+       E_CONTENT_EDITOR_MESSAGE_FROM_SELECTION = 1 << 3,
+       E_CONTENT_EDITOR_MESSAGE_NEW = 1 << 4
+} EContentEditorContentFlags;
+
+typedef enum {
+       E_CONTENT_EDITOR_NODE_IS_ANCHOR = 1 << 0,
+       E_CONTENT_EDITOR_NODE_IS_H_RULE = 1 << 1,
+       E_CONTENT_EDITOR_NODE_IS_IMAGE = 1 << 2,
+       E_CONTENT_EDITOR_NODE_IS_TABLE = 1 << 3,
+       E_CONTENT_EDITOR_NODE_IS_TABLE_CELL = 1 << 4,
+       E_CONTENT_EDITOR_NODE_IS_TEXT = 1 << 5,
+       E_CONTENT_EDITOR_NODE_IS_TEXT_COLLAPSED = 1 << 6,
+} EContentEditorNodeFlags;
+
+typedef enum {
+       E_CONTENT_EDITOR_BLOCK_FORMAT_NONE = 0,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_PRE,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_ADDRESS,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H1,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H2,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H3,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H4,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H5,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_H6,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN,
+       E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA
+} EContentEditorBlockFormat;
+
+/* The values match the actual size in <font size="n"> */
+typedef enum {
+       E_CONTENT_EDITOR_FONT_SIZE_TINY         = 1,
+       E_CONTENT_EDITOR_FONT_SIZE_SMALL        = 2,
+       E_CONTENT_EDITOR_FONT_SIZE_NORMAL       = 3,
+       E_CONTENT_EDITOR_FONT_SIZE_BIG          = 4,
+       E_CONTENT_EDITOR_FONT_SIZE_BIGGER       = 5,
+       E_CONTENT_EDITOR_FONT_SIZE_LARGE        = 6,
+       E_CONTENT_EDITOR_FONT_SIZE_VERY_LARGE   = 7
+} EContentEditorFontSize;
+
+typedef enum {
+       E_CONTENT_EDITOR_ALIGNMENT_LEFT = 0,
+       E_CONTENT_EDITOR_ALIGNMENT_CENTER,
+       E_CONTENT_EDITOR_ALIGNMENT_RIGHT
+} EContentEditorAlignment;
+
+typedef enum {
+       E_CONTENT_EDITOR_GRANULARITY_CHARACTER = 0,
+       E_CONTENT_EDITOR_GRANULARITY_WORD
+} EContentEditorGranularity;
+
+/**
+ * EContentEditorCommand:
+ * @E_CONTENT_EDITOR_COMMAND_BACKGROUND_COLOR:
+ *   Sets background color to given value.
+ * @E_CONTENT_EDITOR_COMMAND_BOLD:
+ *   Toggles bold formatting of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_COPY:
+ *   Copies current selection to clipboard.
+ * @E_CONTENT_EDITOR_COMMAND_CREATE_LINK:
+ *   Converts current selection to a link that points to URL in value
+ * @E_CONTENT_EDITOR_COMMAND_CUT:
+ *   Cuts current selection to clipboard.
+ * @E_CONTENT_EDITOR_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR:
+ *   (XXX Explain me!)
+ * @E_CONTENT_EDITOR_COMMAND_DELETE:
+ *   Deletes current selection.
+ * @E_CONTENT_EDITOR_COMMAND_FIND_STRING:
+ *   Highlights given string.
+ * @E_CONTENT_EDITOR_COMMAND_FONT_NAME:
+ *   Sets font name to given value.
+ * @E_CONTENT_EDITOR_COMMAND_FONT_SIZE:
+ *   Sets font point size to given value (no units, just number)
+ * @E_CONTENT_EDITOR_COMMAND_FONT_SIZE_DELTA:
+ *   Changes font size by given delta value (no units, just number)
+ * @E_CONTENT_EDITOR_COMMAND_FORE_COLOR:
+ *   Sets font color to given value
+ * @E_CONTENT_EDITOR_COMMAND_FORMAT_BLOCK:
+ *   Sets block type of current paragraph to given format. Allowed formats
+ *   are "BLOCKQUOTE", "H1", "H2", "H3", "H4", "H5", "H6", "P", "PRE" and
+ *   "ADDRESS".
+ * @E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE:
+ *   (XXX Explain me!)
+ * @E_CONTENT_EDITOR_COMMAND_HILITE_COLOR:
+ *   Sets color in which results of "FindString" command should be
+ *   highlighted to given value.
+ * @E_CONTENT_EDITOR_COMMAND_INDENT:
+ *   Indents current paragraph by one level.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_HTML:
+ *   Inserts give HTML code into document.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_HORIZONTAL_RULE:
+ *   Inserts a horizontal rule (&lt;HR&gt;) on current line.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_IMAGE:
+ *   Inserts an image with given source file.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_LINE_BREAK:
+ *   Breaks line at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT:
+ *   Breaks citation at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_ORDERED_LIST:
+ *   Creates an ordered list environment at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_PARAGRAPH:
+ *   Inserts a new paragraph at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_TEXT:
+ *   Inserts given text at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_INSERT_UNORDERED_LIST:
+ *   Creates an undordered list environment at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_ITALIC:
+ *   Toggles italic formatting of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_JUSTIFY_CENTER:
+ *   Aligns current paragraph to center.
+ * @E_CONTENT_EDITOR_COMMAND_JUSTIFY_FULL:
+ *   Justifies current paragraph to block.
+ * @E_CONTENT_EDITOR_COMMAND_JUSTIFY_NONE:
+ *   Removes any justification or alignment of current paragraph.
+ * @E_CONTENT_EDITOR_COMMAND_JUSTIFY_RIGHT:
+ *   Aligns current paragraph to right.
+ * @E_CONTENT_EDITOR_COMMAND_OUTDENT:
+ *   Outdents current paragraph by one level.
+ * @E_CONTENT_EDITOR_COMMAND_PASTE:
+ *   Pastes clipboard content at current cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_PASTE_AND_MATCH_STYLE:
+ *   Pastes clipboard content and matches its style to style at current
+ *   cursor position.
+ * @E_CONTENT_EDITOR_COMMAND_PASTE_AS_PLAIN_TEXT:
+ *   Pastes clipboard content at current cursor position removing any HTML
+ *   formatting.
+ * @E_CONTENT_EDITOR_COMMAND_PRINT:
+ *   Print current document.
+ * @E_CONTENT_EDITOR_COMMAND_REDO:
+ *   Redoes last action.
+ * @E_CONTENT_EDITOR_COMMAND_REMOVE_FORMAT:
+ *   Removes any formatting of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_SELECT_ALL:
+ *   Extends selects to the entire document.
+ * @E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH:
+ *   Toggles strikethrough formatting.
+ * @E_CONTENT_EDITOR_COMMAND_STYLE_WITH_CSS:
+ *   Toggles whether style should be defined in CSS "style" attribute of
+ *   elements or whether to use deprecated &lt;FONT&gt; tags. Depends on
+ *   whether given value is "true" or "false".
+ * @E_CONTENT_EDITOR_COMMAND_SUBSCRIPT:
+ *   Toggles subscript of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_SUPERSCRIPT:
+ *   Toggles superscript of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_TRANSPOSE:
+ *   (XXX Explain me!)
+ * @E_CONTENT_EDITOR_COMMAND_UNDERLINE:
+ *   Toggles underline formatting of current selection.
+ * @E_CONTENT_EDITOR_COMMAND_UNDO:
+ *   Undoes last action.
+ * @E_CONTENT_EDITOR_COMMAND_UNLINK:
+ *   Removes active links (&lt;A&gt;) from current selection (if there's any).
+ * @E_CONTENT_EDITOR_COMMAND_UNSELECT:
+ *   Cancels current selection.
+ * @E_CONTENT_EDITOR_COMMAND_USE_CSS:
+ *   Whether to allow use of CSS or not depending on whether given value is
+ *   "true" or "false".
+ *
+ * Specifies the DOM command to execute in e_editor_widget_exec_command().
+ * Some commands require value to be passed in, which is always stated in the
+ * documentation.
+ */
+typedef enum {
+       E_CONTENT_EDITOR_COMMAND_BACKGROUND_COLOR,
+       E_CONTENT_EDITOR_COMMAND_BOLD,
+       E_CONTENT_EDITOR_COMMAND_COPY,
+       E_CONTENT_EDITOR_COMMAND_CREATE_LINK,
+       E_CONTENT_EDITOR_COMMAND_CUT,
+       E_CONTENT_EDITOR_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR,
+       E_CONTENT_EDITOR_COMMAND_DELETE,
+       E_CONTENT_EDITOR_COMMAND_FIND_STRING,
+       E_CONTENT_EDITOR_COMMAND_FONT_NAME,
+       E_CONTENT_EDITOR_COMMAND_FONT_SIZE,
+       E_CONTENT_EDITOR_COMMAND_FONT_SIZE_DELTA,
+       E_CONTENT_EDITOR_COMMAND_FORE_COLOR,
+       E_CONTENT_EDITOR_COMMAND_FORMAT_BLOCK,
+       E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE,
+       E_CONTENT_EDITOR_COMMAND_HILITE_COLOR,
+       E_CONTENT_EDITOR_COMMAND_INDENT,
+       E_CONTENT_EDITOR_COMMAND_INSERT_HTML,
+       E_CONTENT_EDITOR_COMMAND_INSERT_HORIZONTAL_RULE,
+       E_CONTENT_EDITOR_COMMAND_INSERT_IMAGE,
+       E_CONTENT_EDITOR_COMMAND_INSERT_LINE_BREAK,
+       E_CONTENT_EDITOR_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT,
+       E_CONTENT_EDITOR_COMMAND_INSERT_ORDERED_LIST,
+       E_CONTENT_EDITOR_COMMAND_INSERT_PARAGRAPH,
+       E_CONTENT_EDITOR_COMMAND_INSERT_TEXT,
+       E_CONTENT_EDITOR_COMMAND_INSERT_UNORDERED_LIST,
+       E_CONTENT_EDITOR_COMMAND_ITALIC,
+       E_CONTENT_EDITOR_COMMAND_JUSTIFY_CENTER,
+       E_CONTENT_EDITOR_COMMAND_JUSTIFY_FULL,
+       E_CONTENT_EDITOR_COMMAND_JUSTIFY_LEFT,
+       E_CONTENT_EDITOR_COMMAND_JUSTIFY_NONE,
+       E_CONTENT_EDITOR_COMMAND_JUSTIFY_RIGHT,
+       E_CONTENT_EDITOR_COMMAND_OUTDENT,
+       E_CONTENT_EDITOR_COMMAND_PASTE,
+       E_CONTENT_EDITOR_COMMAND_PASTE_AND_MATCH_STYLE,
+       E_CONTENT_EDITOR_COMMAND_PASTE_AS_PLAIN_TEXT,
+       E_CONTENT_EDITOR_COMMAND_PRINT,
+       E_CONTENT_EDITOR_COMMAND_REDO,
+       E_CONTENT_EDITOR_COMMAND_REMOVE_FORMAT,
+       E_CONTENT_EDITOR_COMMAND_SELECT_ALL,
+       E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH,
+       E_CONTENT_EDITOR_COMMAND_STYLE_WITH_CSS,
+       E_CONTENT_EDITOR_COMMAND_SUBSCRIPT,
+       E_CONTENT_EDITOR_COMMAND_SUPERSCRIPT,
+       E_CONTENT_EDITOR_COMMAND_TRANSPOSE,
+       E_CONTENT_EDITOR_COMMAND_UNDERLINE,
+       E_CONTENT_EDITOR_COMMAND_UNDO,
+       E_CONTENT_EDITOR_COMMAND_UNLINK,
+       E_CONTENT_EDITOR_COMMAND_UNSELECT,
+       E_CONTENT_EDITOR_COMMAND_USE_CSS
+} EContentEditorCommand;
+
+typedef enum {
+       E_CONTENT_EDITOR_SCOPE_CELL = 0,
+       E_CONTENT_EDITOR_SCOPE_ROW,
+       E_CONTENT_EDITOR_SCOPE_COLUMN,
+       E_CONTENT_EDITOR_SCOPE_TABLE
+} EContentEditorScope;
+
+typedef enum {
+       E_CONTENT_EDITOR_UNIT_AUTO = 0,
+       E_CONTENT_EDITOR_UNIT_PIXEL,
+       E_CONTENT_EDITOR_UNIT_PERCENTAGE
+} EContentEditorUnit;
+
+G_END_DECLS
+
+#endif /* E_CONTENT_EDITOR_ENUMS_H */
diff --git a/e-util/e-content-editor-find-controller.c b/e-util/e-content-editor-find-controller.c
new file mode 100644
index 0000000..1ae0241
--- /dev/null
+++ b/e-util/e-content-editor-find-controller.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+
+#include "e-content-editor.h"
+#include "e-marshal.h"
+
+G_DEFINE_INTERFACE (EContentEditorFindController, e_content_editor_find_controller, G_TYPE_OBJECT)
+
+enum {
+       FOUND_TEXT,
+       FAILED_TO_FIND_TEXT,
+       COUNTED_MATCHES,
+       REPLACE_ALL_FINISHED,
+
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+e_content_editor_find_controller_default_init (EContentEditorFindControllerInterface *iface)
+{
+       /**
+        * EContentEditorFindController:found-text
+        *
+        * Emitted when a text is found.
+        */
+       signals[FOUND_TEXT] = g_signal_new (
+               "found-text",
+               E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (
+                       EContentEditorFindControllerInterface,
+                       found_text),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__UINT,
+               G_TYPE_NONE, 1,
+               G_TYPE_UINT);
+
+       /**
+        * EContentEditorFindController:failed-to-find-text
+        *
+        * XXX.
+        */
+       signals[FAILED_TO_FIND_TEXT] = g_signal_new (
+               "load-finished",
+               E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (
+                       EContentEditorFindControllerInterface,
+                       failed_to_find_text),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__VOID,
+               G_TYPE_NONE, 0);
+
+       /**
+        * EContentEditorFindController:counted-matches
+        *
+        * XXX.
+        */
+       signals[COUNTED_MATCHES] = g_signal_new (
+               "counted-matches",
+               E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (
+                       EContentEditorFindControllerInterface,
+                       counted_matches),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__UINT,
+               G_TYPE_NONE, 1,
+               G_TYPE_UINT);
+
+       /**
+        * EContentEditorFindController:replace-all-finished
+        *
+        * XXX.
+        */
+       signals[REPLACE_ALL_FINISHED] = g_signal_new (
+               "replace-all-finished",
+               E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (
+                       EContentEditorFindControllerInterface,
+                       replace_all_finished),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__UINT,
+               G_TYPE_NONE, 1,
+               G_TYPE_UINT);
+}
+
+void
+e_content_editor_find_controller_search_next (EContentEditorFindController *controller)
+{
+       EContentEditorFindControllerInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR_FIND_CONTROLLER (controller));
+
+       iface = E_CONTENT_EDITOR_FIND_CONTROLLER_GET_IFACE (controller);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->search_next != NULL);
+
+       iface->search_next (controller);
+}
+
+void
+e_content_editor_find_controller_search (EContentEditorFindController *controller,
+                                         const gchar *text,
+                                         EContentEditorFindControllerFlags flags)
+{
+       EContentEditorFindControllerInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR_FIND_CONTROLLER (controller));
+       g_return_if_fail (text && *text);
+
+       iface = E_CONTENT_EDITOR_FIND_CONTROLLER_GET_IFACE (controller);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->search != NULL);
+
+       iface->search (controller, text, flags);
+}
+
+void
+e_content_editor_find_controller_search_finish (EContentEditorFindController *controller)
+{
+       EContentEditorFindControllerInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR_FIND_CONTROLLER (controller));
+
+       iface = E_CONTENT_EDITOR_FIND_CONTROLLER_GET_IFACE (controller);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->search_finish != NULL);
+
+       iface->search_finish (controller);
+}
+
+void
+e_content_editor_find_controller_count_matches (EContentEditorFindController *controller,
+                                                const gchar *text,
+                                                EContentEditorFindControllerFlags flags)
+{
+       EContentEditorFindControllerInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR_FIND_CONTROLLER (controller));
+       g_return_if_fail (text && *text);
+
+       iface = E_CONTENT_EDITOR_FIND_CONTROLLER_GET_IFACE (controller);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->count_matches != NULL);
+
+       iface->count_matches (controller, text, flags);
+}
+
+void
+e_content_editor_find_controller_replace_all (EContentEditorFindController *controller,
+                                              const gchar *text,
+                                              const gchar *replacement,
+                                              EContentEditorFindControllerFlags flags)
+{
+       EContentEditorFindControllerInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR_FIND_CONTROLLER (controller));
+       g_return_if_fail (text && *text);
+
+       iface = E_CONTENT_EDITOR_FIND_CONTROLLER_GET_IFACE (controller);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->replace_all != NULL);
+
+       iface->replace_all (controller, text, replacement, flags);
+}
diff --git a/e-util/e-content-editor-find-controller.h b/e-util/e-content-editor-find-controller.h
new file mode 100644
index 0000000..f9ed97b
--- /dev/null
+++ b/e-util/e-content-editor-find-controller.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_CONTENT_EDITOR_FIND_CONTROLLER_H
+#define E_CONTENT_EDITOR_FIND_CONTROLLER_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER e_content_editor_find_controller_get_type ()
+G_DECLARE_INTERFACE (EContentEditorFindController, e_content_editor_find_controller, E, 
CONTENT_EDITOR_FIND_CONTROLLER, GObject)
+
+typedef enum {
+       E_CONTENT_EDITOR_FIND_BACKWARDS,
+       E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE,
+       E_CONTENT_EDITOR_FIND_WRAP_AROUND,
+} EContentEditorFindControllerFlags;
+
+struct _EContentEditorFindControllerInterface {
+       GTypeInterface parent_interface;
+
+       void            (*search)                       (EContentEditorFindController *controller,
+                                                        const gchar *text,
+                                                        EContentEditorFindControllerFlags flags);
+
+       void            (*search_next)                  (EContentEditorFindController *controller);
+
+       void            (*search_finish)                (EContentEditorFindController *controller);
+
+       void            (*count_matches)                (EContentEditorFindController *controller,
+                                                        const gchar *text,
+                                                        EContentEditorFindControllerFlags flags);
+
+       void            (*replace_all)                  (EContentEditorFindController *controller,
+                                                        const gchar *text,
+                                                        const gchar *replacement,
+                                                        EContentEditorFindControllerFlags flags);
+
+       /* Signals */
+       void            (*found_text)                   (EContentEditorFindController *controller,
+                                                        guint match_count);
+
+       void            (*failed_to_find_text)          (EContentEditorFindController *controller);
+
+       void            (*counted_matches)              (EContentEditorFindController *controller,
+                                                        guint match_count);
+
+       void            (*replace_all_finished)         (EContentEditorFindController *controller,
+                                                        guint match_count);
+};
+
+void           e_content_editor_find_controller_search
+                                               (EContentEditorFindController *controller,
+                                                const gchar *text,
+                                                EContentEditorFindControllerFlags flags);
+
+void           e_content_editor_find_controller_search_next
+                                               (EContentEditorFindController *controller);
+
+void           e_content_editor_find_controller_search_finish
+                                               (EContentEditorFindController *controller);
+
+void           e_content_editor_find_controller_count_matches
+                                               (EContentEditorFindController *controller,
+                                                const gchar *text,
+                                                EContentEditorFindControllerFlags flags);
+
+void           e_content_editor_find_controller_replace_all
+                                               (EContentEditorFindController *controller,
+                                                const gchar *text,
+                                                const gchar *replacement,
+                                                EContentEditorFindControllerFlags flags);
+
+G_END_DECLS
+
+#endif /* E_CONTENT_EDITOR_FIND_CONTROLLER_H */
diff --git a/e-util/e-content-editor.c b/e-util/e-content-editor.c
new file mode 100644
index 0000000..230ebe7
--- /dev/null
+++ b/e-util/e-content-editor.c
@@ -0,0 +1,3457 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/libedataserver.h>
+
+#include "e-content-editor.h"
+#include "e-marshal.h"
+
+G_DEFINE_INTERFACE (EContentEditor, e_content_editor, GTK_TYPE_WIDGET);
+
+enum {
+       CONTEXT_MENU_REQUESTED,
+       PASTE_CLIPBOARD,
+       PASTE_PRIMARY_CLIPBOARD,
+       LOAD_FINISHED,
+
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+e_content_editor_default_init (EContentEditorInterface *iface)
+{
+       /**
+        * EContentEditor:can-copy
+        *
+        * Determines whether it's possible to copy to clipboard. The action
+        * is usually disabled when there is no selection to copy.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "can-copy",
+                       _("Can Copy"),
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:can-cut
+        *
+        * Determines whether it's possible to cut to clipboard. The action
+        * is usually disabled when there is no selection to cut.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "can-cut",
+                       _("Can Cut"),
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:can-paste
+        *
+        * Determines whether it's possible to paste from clipboard. The action
+        * is usually disabled when there is no valid content in clipboard to
+        * paste.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "can-paste",
+                       _("Can Paste"),
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:can-redo
+        *
+        * Determines whether it's possible to redo previous action. The action
+        * is usually disabled when there is no action to redo.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "can-redo",
+                       _("Can Redo"),
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:can-undo
+        *
+        * Determines whether it's possible to undo last action. The action
+        * is usually disabled when there is no previous action to undo.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "can-undo",
+                       _("Can Undo"),
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:changed
+        *
+        * Determines whether document has been modified
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "changed",
+                       _("Changed property"),
+                       _("Whether editor changed"),
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:html-mode
+        *
+        * Determines whether HTML or plain text mode is enabled.
+        **/
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "html-mode",
+                       _("HTML Mode"),
+                       _("Edit HTML or plain text"),
+                       TRUE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:editable
+        *
+        * Determines whether the editor is editable or read-only.
+        **/
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "editable",
+                       _("Editable"),
+                       _("Wheter editor is editable"),
+                       TRUE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:alignment
+        *
+        * Holds alignment of current paragraph.
+        */
+       /* FIXME: Convert the enum to a proper type */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_int (
+                       "alignment",
+                       NULL,
+                       NULL,
+                       E_CONTENT_EDITOR_ALIGNMENT_LEFT,
+                       E_CONTENT_EDITOR_ALIGNMENT_RIGHT,
+                       E_CONTENT_EDITOR_ALIGNMENT_LEFT,
+                       G_PARAM_READWRITE));
+
+       /**
+        * EContentEditor:background-color
+        *
+        * Holds background color of current selection or at current cursor
+        * position.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_string (
+                       "background-color",
+                       NULL,
+                       NULL,
+                       NULL,
+                       G_PARAM_READWRITE));
+
+       /**
+        * EContentEditor:block-format
+        *
+        * Holds block format of current paragraph. See
+        * #EContentEditorBlockFormat for valid values.
+        */
+       /* FIXME Convert the EContentEditorBlockFormat
+        *       enum to a proper type. */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_int (
+                       "block-format",
+                       NULL,
+                       NULL,
+                       0,
+                       G_MAXINT,
+                       0,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:bold
+        *
+        * Holds whether current selection or text at current cursor position
+        * is bold.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "bold",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:font-color
+        *
+        * Holds font color of current selection or at current cursor position.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boxed (
+                       "font-color",
+                       NULL,
+                       NULL,
+                       GDK_TYPE_RGBA,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:font-name
+        *
+        * Holds name of font in current selection or at current cursor
+        * position.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_string (
+                       "font-name",
+                       NULL,
+                       NULL,
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:font-size
+        *
+        * Holds point size of current selection or at current cursor position.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_int (
+                       "font-size",
+                       NULL,
+                       NULL,
+                       1,
+                       7,
+                       3,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:indented
+        *
+        * Holds whether current paragraph is indented. This does not include
+        * citations.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "indented",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:italic
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is italic.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "italic",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:monospaced
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is monospaced.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "monospaced",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:strikethrough
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is strikethrough.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "strikethrough",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:superscript
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is in superscript.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "superscript",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:subscript
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is in subscript.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "subscript",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:underline
+        *
+        * Holds whether current selection or letter at current cursor position
+        * is underlined.
+        */
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_boolean (
+                       "underline",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:spell-checker:
+        *
+        * The #ESpellChecker used for spell checking.
+        **/
+       g_object_interface_install_property (
+               iface,
+               g_param_spec_object (
+                       "spell-checker",
+                       "Spell Checker",
+                       "The spell checker",
+                       E_TYPE_SPELL_CHECKER,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_STRINGS));
+
+       /**
+        * EContentEditor:paste-clipboard
+        *
+        * Emitted when user presses middle button on EWebKitContentEditor.
+        */
+       signals[PASTE_CLIPBOARD] = g_signal_new (
+               "paste-clipboard",
+               E_TYPE_CONTENT_EDITOR,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (EContentEditorInterface, paste_clipboard),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__VOID,
+               G_TYPE_NONE, 0);
+
+       /**
+        * EContentEditor:paste-primary-clipboard
+        *
+        * Emitted when user presses middle button on EWebKitContentEditor.
+        */
+       signals[PASTE_PRIMARY_CLIPBOARD] = g_signal_new (
+               "paste-primary-clipboard",
+               E_TYPE_CONTENT_EDITOR,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (EContentEditorInterface, paste_primary_clipboard),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__VOID,
+               G_TYPE_NONE, 0);
+
+       /**
+        * EContentEditor:is-ready
+        *
+        * Emitted when the content editor is ready.
+        */
+       signals[LOAD_FINISHED] = g_signal_new (
+               "load-finished",
+               E_TYPE_CONTENT_EDITOR,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (EContentEditorInterface, load_finished),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__VOID,
+               G_TYPE_NONE, 0);
+
+       /**
+        * EContentEditor:context-menu-requested
+        *
+        * Emitted whenever a context menu is requested.
+        */
+       signals[CONTEXT_MENU_REQUESTED] = g_signal_new (
+               "context-menu-requested",
+               E_TYPE_CONTENT_EDITOR,
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (EContentEditorInterface, context_menu_requested),
+               g_signal_accumulator_true_handled, NULL,
+               e_marshal_BOOLEAN__INT_BOXED,
+               G_TYPE_BOOLEAN, 2,
+               G_TYPE_INT,
+               GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+EContentEditorFindController *
+e_content_editor_get_find_controller (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_find_controller != NULL, NULL);
+
+       return iface->get_find_controller (editor);
+}
+
+void
+e_content_editor_insert_content (EContentEditor *editor,
+                                 const gchar *content,
+                                 EContentEditorInsertContentFlags flags)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (content != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_content != NULL);
+
+       iface->insert_content (editor, content, flags);
+}
+
+gchar *
+e_content_editor_get_content (EContentEditor *editor,
+                              EContentEditorGetContentFlags flags,
+                              EContentEditorInlineImages **inline_images)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+       if ((flags & E_CONTENT_EDITOR_GET_INLINE_IMAGES))
+               g_return_val_if_fail (inline_images != NULL, NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_content != NULL, NULL);
+
+       return iface->get_content (editor, flags, inline_images);
+}
+
+void
+e_content_editor_insert_image_from_mime_part (EContentEditor *editor,
+                                              CamelMimePart *part)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (part != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_image_from_mime_part != NULL);
+
+       iface->insert_image_from_mime_part (editor, part);
+}
+
+/**
+ * e_content_editor_insert_image:
+ * @editor: an #EContentEditor
+ * @uri: an URI of the source image
+ *
+ * Inserts image at current cursor position using @uri as source. When a
+ * text range is selected, it will be replaced by the image.
+ */
+void
+e_content_editor_insert_image (EContentEditor *editor,
+                               const gchar *uri)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (uri != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_image != NULL);
+
+       iface->insert_image (editor, uri);
+}
+
+void
+e_content_editor_insert_emoticon (EContentEditor *editor,
+                                  EEmoticon *emoticon)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (emoticon != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_emoticon != NULL);
+
+       iface->insert_emoticon (editor, emoticon);
+}
+
+void
+e_content_editor_set_current_content_flags (EContentEditor *editor,
+                                            EContentEditorContentFlags flags)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_current_content_flags != NULL);
+
+       iface->set_current_content_flags (editor, flags);
+}
+
+EContentEditorContentFlags
+e_content_editor_get_current_content_flags (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->get_current_content_flags != NULL, 0);
+
+       return iface->get_current_content_flags (editor);
+}
+
+void
+e_content_editor_move_caret_on_coordinates (EContentEditor *editor,
+                                            gint x,
+                                            gint y,
+                                            gboolean cancel_if_not_collapsed)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (x > 0);
+       g_return_if_fail (y > 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->move_caret_on_coordinates != NULL);
+
+       iface->move_caret_on_coordinates (editor, x, y, cancel_if_not_collapsed);
+}
+
+void
+e_content_editor_set_changed (EContentEditor *editor,
+                              gboolean changed)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_changed != NULL);
+
+       iface->set_changed (editor, changed);
+}
+
+gboolean
+e_content_editor_get_changed (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->get_changed != NULL, FALSE);
+
+       return iface->get_changed (editor);
+}
+
+void
+e_content_editor_cut (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cut != NULL);
+
+       iface->cut (editor);
+}
+
+void
+e_content_editor_copy (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->copy != NULL);
+
+       iface->copy (editor);
+}
+
+void
+e_content_editor_paste (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->paste != NULL);
+
+       iface->paste (editor);
+}
+
+gboolean
+e_content_editor_paste_prefer_text_html (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->paste_prefer_text_html != NULL, FALSE);
+
+       return iface->paste_prefer_text_html (editor);
+}
+
+void
+e_content_editor_reconnect_paste_clipboard_signals (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->reconnect_paste_clipboard_signals != NULL);
+
+       iface->reconnect_paste_clipboard_signals (editor);
+}
+
+gboolean
+e_content_editor_can_undo (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->can_undo != NULL, FALSE);
+
+       return iface->can_undo (editor);
+}
+
+void
+e_content_editor_undo (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->undo != NULL);
+
+       iface->undo (editor);
+}
+
+gboolean
+e_content_editor_can_redo (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->can_redo != NULL, FALSE);
+
+       return iface->can_redo (editor);
+}
+
+void
+e_content_editor_redo (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->redo != NULL);
+
+       iface->redo (editor);
+}
+
+void
+e_content_editor_clear_undo_redo_history (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->clear_undo_redo_history != NULL);
+
+       iface->clear_undo_redo_history (editor);
+}
+
+void
+e_content_editor_set_html_mode (EContentEditor *editor,
+                                gboolean html_mode)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_html_mode != NULL);
+
+       iface->set_html_mode (editor, html_mode);
+}
+
+gboolean
+e_content_editor_get_html_mode (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->get_html_mode != NULL, FALSE);
+
+       return iface->get_html_mode (editor);
+}
+
+ESpellChecker *
+e_content_editor_get_spell_checker (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->get_spell_checker != NULL, FALSE);
+
+       return iface->get_spell_checker (editor);
+}
+
+void
+e_content_editor_set_spell_checking_languages (EContentEditor *editor,
+                                               const gchar **languages)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_spell_checking_languages != NULL);
+
+       iface->set_spell_checking_languages (editor, languages);
+}
+
+void
+e_content_editor_set_spell_check (EContentEditor *editor,
+                                  gboolean enable)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_spell_check != NULL);
+
+       iface->set_spell_check (editor, enable);
+}
+
+gboolean
+e_content_editor_get_spell_check (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->get_spell_check != NULL, FALSE);
+
+       return iface->get_spell_check (editor);
+}
+
+void
+e_content_editor_select_all (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->select_all != NULL);
+
+       iface->select_all (editor);
+}
+
+/**
+ * e_content_editor_has_text:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection contains any text.
+ *
+ * Returns: @TRUE when current selection contains text, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_selection_has_text (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->selection_has_text != NULL, FALSE);
+
+       return iface->selection_has_text (editor);
+}
+
+/**
+ * e_content_editor_selection_get_text:
+ * @editor: an #EContentEditor
+ *
+ * Returns currently selected string.
+ *
+ * Returns: A newly allocated string with the content of current selection.
+ * [transfer-full].
+ */
+gchar *
+e_content_editor_selection_get_text (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->selection_get_text != NULL, NULL);
+
+       return iface->selection_get_text (editor);
+}
+
+/**
+ * e_content_editor_get_caret_word:
+ * @editor: an #EContentEditor
+ *
+ * Returns word under cursor.
+ *
+ * Returns: A newly allocated string with current caret word or @NULL when there
+ * is no text under cursor or when selection is active. [transfer-full].
+ */
+gchar *
+e_content_editor_get_caret_word (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_caret_word != NULL, NULL);
+
+       return iface->get_caret_word (editor);
+}
+
+/**
+ * e_content_editor_replace_caret_word:
+ * @editor: an #EContentEditor
+ * @replacement: a string to replace current caret word with
+ *
+ * Replaces current word under cursor with @replacement.
+ */
+void
+e_content_editor_replace_caret_word (EContentEditor *editor,
+                                     const gchar *replacement)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (replacement != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->replace_caret_word != NULL);
+
+       iface->replace_caret_word (editor, replacement);
+}
+
+/**
+ * e_content_editor_is_indented:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current paragraph is indented. This does not include
+ * citations.
+ *
+ * Returns: @TRUE when current paragraph is indented, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_selection_is_indented (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->selection_is_indented != NULL, FALSE);
+
+       return iface->selection_is_indented (editor);
+}
+
+void
+e_content_editor_selection_indent (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_indent != NULL);
+
+       iface->selection_indent (editor);
+}
+
+void
+e_content_editor_selection_unindent (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_unindent != NULL);
+
+       iface->selection_unindent (editor);
+}
+
+/**
+ * e_content_editor_selection_create_link:
+ * @editor: an #EContentEditor
+ * @uri: destination of the new link
+ *
+ * Converts current selection into a link pointing to @url.
+ */
+void
+e_content_editor_selection_create_link (EContentEditor *editor,
+                                        const gchar *uri)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (uri != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_create_link != NULL);
+
+       iface->selection_create_link (editor, uri);
+}
+
+/**
+ * e_content_editor_selection_unlink:
+ * @editor: an #EContentEditor
+ *
+ * Removes any links (&lt;A&gt; elements) from current selection or at current
+ * cursor position.
+ */
+void
+e_content_editor_selection_unlink (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_unlink != NULL);
+
+       iface->selection_unlink (editor);
+}
+
+/**
+ * e_content_editor_replace:
+ * @editor: an #EContentEditor
+ * @replacement: a string to replace current selection with
+ *
+ * Replaces currently selected text with @replacement.
+ */
+void
+e_content_editor_selection_replace (EContentEditor *editor,
+                                    const gchar *replacement)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (replacement != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_replace != NULL);
+
+       iface->selection_replace (editor, replacement);
+}
+
+/**
+ * e_content_editor_selection_save:
+ * @editor: an #EContentEditor
+ *
+ * Saves current cursor position or current selection range. The selection can
+ * be later restored by calling e_content_editor_selection_restore().
+ *
+ * Note that calling e_content_editor_selection_save() overwrites previously saved
+ * position.
+ *
+ * Note that this method inserts special markings into the HTML code that are
+ * used to later restore the selection. It can happen that by deleting some
+ * segments of the document some of the markings are deleted too. In that case
+ * restoring the selection by e_content_editor_selection_restore() can fail. Also by
+ * moving text segments (Cut & Paste) can result in moving the markings
+ * elsewhere, thus e_content_editor_selection_restore() will restore the selection
+ * incorrectly.
+ *
+ * It is recommended to use this method only when you are not planning to make
+ * bigger changes to content or structure of the document (formatting changes
+ * are usually OK).
+ */
+void
+e_content_editor_selection_save (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_save != NULL);
+
+       iface->selection_save (editor);
+}
+
+/**
+ * e_content_editor_selection_restore:
+ * @editor: an #EContentEditor
+ *
+ * Restores cursor position or selection range that was saved by
+ * e_content_editor_selection_save().
+ *
+ * Note that calling this function without calling e_content_editor_selection_save()
+ * before is a programming error and the behavior is undefined.
+ */
+void
+e_content_editor_selection_restore (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_restore != NULL);
+
+       iface->selection_restore (editor);
+}
+
+void
+e_content_editor_selection_wrap (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->selection_wrap != NULL);
+
+       iface->selection_wrap (editor);
+}
+
+void
+e_content_editor_show_inspector (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->show_inspector != NULL);
+
+       iface->show_inspector (editor);
+}
+
+guint
+e_content_editor_get_caret_position (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->get_caret_position != NULL, 0);
+
+       return iface->get_caret_position (editor);
+}
+
+guint
+e_content_editor_get_caret_offset (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->get_caret_offset != NULL, 0);
+
+       return iface->get_caret_offset (editor);
+}
+
+void
+e_content_editor_update_fonts (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->update_fonts != NULL);
+
+       iface->update_fonts (editor);
+}
+
+gboolean
+e_content_editor_is_editable (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_editable != NULL, FALSE);
+
+       return iface->is_editable (editor);
+}
+
+void
+e_content_editor_set_editable (EContentEditor *editor,
+                               gboolean editable)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_editable != NULL);
+
+       iface->set_editable (editor, editable);
+}
+
+gchar *
+e_content_editor_get_current_signature_uid (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_current_signature_uid != NULL, NULL);
+
+       return iface->get_current_signature_uid (editor);
+}
+
+gboolean
+e_content_editor_is_ready (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_ready != NULL, FALSE);
+
+       return iface->is_ready (editor);
+}
+
+char *
+e_content_editor_insert_signature (EContentEditor *editor,
+                                   const gchar *content,
+                                   gboolean is_html,
+                                   const gchar *signature_id,
+                                   gboolean *set_signature_from_message,
+                                   gboolean *check_if_signature_is_changed,
+                                   gboolean *ignore_next_signature_change)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->insert_signature != NULL, FALSE);
+
+       return iface->insert_signature (
+               editor,
+               content,
+               is_html,
+               signature_id,
+               set_signature_from_message,
+               check_if_signature_is_changed,
+               ignore_next_signature_change);
+}
+
+/**
+ * e_content_editor_set_alignment:
+ * @editor: an #EContentEditor
+ * @alignment: an #EContentEditorAlignment value to apply
+ *
+ * Sets alignment of current paragraph to @alignment.
+ */
+void
+e_content_editor_set_alignment (EContentEditor *editor,
+                                EContentEditorAlignment value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_alignment != NULL);
+
+       iface->set_alignment (editor, value);
+}
+
+/**
+ * e_content_editor_get_alignment:
+ * @editor: #an EContentEditor
+ *
+ * Returns alignment of the current paragraph.
+ *
+ * Returns: #EContentEditorAlignment
+ */
+EContentEditorAlignment
+e_content_editor_get_alignment (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (
+               E_IS_CONTENT_EDITOR (editor), E_CONTENT_EDITOR_ALIGNMENT_LEFT);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, E_CONTENT_EDITOR_ALIGNMENT_LEFT);
+       g_return_val_if_fail (iface->get_alignment != NULL, E_CONTENT_EDITOR_ALIGNMENT_LEFT);
+
+       return iface->get_alignment (editor);
+}
+
+/**
+ * e_content_editor_set_block_format:
+ * @editor: an #EContentEditor
+ * @format: an #EContentEditorBlockFormat value
+ *
+ * Changes block format of current paragraph to @format.
+ */
+void
+e_content_editor_set_block_format (EContentEditor *editor,
+                                   EContentEditorBlockFormat value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_block_format != NULL);
+
+       iface->set_block_format (editor, value);
+}
+
+/**
+ * e_content_editor_get_block_format:
+ * @editor: an #EContentEditor
+ *
+ * Returns block format of current paragraph.
+ *
+ * Returns: #EContentEditorBlockFormat
+ */
+EContentEditorBlockFormat
+e_content_editor_get_block_format (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (
+               E_IS_CONTENT_EDITOR (editor),
+               E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (
+               iface != NULL, E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH);
+       g_return_val_if_fail (
+               iface->get_block_format != NULL,
+               E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH);
+
+       return iface->get_block_format (editor);
+}
+
+/**
+ * e_content_editor_set_font_color:
+ * @editor: an #EContentEditor
+ * @rgba: a #GdkRGBA
+ *
+ * Sets font color of current selection or letter at current cursor position to
+ * color defined in @rgba.
+ */
+void
+e_content_editor_set_background_color (EContentEditor *editor,
+                                       const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_background_color != NULL);
+
+       iface->set_background_color (editor, value);
+}
+
+/**
+ * e_content_editor_get_font_color:
+ * @editor: an #EContentEditor
+ * @rgba: a #GdkRGBA object to be set to current font color
+ *
+ * Returns: A color of current text selection or letter at current cursor
+ * position. [transfer-none]
+ */
+const GdkRGBA *
+e_content_editor_get_background_color (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_background_color != NULL, NULL);
+
+       return iface->get_background_color (editor);
+}
+
+/**
+ * e_content_editor_set_font_name:
+ * @editor: an #EContentEditor
+ * @font_name: a font name to apply
+ *
+ * Sets font name of current selection or of letter at current cursor position
+ * to @font_name.
+ */
+void
+e_content_editor_set_font_name (EContentEditor *editor,
+                                const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_font_name != NULL);
+
+       iface->set_font_name (editor, value);
+}
+
+/**
+ * e_content_editor_get_font_name:
+ * @editor: an #EContentEditor
+ *
+ * Returns name of font used in current selection or at letter at current cursor
+ * position.
+ *
+ * Returns: A string with font name. [transfer-none]
+ */
+const gchar *
+e_content_editor_get_font_name (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_font_name != NULL, NULL);
+
+       return iface->get_font_name (editor);
+}
+
+/**
+ * e_content_editor_set_font_color:
+ * @editor: an #EContentEditor
+ * @rgba: a #GdkRGBA
+ *
+ * Sets font color of current selection or letter at current cursor position to
+ * color defined in @rgba.
+ *
+ */
+void
+e_content_editor_set_font_color (EContentEditor *editor,
+                                 const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_font_color != NULL);
+
+       iface->set_font_color (editor, value);
+}
+
+/**
+ * e_content_editor_get_font_color:
+ * @editor: an #EContentEditor
+ *
+ * Returns color of font used in current selection or at letter at current cursor
+ * position.
+ *
+ * Returns: A #GdkRGBA object with current font color. [transfer-none]
+ */
+const GdkRGBA *
+e_content_editor_get_font_color (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->get_font_color != NULL, NULL);
+
+       return iface->get_font_color (editor);
+}
+
+/**
+ * e_content_editor_set_font_size:
+ * @editor: an #EContentEditor
+ * @font_size: point size to apply
+ *
+ * Sets font size of current selection or of letter at current cursor position
+ * to @font_size.
+ */
+void
+e_content_editor_set_font_size (EContentEditor *editor,
+                                guint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_font_size != NULL);
+
+       iface->set_font_size (editor, value);
+}
+
+/**
+ * e_content_editor_is_citation:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current paragraph is a citation.
+ *
+ * Returns: @TRUE when current paragraph is a citation, @FALSE otherwise.
+ */
+guint
+e_content_editor_get_font_size (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 3);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 3);
+       g_return_val_if_fail (iface->get_font_size != NULL, 3);
+
+       return iface->get_font_size (editor);
+}
+
+/**
+ * e_content_editor_set_bold:
+ * @editor: an #EContentEditor
+ * @bold: @TRUE to enable bold, @FALSE to disable
+ *
+ * Toggles bold formatting of current selection or letter at current cursor
+ * position, depending on whether @bold is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_bold (EContentEditor *editor,
+                           gboolean bold)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_bold != NULL);
+
+       iface->set_bold (editor, bold);
+}
+
+/**
+ * e_content_editor_is_bold:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position is bold.
+ *
+ * Returns @TRUE when selection is bold, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_bold (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_bold != NULL, FALSE);
+
+       return iface->is_bold (editor);
+}
+
+/**
+ * e_content_editor_set_bold:
+ * @editor: an #EContentEditor
+ * @bold: @TRUE to enable bold, @FALSE to disable
+ *
+ * Toggles bold formatting of current editor or letter at current cursor
+ * position, depending on whether @bold is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_italic (EContentEditor *editor,
+                             gboolean italic)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_italic != NULL);
+
+       iface->set_italic (editor, italic);
+}
+
+/**
+ * e_content_editor_is_italic:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is italic.
+ *
+ * Returns @TRUE when selection is italic, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_italic (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_italic != NULL, FALSE);
+
+       return iface->is_italic (editor);
+}
+
+/**
+ * e_content_editor_set_monospaced:
+ * @editor: an #EContentEditor
+ * @monospaced: @TRUE to enable monospaced, @FALSE to disable
+ *
+ * Toggles monospaced formatting of current selection or letter at current cursor
+ * position, depending on whether @monospaced is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_monospaced (EContentEditor *editor,
+                                 gboolean monospaced)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_monospaced != NULL);
+
+       iface->set_monospaced (editor, monospaced);
+}
+
+/**
+ * e_content_editor_is_monospaced:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is monospaced.
+ *
+ * Returns @TRUE when selection is monospaced, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_monospaced (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_monospaced != NULL, FALSE);
+
+       return iface->is_monospaced (editor);
+}
+
+/**
+ * e_content_editor_set_strikethrough:
+ * @editor: an #EContentEditor
+ * @strikethrough: @TRUE to enable strikethrough, @FALSE to disable
+ *
+ * Toggles strike through formatting of current selection or letter at current
+ * cursor position, depending on whether @strikethrough is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_strikethrough (EContentEditor *editor,
+                                    gboolean strikethrough)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_strikethrough != NULL);
+
+       iface->set_strikethrough (editor, strikethrough);
+}
+
+/**
+ * e_content_editor_is_strikethrough:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is striked through.
+ *
+ * Returns @TRUE when selection is striked through, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_strikethrough (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_strikethrough != NULL, FALSE);
+
+       return iface->is_strikethrough (editor);
+}
+
+/**
+ * e_content_editor_set_subscript:
+ * @editor: an #EContentEditor
+ * @subscript: @TRUE to enable subscript, @FALSE to disable
+ *
+ * Toggles subscript of current selection or letter at current cursor position,
+ * depending on whether @subscript is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_subscript (EContentEditor *editor,
+                                gboolean subscript)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_subscript != NULL);
+
+       iface->set_subscript (editor, subscript);
+}
+
+/**
+ * e_content_editor_is_subscript:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is in subscript.
+ *
+ * Returns @TRUE when selection is in subscript, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_subscript (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_subscript != NULL, FALSE);
+
+       return iface->is_subscript (editor);
+}
+
+/**
+ * e_content_editor_set_superscript:
+ * @editor: an #EContentEditor
+ * @superscript: @TRUE to enable superscript, @FALSE to disable
+ *
+ * Toggles superscript of current selection or letter at current cursor position,
+ * depending on whether @superscript is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_superscript (EContentEditor *editor,
+                                  gboolean superscript)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_superscript != NULL);
+
+       iface->set_superscript (editor, superscript);
+}
+
+/**
+ * e_content_editor_is_superscript:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is in superscript.
+ *
+ * Returns @TRUE when selection is in superscript, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_superscript (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_superscript != NULL, FALSE);
+
+       return iface->is_superscript (editor);
+}
+
+/**
+ * e_content_editor_set_underline:
+ * @editor: an #EContentEditor
+ * @underline: @TRUE to enable underline, @FALSE to disable
+ *
+ * Toggles underline formatting of current editor or letter at current cursor
+ * position, depending on whether @underline is @TRUE or @FALSE.
+ */
+void
+e_content_editor_set_underline (EContentEditor *editor,
+                                gboolean underline)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->set_underline != NULL);
+
+       iface->set_underline (editor, underline);
+}
+
+/**
+ * e_content_editor_is_underline:
+ * @editor: an #EContentEditor
+ *
+ * Returns whether current selection or letter at current cursor position
+ * is underlined.
+ *
+ * Returns @TRUE when selection is underlined, @FALSE otherwise.
+ */
+gboolean
+e_content_editor_is_underline (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->is_underline != NULL, FALSE);
+
+       return iface->is_underline (editor);
+}
+
+void
+e_content_editor_delete_cell_contents (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->delete_cell_contents != NULL);
+
+       iface->delete_cell_contents (editor);
+}
+
+void
+e_content_editor_delete_column (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->delete_column != NULL);
+
+       iface->delete_column (editor);
+}
+
+void
+e_content_editor_delete_row (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->delete_row != NULL);
+
+       iface->delete_row (editor);
+}
+
+void
+e_content_editor_delete_table (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->delete_table != NULL);
+
+       iface->delete_table (editor);
+}
+
+void
+e_content_editor_insert_column_after (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_column_after != NULL);
+
+       iface->insert_column_after (editor);
+}
+
+void
+e_content_editor_insert_column_before (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_column_before != NULL);
+
+       iface->insert_column_before (editor);
+}
+
+void
+e_content_editor_insert_row_above (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_row_above != NULL);
+
+       iface->insert_row_above (editor);
+}
+
+void
+e_content_editor_insert_row_below (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->insert_row_below != NULL);
+
+       iface->insert_row_below (editor);
+}
+
+gboolean
+e_content_editor_on_h_rule_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->on_h_rule_dialog_open != NULL, FALSE);
+
+       return iface->on_h_rule_dialog_open (editor);
+}
+
+void
+e_content_editor_on_h_rule_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_h_rule_dialog_close != NULL);
+
+       iface->on_h_rule_dialog_close (editor);
+}
+
+void
+e_content_editor_h_rule_set_align (EContentEditor *editor,
+                                   const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->h_rule_set_align != NULL);
+
+       iface->h_rule_set_align (editor, value);
+}
+
+gchar *
+e_content_editor_h_rule_get_align (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->h_rule_get_align != NULL, NULL);
+
+       return iface->h_rule_get_align (editor);
+}
+
+void
+e_content_editor_h_rule_set_size (EContentEditor *editor,
+                                  gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->h_rule_set_size != NULL);
+
+       iface->h_rule_set_size (editor, value);
+}
+
+gint
+e_content_editor_h_rule_get_size (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->h_rule_get_size != NULL, 0);
+
+       return iface->h_rule_get_size (editor);
+}
+
+void
+e_content_editor_h_rule_set_width (EContentEditor *editor,
+                                   gint value,
+                                   EContentEditorUnit unit)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->h_rule_set_width != NULL);
+
+       iface->h_rule_set_width (editor, value, unit);
+}
+
+gint
+e_content_editor_h_rule_get_width (EContentEditor *editor,
+                                   EContentEditorUnit *unit)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+       g_return_val_if_fail (unit != NULL, 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->h_rule_get_width != NULL, 0);
+
+       return iface->h_rule_get_width (editor, unit);
+}
+
+void
+e_content_editor_h_rule_set_no_shade (EContentEditor *editor,
+                                      gboolean value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->h_rule_set_no_shade != NULL);
+
+       iface->h_rule_set_no_shade (editor, value);
+}
+
+gboolean
+e_content_editor_h_rule_get_no_shade (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->h_rule_get_no_shade != NULL, FALSE);
+
+       return iface->h_rule_get_no_shade (editor);
+}
+
+void
+e_content_editor_on_image_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_image_dialog_open != NULL);
+
+       iface->on_image_dialog_open (editor);
+}
+
+void
+e_content_editor_on_image_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_image_dialog_close != NULL);
+
+       iface->on_image_dialog_close (editor);
+}
+
+void
+e_content_editor_image_set_width_follow (EContentEditor *editor,
+                                         gboolean value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_width_follow != NULL);
+
+       iface->image_set_width_follow (editor, value);
+}
+
+void
+e_content_editor_image_set_src (EContentEditor *editor,
+                                const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_src != NULL);
+
+       iface->image_set_src (editor, value);
+}
+
+gchar *
+e_content_editor_image_get_src (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->image_get_src != NULL, FALSE);
+
+       return iface->image_get_src (editor);
+}
+
+void
+e_content_editor_image_set_alt (EContentEditor *editor,
+                                const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_alt != NULL);
+
+       iface->image_set_alt (editor, value);
+}
+
+gchar *
+e_content_editor_image_get_alt (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->image_get_alt != NULL, FALSE);
+
+       return iface->image_get_alt (editor);
+}
+
+void
+e_content_editor_image_set_url (EContentEditor *editor,
+                                const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_url != NULL);
+
+       iface->image_set_url (editor, value);
+}
+
+gchar *
+e_content_editor_image_get_url (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->image_get_url != NULL, FALSE);
+
+       return iface->image_get_url (editor);
+}
+
+void
+e_content_editor_image_set_vspace (EContentEditor *editor,
+                                   gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_vspace != NULL);
+
+       iface->image_set_vspace (editor, value);
+}
+
+gint
+e_content_editor_image_get_vspace (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_vspace != NULL, 0);
+
+       return iface->image_get_vspace (editor);
+}
+
+
+void
+e_content_editor_image_set_hspace (EContentEditor *editor,
+                                   gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_hspace != NULL);
+
+       iface->image_set_hspace (editor, value);
+}
+
+gint
+e_content_editor_image_get_hspace (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_hspace != NULL, 0);
+
+       return iface->image_get_hspace (editor);
+}
+
+void
+e_content_editor_image_set_border (EContentEditor *editor,
+                                   gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_border != NULL);
+
+       iface->image_set_border (editor, value);
+}
+
+gint
+e_content_editor_image_get_border (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->image_get_border != NULL, FALSE);
+
+       return iface->image_get_border (editor);
+}
+
+void
+e_content_editor_image_set_align (EContentEditor *editor,
+                                  const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_align != NULL);
+
+       iface->image_set_align (editor, value);
+}
+
+gchar *
+e_content_editor_image_get_align (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->image_get_align != NULL, FALSE);
+
+       return iface->image_get_align (editor);
+}
+
+gint32
+e_content_editor_image_get_natural_width (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_natural_width != NULL, 0);
+
+       return iface->image_get_natural_width (editor);
+}
+
+gint32
+e_content_editor_image_get_natural_height (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_natural_height != NULL, 0);
+
+       return iface->image_get_natural_height (editor);
+}
+
+void
+e_content_editor_image_set_width (EContentEditor *editor,
+                                  gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_width != NULL);
+
+       iface->image_set_width (editor, value);
+}
+
+gint32
+e_content_editor_image_get_width (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_width != NULL, 0);
+
+       return iface->image_get_width (editor);
+}
+
+void
+e_content_editor_image_set_height (EContentEditor *editor,
+                                   gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_height != NULL);
+
+       iface->image_set_height (editor, value);
+}
+
+gint32
+e_content_editor_image_get_height (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->image_get_height != NULL, 0);
+
+       return iface->image_get_height (editor);
+}
+
+void
+e_content_editor_image_set_height_follow (EContentEditor *editor,
+                                          gboolean value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->image_set_height_follow != NULL);
+
+       iface->image_set_height_follow (editor, value);
+}
+
+void
+e_content_editor_link_get_values (EContentEditor *editor,
+                                  gchar **href,
+                                  gchar **text)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->link_get_values != NULL);
+
+       return iface->link_get_values (editor, href, text);
+}
+
+void
+e_content_editor_link_set_values (EContentEditor *editor,
+                                  const gchar *href,
+                                  const gchar *text)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->link_set_values != NULL);
+
+       iface->link_set_values (editor, href, text);
+}
+
+void
+e_content_editor_on_page_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_page_dialog_open != NULL);
+
+       iface->on_page_dialog_open (editor);
+}
+
+void
+e_content_editor_on_page_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_page_dialog_close != NULL);
+
+       iface->on_page_dialog_close (editor);
+}
+
+void
+e_content_editor_page_set_text_color (EContentEditor *editor,
+                                      const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_set_text_color != NULL);
+
+       iface->page_set_text_color (editor, value);
+}
+
+void
+e_content_editor_page_get_text_color (EContentEditor *editor,
+                                      GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_get_text_color != NULL);
+
+       return iface->page_get_text_color (editor, value);
+}
+
+void
+e_content_editor_page_set_background_color (EContentEditor *editor,
+                                            const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_set_background_color != NULL);
+
+       iface->page_set_background_color (editor, value);
+}
+
+void
+e_content_editor_page_get_background_color (EContentEditor *editor,
+                                            GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_get_background_color != NULL);
+
+       return iface->page_get_background_color (editor, value);
+}
+
+void
+e_content_editor_page_set_link_color (EContentEditor *editor,
+                                      const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_set_link_color != NULL);
+
+       iface->page_set_link_color (editor, value);
+}
+
+void
+e_content_editor_page_get_link_color (EContentEditor *editor,
+                                      GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_get_link_color != NULL);
+
+       return iface->page_get_link_color (editor, value);
+}
+
+void
+e_content_editor_page_set_visited_link_color (EContentEditor *editor,
+                                              const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_set_visited_link_color != NULL);
+
+       iface->page_set_visited_link_color (editor, value);
+}
+
+void
+e_content_editor_page_get_visited_link_color (EContentEditor *editor,
+                                              GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_get_visited_link_color != NULL);
+
+       return iface->page_get_visited_link_color (editor, value);
+}
+
+/* uri could be NULL -> removes the current image */
+void
+e_content_editor_page_set_background_image_uri (EContentEditor *editor,
+                                                const gchar *uri)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->page_set_background_image_uri != NULL);
+
+       iface->page_set_background_image_uri (editor, uri);
+}
+
+gchar *
+e_content_editor_page_get_background_image_uri (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->page_get_background_image_uri != NULL, NULL);
+
+       return iface->page_get_background_image_uri (editor);
+}
+
+void
+e_content_editor_on_cell_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_cell_dialog_open != NULL);
+
+       iface->on_cell_dialog_open (editor);
+}
+
+void
+e_content_editor_on_cell_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_cell_dialog_close != NULL);
+
+       iface->on_cell_dialog_close (editor);
+}
+
+void
+e_content_editor_cell_set_v_align (EContentEditor *editor,
+                                   const gchar *value,
+                                   EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_v_align != NULL);
+
+       iface->cell_set_v_align (editor, value, scope);
+}
+
+gchar *
+e_content_editor_cell_get_v_align (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->cell_get_v_align != NULL, NULL);
+
+       return iface->cell_get_v_align (editor);
+}
+
+void
+e_content_editor_cell_set_align        (EContentEditor *editor,
+                                 const gchar *value,
+                                 EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_align != NULL);
+
+       iface->cell_set_align (editor, value, scope);
+}
+
+gchar *
+e_content_editor_cell_get_align (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->cell_get_align != NULL, NULL);
+
+       return iface->cell_get_align (editor);
+}
+
+void
+e_content_editor_cell_set_wrap (EContentEditor *editor,
+                                gboolean value,
+                                EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_wrap != NULL);
+
+       iface->cell_set_wrap (editor, value, scope);
+}
+
+gboolean
+e_content_editor_cell_get_wrap (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->cell_get_wrap != NULL, FALSE);
+
+       return iface->cell_get_wrap (editor);
+}
+
+void
+e_content_editor_cell_set_header_style (EContentEditor *editor,
+                                        gboolean value,
+                                        EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_header_style != NULL);
+
+       iface->cell_set_header_style (editor, value, scope);
+}
+
+gboolean
+e_content_editor_cell_is_header (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->cell_is_header != NULL, FALSE);
+
+       return iface->cell_is_header (editor);
+}
+
+void
+e_content_editor_cell_set_width (EContentEditor *editor,
+                                 gint value,
+                                 EContentEditorUnit unit,
+                                 EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_width != NULL);
+
+       iface->cell_set_width (editor, value, unit, scope);
+}
+
+gint
+e_content_editor_cell_get_width (EContentEditor *editor,
+                                 EContentEditorUnit *unit)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+       g_return_val_if_fail (unit != NULL, 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->cell_get_width != NULL, 0);
+
+       return iface->cell_get_width (editor, unit);
+}
+
+void
+e_content_editor_cell_set_row_span (EContentEditor *editor,
+                                    gint value,
+                                    EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_row_span != NULL);
+
+       iface->cell_set_row_span (editor, value, scope);
+}
+
+gint
+e_content_editor_cell_get_row_span (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->cell_get_row_span != NULL, 0);
+
+       return iface->cell_get_row_span (editor);
+}
+
+void
+e_content_editor_cell_set_col_span (EContentEditor *editor,
+                                    gint value,
+                                    EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_col_span != NULL);
+
+       iface->cell_set_col_span (editor, value, scope);
+}
+
+gint
+e_content_editor_cell_get_col_span (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->cell_get_col_span != NULL, 0);
+
+       return iface->cell_get_col_span (editor);
+}
+
+/* uri could be NULL -> removes the current image */
+void
+e_content_editor_cell_set_background_image_uri (EContentEditor *editor,
+                                                const gchar *uri)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_background_image_uri != NULL);
+
+       iface->cell_set_background_image_uri (editor, uri);
+}
+
+gchar *
+e_content_editor_cell_get_background_image_uri (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->cell_get_background_image_uri != NULL, NULL);
+
+       return iface->cell_get_background_image_uri (editor);
+}
+
+void
+e_content_editor_cell_set_background_color (EContentEditor *editor,
+                                            const GdkRGBA *value,
+                                            EContentEditorScope scope)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+       g_return_if_fail (value != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_set_background_color != NULL);
+
+       iface->cell_set_background_color (editor, value, scope);
+}
+
+void
+e_content_editor_cell_get_background_color (EContentEditor *editor,
+                                            GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->cell_get_background_color != NULL);
+
+       iface->cell_get_background_color (editor, value);
+}
+
+void
+e_content_editor_table_set_row_count (EContentEditor *editor,
+                                      guint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_row_count != NULL);
+
+       iface->table_set_row_count (editor, value);
+}
+
+guint
+e_content_editor_table_get_row_count (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_row_count != NULL, 0);
+
+       return iface->table_get_row_count (editor);
+}
+
+void
+e_content_editor_table_set_column_count (EContentEditor *editor,
+                                         guint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_column_count != NULL);
+
+       iface->table_set_column_count (editor, value);
+}
+
+guint
+e_content_editor_table_get_column_count (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_column_count != NULL, 0);
+
+       return iface->table_get_column_count (editor);
+}
+
+void
+e_content_editor_table_set_width (EContentEditor *editor,
+                                  gint value,
+                                  EContentEditorUnit unit)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_width != NULL);
+
+       iface->table_set_width (editor, value, unit);
+}
+
+guint
+e_content_editor_table_get_width (EContentEditor *editor,
+                                  EContentEditorUnit *unit)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_width != NULL, 0);
+
+       return iface->table_get_width (editor, unit);
+}
+
+void
+e_content_editor_table_set_align (EContentEditor *editor,
+                                  const gchar *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_align != NULL);
+
+       iface->table_set_align (editor, value);
+}
+
+gchar *
+e_content_editor_table_get_align (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->table_get_align != NULL, NULL);
+
+       return iface->table_get_align (editor);
+}
+
+void
+e_content_editor_table_set_padding (EContentEditor *editor,
+                                    gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_padding != NULL);
+
+       iface->table_set_padding (editor, value);
+}
+
+gint
+e_content_editor_table_get_padding (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_padding != NULL, 0);
+
+       return iface->table_get_padding (editor);
+}
+
+void
+e_content_editor_table_set_spacing (EContentEditor *editor,
+                                    gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_spacing != NULL);
+
+       iface->table_set_spacing (editor, value);
+}
+
+gint
+e_content_editor_table_get_spacing (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_spacing != NULL, 0);
+
+       return iface->table_get_spacing (editor);
+}
+
+void
+e_content_editor_table_set_border (EContentEditor *editor,
+                                   gint value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_border != NULL);
+
+       iface->table_set_border (editor, value);
+}
+
+gint
+e_content_editor_table_get_border (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), 0);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, 0);
+       g_return_val_if_fail (iface->table_get_border != NULL, 0);
+
+       return iface->table_get_border (editor);
+}
+
+gchar *
+e_content_editor_table_get_background_image_uri (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->table_get_background_image_uri != NULL, NULL);
+
+       return iface->table_get_background_image_uri (editor);
+}
+
+void
+e_content_editor_table_set_background_image_uri (EContentEditor *editor,
+                                                 const gchar *uri)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_background_image_uri != NULL);
+
+       iface->table_set_background_image_uri (editor, uri);
+}
+
+void
+e_content_editor_table_get_background_color (EContentEditor *editor,
+                                             GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_get_background_color != NULL);
+
+       iface->table_get_background_color (editor, value);
+}
+
+void
+e_content_editor_table_set_background_color (EContentEditor *editor,
+                                             const GdkRGBA *value)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->table_set_background_color != NULL);
+
+       iface->table_set_background_color (editor, value);
+}
+
+gboolean
+e_content_editor_on_table_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), FALSE);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, FALSE);
+       g_return_val_if_fail (iface->on_table_dialog_open != NULL, FALSE);
+
+       return iface->on_table_dialog_open (editor);
+}
+
+void
+e_content_editor_on_table_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_table_dialog_close != NULL);
+
+       iface->on_table_dialog_close (editor);
+}
+
+void
+e_content_editor_on_spell_check_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_spell_check_dialog_close != NULL);
+
+       iface->on_spell_check_dialog_close (editor);
+}
+
+void
+e_content_editor_on_spell_check_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_spell_check_dialog_close != NULL);
+
+       iface->on_spell_check_dialog_close (editor);
+}
+
+gchar *
+e_content_editor_spell_check_next_word (EContentEditor *editor,
+                                        const gchar *word)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->spell_check_next_word != NULL, NULL);
+
+       return iface->spell_check_next_word (editor, word);
+}
+
+gchar *
+e_content_editor_spell_check_prev_word (EContentEditor *editor,
+                                        const gchar *word)
+{
+       EContentEditorInterface *iface;
+
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (editor), NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (iface->spell_check_prev_word != NULL, NULL);
+
+       return iface->spell_check_prev_word (editor, word);
+}
+
+void
+e_content_editor_on_replace_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_replace_dialog_open != NULL);
+
+       iface->on_replace_dialog_open (editor);
+}
+
+void
+e_content_editor_on_replace_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_replace_dialog_close != NULL);
+
+       iface->on_replace_dialog_close (editor);
+}
+
+void
+e_content_editor_on_find_dialog_open (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_find_dialog_open != NULL);
+
+       iface->on_find_dialog_open (editor);
+}
+
+void
+e_content_editor_on_find_dialog_close (EContentEditor *editor)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (editor));
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->on_find_dialog_close != NULL);
+
+       iface->on_find_dialog_close (editor);
+}
+
diff --git a/e-util/e-content-editor.h b/e-util/e-content-editor.h
new file mode 100644
index 0000000..eca62c5
--- /dev/null
+++ b/e-util/e-content-editor.h
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_CONTENT_EDITOR_H
+#define E_CONTENT_EDITOR_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+#include "e-content-editor-find-controller.h"
+#include "e-content-editor-enums.h"
+
+#include <e-util/e-emoticon.h>
+#include <e-util/e-spell-checker.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CONTENT_EDITOR e_content_editor_get_type ()
+G_DECLARE_INTERFACE (EContentEditor, e_content_editor, E, CONTENT_EDITOR, GtkWidget)
+
+typedef struct {
+       const gchar *from_domain;
+       GList *images;
+} EContentEditorInlineImages;
+
+struct _EContentEditorInterface {
+       GTypeInterface parent_interface;
+
+       EContentEditorFindController *
+                       (*get_find_controller)          (EContentEditor *editor);
+
+       void            (*insert_content)               (EContentEditor *editor,
+                                                        const gchar *content,
+                                                        EContentEditorInsertContentFlags flags);
+
+       gchar *         (*get_content)                  (EContentEditor *editor,
+                                                        EContentEditorGetContentFlags flags,
+                                                        EContentEditorInlineImages **inline_images);
+
+       void            (*insert_image)                 (EContentEditor *editor,
+                                                        const gchar *uri);
+
+       void            (*insert_image_from_mime_part)
+                                                       (EContentEditor *editor,
+                                                        CamelMimePart *part);
+
+       void            (*insert_emoticon)              (EContentEditor *editor,
+                                                        EEmoticon *emoticon);
+
+       void            (*set_current_content_flags)    (EContentEditor *editor,
+                                                        EContentEditorContentFlags flags);
+
+       EContentEditorContentFlags
+                       (*get_current_content_flags)    (EContentEditor *editor);
+
+       void            (*move_caret_on_coordinates)    (EContentEditor *editor,
+                                                        gint x,
+                                                        gint y,
+                                                        gboolean cancel_if_not_collapsed);
+
+       void            (*set_changed)                  (EContentEditor *editor,
+                                                        gboolean changed);
+
+       gboolean        (*get_changed)                  (EContentEditor *editor);
+
+       void            (*cut)                          (EContentEditor *editor);
+
+       void            (*copy)                         (EContentEditor *editor);
+
+       void            (*paste)                        (EContentEditor *editor);
+
+       gboolean        (*paste_prefer_text_html)       (EContentEditor *editor);
+
+       void            (*reconnect_paste_clipboard_signals)
+                                                       (EContentEditor *editor);
+
+       gboolean        (*can_undo)                     (EContentEditor *editor);
+
+       void            (*undo)                         (EContentEditor *editor);
+
+       gboolean        (*can_redo)                     (EContentEditor *editor);
+
+       void            (*redo)                         (EContentEditor *editor);
+
+       void            (*clear_undo_redo_history)      (EContentEditor *editor);
+
+       void            (*set_html_mode)                (EContentEditor *editor,
+                                                        gboolean html_mode);
+
+       gboolean        (*get_html_mode)                (EContentEditor *editor);
+
+       ESpellChecker * (*get_spell_checker)            (EContentEditor *editor);
+
+       void            (*set_spell_checking_languages) (EContentEditor *editor,
+                                                        const gchar **languages);
+
+       void            (*set_spell_check)              (EContentEditor *editor,
+                                                        gboolean enable);
+
+       gboolean        (*get_spell_check)              (EContentEditor *editor);
+
+       gboolean        (*selection_has_text)           (EContentEditor *editor);
+
+       gchar *         (*selection_get_text)           (EContentEditor *editor);
+
+       gchar *         (*get_caret_word)               (EContentEditor *editor);
+
+       void            (*replace_caret_word)           (EContentEditor *editor,
+                                                        const gchar *replacement);
+
+       void            (*select_all)                   (EContentEditor *editor);
+
+       gboolean        (*selection_is_indented)        (EContentEditor *editor);
+
+       void            (*selection_indent)             (EContentEditor *editor);
+
+       void            (*selection_unindent)           (EContentEditor *editor);
+
+       void            (*selection_create_link)        (EContentEditor *editor,
+                                                        const gchar *uri);
+
+       void            (*selection_unlink)             (EContentEditor *editor);
+
+       void            (*selection_replace)            (EContentEditor *editor,
+                                                        const gchar *replacement);
+
+       void            (*selection_save)               (EContentEditor *editor);
+
+       void            (*selection_restore)            (EContentEditor *editor);
+
+       void            (*selection_wrap)               (EContentEditor *editor);
+
+       void            (*show_inspector)               (EContentEditor *editor);
+
+       guint           (*get_caret_position)           (EContentEditor *editor);
+
+       guint           (*get_caret_offset)             (EContentEditor *editor);
+
+       void            (*update_fonts)                 (EContentEditor *editor);
+
+       gboolean        (*is_editable)                  (EContentEditor *editor);
+
+       void            (*set_editable)                 (EContentEditor *editor,
+                                                        gboolean editable);
+
+       gchar *         (*get_current_signature_uid)    (EContentEditor *editor);
+
+       gboolean        (*is_ready)                     (EContentEditor *editor);
+
+       char *          (*insert_signature)             (EContentEditor *editor,
+                                                        const gchar *content,
+                                                        gboolean is_html,
+                                                        const gchar *signature_id,
+                                                        gboolean *set_signature_from_message,
+                                                        gboolean *check_if_signature_is_changed,
+                                                        gboolean *ignore_next_signature_change);
+
+       void            (*set_alignment)                (EContentEditor *editor,
+                                                        EContentEditorAlignment value);
+
+       EContentEditorAlignment
+                       (*get_alignment)                (EContentEditor *editor);
+
+       void            (*set_block_format)             (EContentEditor *editor,
+                                                        EContentEditorBlockFormat value);
+
+       EContentEditorBlockFormat
+                       (*get_block_format)             (EContentEditor *editor);
+
+       void            (*set_background_color)         (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       const GdkRGBA * (*get_background_color)         (EContentEditor *editor);
+
+       void            (*set_font_name)                (EContentEditor *editor,
+                                                        const gchar *value);
+
+       const gchar *   (*get_font_name)                (EContentEditor *editor);
+
+       void            (*set_font_color)               (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       const GdkRGBA * (*get_font_color)               (EContentEditor *editor);
+
+       void            (*set_font_size)                (EContentEditor *editor,
+                                                        guint value);
+
+       guint           (*get_font_size)                (EContentEditor *editor);
+
+       void            (*set_bold)                     (EContentEditor *editor,
+                                                        gboolean bold);
+
+       gboolean        (*is_bold)                      (EContentEditor *editor);
+
+       void            (*set_italic)                   (EContentEditor *editor,
+                                                        gboolean italic);
+
+       gboolean        (*is_italic)                    (EContentEditor *editor);
+
+       void            (*set_monospaced)               (EContentEditor *editor,
+                                                        gboolean monospaced);
+
+       gboolean        (*is_monospaced)                (EContentEditor *editor);
+
+       void            (*set_strikethrough)            (EContentEditor *editor,
+                                                        gboolean strikethrough);
+
+       gboolean        (*is_strikethrough)             (EContentEditor *editor);
+
+       void            (*set_subscript)                (EContentEditor *editor,
+                                                        gboolean subscript);
+
+       gboolean        (*is_subscript)                 (EContentEditor *editor);
+
+       void            (*set_superscript)              (EContentEditor *editor,
+                                                        gboolean superscript);
+
+       gboolean        (*is_superscript)               (EContentEditor *editor);
+
+       void            (*set_underline)                (EContentEditor *editor,
+                                                        gboolean underline);
+
+       gboolean        (*is_underline)                 (EContentEditor *editor);
+
+       void            (*delete_cell_contents)         (EContentEditor *editor);
+
+       void            (*delete_column)                (EContentEditor *editor);
+
+       void            (*delete_row)                   (EContentEditor *editor);
+
+       void            (*delete_table)                 (EContentEditor *editor);
+
+       void            (*insert_column_after)          (EContentEditor *editor);
+
+       void            (*insert_column_before)         (EContentEditor *editor);
+
+       void            (*insert_row_above)             (EContentEditor *editor);
+
+       void            (*insert_row_below)             (EContentEditor *editor);
+
+       gboolean        (*on_h_rule_dialog_open)        (EContentEditor *editor);
+
+       void            (*on_h_rule_dialog_close)       (EContentEditor *editor);
+
+       void            (*h_rule_set_align)             (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*h_rule_get_align)             (EContentEditor *editor);
+
+       void            (*h_rule_set_size)              (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*h_rule_get_size)              (EContentEditor *editor);
+
+       void            (*h_rule_set_width)             (EContentEditor *editor,
+                                                        gint value,
+                                                        EContentEditorUnit unit);
+
+       gint            (*h_rule_get_width)             (EContentEditor *editor,
+                                                        EContentEditorUnit *unit);
+
+       void            (*h_rule_set_no_shade)          (EContentEditor *editor,
+                                                        gboolean value);
+
+       gboolean        (*h_rule_get_no_shade)          (EContentEditor *editor);
+
+       void            (*on_image_dialog_open)         (EContentEditor *editor);
+
+       void            (*on_image_dialog_close)        (EContentEditor *editor);
+
+       void            (*image_set_src)                (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*image_get_src)                (EContentEditor *editor);
+
+       void            (*image_set_alt)                (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*image_get_alt)                (EContentEditor *editor);
+
+       gint32          (*image_get_natural_width)      (EContentEditor *editor);
+
+       gint32          (*image_get_width)              (EContentEditor *editor);
+
+       void            (*image_set_width)              (EContentEditor *editor,
+                                                        gint value);
+
+       void            (*image_set_width_follow)       (EContentEditor *editor,
+                                                        gboolean value);
+
+       gint32          (*image_get_natural_height)     (EContentEditor *editor);
+
+       gint32          (*image_get_height)             (EContentEditor *editor);
+
+       void            (*image_set_height)             (EContentEditor *editor,
+                                                        gint value);
+
+       void            (*image_set_height_follow)      (EContentEditor *editor,
+                                                        gboolean value);
+
+       void            (*image_set_url)                (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*image_get_url)                (EContentEditor *editor);
+
+       void            (*image_set_vspace)             (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*image_get_vspace)             (EContentEditor *editor);
+
+       void            (*image_set_hspace)             (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*image_get_hspace)             (EContentEditor *editor);
+
+       void            (*image_set_border)             (EContentEditor *editor,
+                                                        gint border);
+
+       gint            (*image_get_border)             (EContentEditor *editor);
+
+       void            (*image_set_align)              (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*image_get_align)              (EContentEditor *editor);
+
+       void            (*link_get_values)              (EContentEditor *editor,
+                                                        gchar **href,
+                                                        gchar **text);
+
+       void            (*link_set_values)              (EContentEditor *editor,
+                                                        const gchar *href,
+                                                        const gchar *text);
+
+       void            (*on_page_dialog_open)          (EContentEditor *editor);
+
+       void            (*on_page_dialog_close)         (EContentEditor *editor);
+
+       void            (*page_set_text_color)          (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       void            (*page_get_text_color)          (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*page_set_background_color)    (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       void            (*page_get_background_color)    (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*page_set_link_color)          (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       void            (*page_get_link_color)          (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*page_set_visited_link_color)  (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       void            (*page_get_visited_link_color)  (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*page_set_background_image_uri)
+                                                       (EContentEditor *editor,
+                                                        const gchar *uri);
+
+       gchar *         (*page_get_background_image_uri)
+                                                       (EContentEditor *editor);
+
+       void            (*on_cell_dialog_open)          (EContentEditor *editor);
+
+       void            (*on_cell_dialog_close)         (EContentEditor *editor);
+
+       void            (*cell_set_v_align)             (EContentEditor *editor,
+                                                        const gchar *value,
+                                                        EContentEditorScope scope);
+
+       gchar *         (*cell_get_v_align)             (EContentEditor *editor);
+
+       void            (*cell_set_align)               (EContentEditor *editor,
+                                                        const gchar *value,
+                                                        EContentEditorScope scope);
+
+       gchar *         (*cell_get_align)               (EContentEditor *editor);
+
+       void            (*cell_set_wrap)                (EContentEditor *editor,
+                                                        gboolean value,
+                                                        EContentEditorScope scope);
+
+       gboolean        (*cell_get_wrap)                (EContentEditor *editor);
+
+       void            (*cell_set_header_style)        (EContentEditor *editor,
+                                                        gboolean value,
+                                                        EContentEditorScope scope);
+
+       gboolean        (*cell_is_header)               (EContentEditor *editor);
+
+       void            (*cell_set_width)               (EContentEditor *editor,
+                                                        gint value,
+                                                        EContentEditorUnit unit,
+                                                        EContentEditorScope scope);
+
+       gint            (*cell_get_width)               (EContentEditor *editor,
+                                                        EContentEditorUnit *unit);
+
+       void            (*cell_set_row_span)            (EContentEditor *editor,
+                                                        gint value,
+                                                        EContentEditorScope scope);
+
+       gint            (*cell_get_row_span)            (EContentEditor *editor);
+
+       void            (*cell_set_col_span)            (EContentEditor *editor,
+                                                        gint value,
+                                                        EContentEditorScope scope);
+
+       gint            (*cell_get_col_span)            (EContentEditor *editor);
+
+       gchar *         (*cell_get_background_image_uri)
+                                                       (EContentEditor *editor);
+
+       void            (*cell_set_background_image_uri)
+                                                       (EContentEditor *editor,
+                                                        const gchar *uri);
+
+       void            (*cell_get_background_color)    (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*cell_set_background_color)    (EContentEditor *editor,
+                                                        const GdkRGBA *value,
+                                                        EContentEditorScope scope);
+
+       void            (*table_set_row_count)          (EContentEditor *editor,
+                                                        guint value);
+
+       guint           (*table_get_row_count)          (EContentEditor *editor);
+
+       void            (*table_set_column_count)       (EContentEditor *editor,
+                                                        guint value);
+
+       guint           (*table_get_column_count)       (EContentEditor *editor);
+
+       void            (*table_set_width)              (EContentEditor *editor,
+                                                        gint value,
+                                                        EContentEditorUnit unit);
+
+       guint           (*table_get_width)              (EContentEditor *editor,
+                                                        EContentEditorUnit *unit);
+
+       void            (*table_set_align)              (EContentEditor *editor,
+                                                        const gchar *value);
+
+       gchar *         (*table_get_align)              (EContentEditor *editor);
+
+       void            (*table_set_padding)            (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*table_get_padding)            (EContentEditor *editor);
+
+       void            (*table_set_spacing)            (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*table_get_spacing)            (EContentEditor *editor);
+
+       void            (*table_set_border)             (EContentEditor *editor,
+                                                        gint value);
+
+       gint            (*table_get_border)             (EContentEditor *editor);
+
+       gchar *         (*table_get_background_image_uri)
+                                                       (EContentEditor *editor);
+
+       void            (*table_set_background_image_uri)
+                                                       (EContentEditor *editor,
+                                                        const gchar *uri);
+
+       void            (*table_get_background_color)   (EContentEditor *editor,
+                                                        GdkRGBA *value);
+
+       void            (*table_set_background_color)   (EContentEditor *editor,
+                                                        const GdkRGBA *value);
+
+       gboolean        (*on_table_dialog_open)         (EContentEditor *editor);
+
+       void            (*on_table_dialog_close)        (EContentEditor *editor);
+
+       void            (*on_spell_check_dialog_open)   (EContentEditor *editor);
+
+       void            (*on_spell_check_dialog_close)  (EContentEditor *editor);
+
+       gchar *         (*spell_check_next_word)        (EContentEditor *editor,
+                                                        const gchar *word);
+
+       gchar *         (*spell_check_prev_word)        (EContentEditor *editor,
+                                                        const gchar *word);
+
+       void            (*on_replace_dialog_open)       (EContentEditor *editor);
+
+       void            (*on_replace_dialog_close)      (EContentEditor *editor);
+
+       void            (*on_find_dialog_open)          (EContentEditor *editor);
+
+       void            (*on_find_dialog_close)         (EContentEditor *editor);
+
+       /* Signals */
+       void            (*load_finished)                (EContentEditor *editor);
+
+       void            (*paste_clipboard)              (EContentEditor *editor);
+
+       void            (*paste_primary_clipboard)      (EContentEditor *editor);
+
+       gboolean        (*context_menu_requested)       (EContentEditor *editor,
+                                                        EContentEditorNodeFlags flags,
+                                                        GdkEvent *event);
+};
+
+EContentEditorFindController *
+               e_content_editor_get_find_controller
+                                               (EContentEditor *editor);
+
+void           e_content_editor_insert_content (EContentEditor *editor,
+                                                const gchar *content,
+                                                EContentEditorInsertContentFlags flags);
+
+gchar *                e_content_editor_get_content    (EContentEditor *editor,
+                                                EContentEditorGetContentFlags flags,
+                                                EContentEditorInlineImages **inline_images);
+
+void            e_content_editor_insert_image_from_mime_part
+                                               (EContentEditor *editor,
+                                                CamelMimePart *part);
+
+void           e_content_editor_insert_image   (EContentEditor *editor,
+                                                const gchar *uri);
+
+void           e_content_editor_insert_emoticon
+                                               (EContentEditor *editor,
+                                                EEmoticon *emoticon);
+
+void           e_content_editor_set_current_content_flags
+                                               (EContentEditor *editor,
+                                                EContentEditorContentFlags flags);
+
+EContentEditorContentFlags
+               e_content_editor_get_current_content_flags
+                                               (EContentEditor *editor);
+
+void           e_content_editor_move_caret_on_coordinates
+                                               (EContentEditor *editor,
+                                                gint x,
+                                                gint y,
+                                                gboolean cancel_if_not_collapsed);
+
+void           e_content_editor_set_changed    (EContentEditor *editor,
+                                                gboolean changed);
+
+gboolean       e_content_editor_get_changed    (EContentEditor *editor);
+
+void           e_content_editor_cut            (EContentEditor *editor);
+
+void           e_content_editor_copy           (EContentEditor *editor);
+
+void           e_content_editor_paste          (EContentEditor *editor);
+
+gboolean       e_content_editor_paste_prefer_text_html
+                                               (EContentEditor *editor);
+
+void           e_content_editor_reconnect_paste_clipboard_signals
+                                               (EContentEditor *editor);
+
+gboolean       e_content_editor_can_undo       (EContentEditor *editor);
+
+void           e_content_editor_undo           (EContentEditor *editor);
+
+gboolean       e_content_editor_can_redo       (EContentEditor *editor);
+
+void           e_content_editor_redo           (EContentEditor *editor);
+
+void           e_content_editor_clear_undo_redo_history
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_html_mode  (EContentEditor *editor,
+                                                gboolean html_mode);
+
+gboolean       e_content_editor_get_html_mode  (EContentEditor *editor);
+
+ESpellChecker *        e_content_editor_get_spell_checker
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_spell_checking_languages
+                                               (EContentEditor *editor,
+                                                const gchar **languages);
+
+void           e_content_editor_set_spell_check
+                                               (EContentEditor *editor,
+                                                gboolean enable);
+
+gboolean       e_content_editor_get_spell_check
+                                               (EContentEditor *editor);
+
+void           e_content_editor_select_all     (EContentEditor *editor);
+
+gboolean       e_content_editor_selection_has_text
+                                               (EContentEditor *editor);
+
+gchar *                e_content_editor_selection_get_text
+                                               (EContentEditor *editor);
+
+gchar *                e_content_editor_get_caret_word (EContentEditor *editor);
+
+void           e_content_editor_replace_caret_word
+                                               (EContentEditor *editor,
+                                                const gchar *replacement);
+
+gboolean       e_content_editor_selection_is_indented
+                                               (EContentEditor *editor);
+
+void           e_content_editor_selection_indent
+                                               (EContentEditor *editor);
+
+void           e_content_editor_selection_unindent
+                                               (EContentEditor *editor);
+
+void           e_content_editor_selection_create_link
+                                               (EContentEditor *editor,
+                                                const gchar *uri);
+
+void           e_content_editor_selection_unlink
+                                               (EContentEditor *editor);
+
+void           e_content_editor_selection_replace
+                                               (EContentEditor *editor,
+                                                const gchar *replacement);
+
+void           e_content_editor_selection_save (EContentEditor *editor);
+
+void           e_content_editor_selection_restore
+                                               (EContentEditor *editor);
+
+void           e_content_editor_selection_wrap (EContentEditor *editor);
+
+void           e_content_editor_show_inspector (EContentEditor *editor);
+
+guint          e_content_editor_get_caret_position
+                                               (EContentEditor *editor);
+
+guint          e_content_editor_get_caret_offset
+                                               (EContentEditor *editor);
+
+void           e_content_editor_update_fonts   (EContentEditor *editor);
+
+gboolean       e_content_editor_is_editable    (EContentEditor *editor);
+
+void           e_content_editor_set_editable   (EContentEditor *editor,
+                                                gboolean editable);
+
+gchar *                e_content_editor_get_current_signature_uid
+                                               (EContentEditor *editor);
+
+gboolean       e_content_editor_is_ready       (EContentEditor *editor);
+
+gchar *                e_content_editor_insert_signature
+                                               (EContentEditor *editor,
+                                                const gchar *content,
+                                                gboolean is_html,
+                                                const gchar *signature_id,
+                                                gboolean *set_signature_from_message,
+                                                gboolean *check_if_signature_is_changed,
+                                                gboolean *ignore_next_signature_change);
+
+void           e_content_editor_set_alignment  (EContentEditor *editor,
+                                                EContentEditorAlignment value);
+
+EContentEditorAlignment
+               e_content_editor_get_alignment  (EContentEditor *editor);
+
+void           e_content_editor_set_block_format
+                                               (EContentEditor *editor,
+                                                EContentEditorBlockFormat value);
+
+EContentEditorBlockFormat
+               e_content_editor_get_block_format
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_background_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+const GdkRGBA *        e_content_editor_get_background_color
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_font_name  (EContentEditor *editor,
+                                                const gchar *value);
+
+const gchar *  e_content_editor_get_font_name  (EContentEditor *editor);
+
+void           e_content_editor_set_font_color (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+const GdkRGBA *        e_content_editor_get_font_color (EContentEditor *editor);
+
+void           e_content_editor_set_font_size  (EContentEditor *editor,
+                                                guint value);
+
+guint          e_content_editor_get_font_size  (EContentEditor *editor);
+
+void           e_content_editor_set_bold       (EContentEditor *editor,
+                                                gboolean bold);
+
+gboolean       e_content_editor_is_bold        (EContentEditor *editor);
+
+void           e_content_editor_set_italic     (EContentEditor *editor,
+                                                gboolean italic);
+
+gboolean       e_content_editor_is_italic      (EContentEditor *editor);
+
+void           e_content_editor_set_monospaced (EContentEditor *editor,
+                                                gboolean monospaced);
+
+gboolean       e_content_editor_is_monospaced (EContentEditor *editor);
+
+void           e_content_editor_set_strikethrough
+                                               (EContentEditor *editor,
+                                                gboolean strikethrough);
+
+gboolean       e_content_editor_is_strikethrough
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_subscript  (EContentEditor *editor,
+                                                gboolean subscript);
+
+gboolean       e_content_editor_is_subscript   (EContentEditor *editor);
+
+void           e_content_editor_set_superscript
+                                               (EContentEditor *editor,
+                                                gboolean superscript);
+
+gboolean       e_content_editor_is_superscript
+                                               (EContentEditor *editor);
+
+void           e_content_editor_set_underline  (EContentEditor *editor,
+                                                gboolean underline);
+
+gboolean       e_content_editor_is_underline   (EContentEditor *editor);
+
+void           e_content_editor_delete_cell_contents
+                                               (EContentEditor *editor);
+void
+               e_content_editor_delete_column  (EContentEditor *editor);
+
+void           e_content_editor_delete_row     (EContentEditor *editor);
+
+void           e_content_editor_delete_table   (EContentEditor *editor);
+
+void           e_content_editor_insert_column_after
+                                               (EContentEditor *editor);
+
+void           e_content_editor_insert_column_before
+                                               (EContentEditor *editor);
+
+void           e_content_editor_insert_row_above
+                                               (EContentEditor *editor);
+
+void           e_content_editor_insert_row_below
+                                               (EContentEditor *editor);
+
+gboolean       e_content_editor_on_h_rule_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_h_rule_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_h_rule_set_align
+                                               (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_h_rule_get_align
+                                               (EContentEditor *editor);
+
+void           e_content_editor_h_rule_set_size
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_h_rule_get_size
+                                               (EContentEditor *editor);
+
+void           e_content_editor_h_rule_set_width
+                                               (EContentEditor *editor,
+                                                gint value,
+                                                EContentEditorUnit unit);
+
+gint           e_content_editor_h_rule_get_width
+                                               (EContentEditor *editor,
+                                                EContentEditorUnit *unit);
+
+void           e_content_editor_h_rule_set_no_shade
+                                               (EContentEditor *editor,
+                                                gboolean value);
+
+gboolean       e_content_editor_h_rule_get_no_shade
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_image_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_image_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_src  (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_image_get_src  (EContentEditor *editor);
+
+void           e_content_editor_image_set_alt  (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_image_get_alt  (EContentEditor *editor);
+
+void           e_content_editor_image_set_url  (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_image_get_url  (EContentEditor *editor);
+
+void           e_content_editor_image_set_vspace
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_image_get_vspace
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_hspace
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_image_get_hspace
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_border
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_image_get_border
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_align
+                                               (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_image_get_align
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_width
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint32         e_content_editor_image_get_width
+                                               (EContentEditor *editor);
+
+gint32         e_content_editor_image_get_natural_width
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_width_follow
+                                               (EContentEditor *editor,
+                                                gboolean value);
+void           e_content_editor_image_set_height
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint32         e_content_editor_image_get_height
+                                               (EContentEditor *editor);
+
+gint32         e_content_editor_image_get_natural_height
+                                               (EContentEditor *editor);
+
+void           e_content_editor_image_set_height_follow
+                                               (EContentEditor *editor,
+                                                gboolean value);
+
+void           e_content_editor_link_get_values
+                                               (EContentEditor *editor,
+                                                gchar **href,
+                                                gchar **text);
+
+void           e_content_editor_link_set_values
+                                               (EContentEditor *editor,
+                                                const gchar *href,
+                                                const gchar *text);
+
+void           e_content_editor_page_set_text_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+void           e_content_editor_on_page_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_page_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_page_get_text_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_page_set_background_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+void           e_content_editor_page_get_background_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_page_set_link_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+void           e_content_editor_page_get_link_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_page_set_visited_link_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+void           e_content_editor_page_get_visited_link_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_page_set_background_image_uri
+                                               (EContentEditor *editor,
+                                                const gchar *uri);
+
+gchar *                e_content_editor_page_get_background_image_uri
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_cell_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_cell_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_cell_set_v_align
+                                               (EContentEditor *editor,
+                                                const gchar *value,
+                                                EContentEditorScope scope);
+
+gchar *                e_content_editor_cell_get_v_align
+                                               (EContentEditor *editor);
+
+void           e_content_editor_cell_set_align (EContentEditor *editor,
+                                                const gchar *value,
+                                                EContentEditorScope scope);
+
+gchar *                e_content_editor_cell_get_align (EContentEditor *editor);
+
+void           e_content_editor_cell_set_wrap  (EContentEditor *editor,
+                                                gboolean value,
+                                                EContentEditorScope scope);
+
+gboolean       e_content_editor_cell_get_wrap  (EContentEditor *editor);
+
+void           e_content_editor_cell_set_header_style
+                                               (EContentEditor *editor,
+                                                gboolean value,
+                                                EContentEditorScope scope);
+
+gboolean       e_content_editor_cell_is_header (EContentEditor *editor);
+
+void           e_content_editor_cell_set_width (EContentEditor *editor,
+                                                gint value,
+                                                EContentEditorUnit unit,
+                                                EContentEditorScope scope);
+
+gint           e_content_editor_cell_get_width (EContentEditor *editor,
+                                                EContentEditorUnit *unit);
+
+void           e_content_editor_cell_set_row_span
+                                               (EContentEditor *editor,
+                                                gint value,
+                                                EContentEditorScope scope);
+
+gint           e_content_editor_cell_get_row_span
+                                               (EContentEditor *editor);
+
+void           e_content_editor_cell_set_col_span
+                                               (EContentEditor *editor,
+                                                gint value,
+                                                EContentEditorScope scope);
+
+gint           e_content_editor_cell_get_col_span
+                                               (EContentEditor *editor);
+
+void           e_content_editor_cell_set_background_image_uri
+                                               (EContentEditor *editor,
+                                                const gchar *uri);
+
+gchar *                e_content_editor_cell_get_background_image_uri
+                                               (EContentEditor *editor);
+
+void           e_content_editor_cell_set_background_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value,
+                                                EContentEditorScope scope);
+
+void           e_content_editor_cell_get_background_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_table_set_row_count
+                                               (EContentEditor *editor,
+                                                guint value);
+
+guint          e_content_editor_table_get_row_count
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_column_count
+                                               (EContentEditor *editor,
+                                                guint value);
+
+guint          e_content_editor_table_get_column_count
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_width
+                                               (EContentEditor *editor,
+                                                gint value,
+                                                EContentEditorUnit unit);
+
+guint          e_content_editor_table_get_width
+                                               (EContentEditor *editor,
+                                                EContentEditorUnit *unit);
+
+void           e_content_editor_table_set_align
+                                               (EContentEditor *editor,
+                                                const gchar *value);
+
+gchar *                e_content_editor_table_get_align
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_padding
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_table_get_padding
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_spacing
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_table_get_spacing
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_border
+                                               (EContentEditor *editor,
+                                                gint value);
+
+gint           e_content_editor_table_get_border
+                                               (EContentEditor *editor);
+
+gchar *                e_content_editor_table_get_background_image_uri
+                                               (EContentEditor *editor);
+
+void           e_content_editor_table_set_background_image_uri
+                                               (EContentEditor *editor,
+                                                const gchar *uri);
+
+void           e_content_editor_table_get_background_color
+                                               (EContentEditor *editor,
+                                                GdkRGBA *value);
+
+void           e_content_editor_table_set_background_color
+                                               (EContentEditor *editor,
+                                                const GdkRGBA *value);
+
+gboolean       e_content_editor_on_table_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_table_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_spell_check_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_spell_check_dialog_close
+                                               (EContentEditor *editor);
+
+gchar *                e_content_editor_spell_check_next_word
+                                               (EContentEditor *editor,
+                                                const gchar *word);
+
+gchar *                e_content_editor_spell_check_prev_word
+                                               (EContentEditor *editor,
+                                                const gchar *word);
+
+void           e_content_editor_spell_check_replace_all
+                                               (EContentEditor *editor,
+                                                const gchar *word,
+                                                const gchar *replacement);
+
+void           e_content_editor_on_replace_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_replace_dialog_close
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_find_dialog_open
+                                               (EContentEditor *editor);
+
+void           e_content_editor_on_find_dialog_close
+                                               (EContentEditor *editor);
+
+G_END_DECLS
+
+#endif /* E_CONTENT_EDITOR_H */
diff --git a/e-util/e-focus-tracker.c b/e-util/e-focus-tracker.c
index 7a9477a..794e56d 100644
--- a/e-util/e-focus-tracker.c
+++ b/e-util/e-focus-tracker.c
@@ -28,7 +28,7 @@
 
 #include "e-selectable.h"
 #include "e-widget-undo.h"
-#include "e-html-editor-view.h"
+#include "e-content-editor.h"
 
 #define E_FOCUS_TRACKER_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -257,7 +257,7 @@ focus_tracker_text_view_update_actions (EFocusTracker *focus_tracker,
 
 static void
 focus_tracker_editor_update_actions (EFocusTracker *focus_tracker,
-                                     EHTMLEditorView *view,
+                                     EContentEditor *cnt_editor,
                                      GdkAtom *targets,
                                      gint n_targets)
 {
@@ -266,7 +266,7 @@ focus_tracker_editor_update_actions (EFocusTracker *focus_tracker,
        gboolean can_cut;
        gboolean can_paste;
 
-       g_object_get (view,
+       g_object_get (cnt_editor,
                      "can-copy", &can_copy,
                      "can-cut", &can_cut,
                      "can-paste", &can_paste,
@@ -368,9 +368,9 @@ focus_tracker_targets_received_cb (GtkClipboard *clipboard,
                        focus_tracker, GTK_TEXT_VIEW (focus),
                        targets, n_targets);
 
-       else if (E_IS_HTML_EDITOR_VIEW (focus))
+       else if (E_IS_CONTENT_EDITOR (focus))
                focus_tracker_editor_update_actions (
-                       focus_tracker, E_HTML_EDITOR_VIEW (focus),
+                       focus_tracker, E_CONTENT_EDITOR (focus),
                        targets, n_targets);
 
        g_object_unref (focus_tracker);
@@ -391,7 +391,7 @@ focus_tracker_set_focus_cb (GtkWindow *window,
                if (GTK_IS_TEXT_VIEW (focus))
                        break;
 
-               if (E_IS_HTML_EDITOR_VIEW (focus))
+               if (E_IS_CONTENT_EDITOR (focus))
                        break;
 
                focus = gtk_widget_get_parent (focus);
diff --git a/e-util/e-html-editor-actions.c b/e-util/e-html-editor-actions.c
index fb9f342..f42f134 100644
--- a/e-util/e-html-editor-actions.c
+++ b/e-util/e-html-editor-actions.c
@@ -34,12 +34,14 @@
 #include "e-image-chooser-dialog.h"
 #include "e-spell-checker.h"
 #include "e-misc-utils.h"
+#include "e-content-editor.h"
 
 static void
 insert_html_file_ready_cb (GFile *file,
                            GAsyncResult *result,
                            EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        gchar *contents = NULL;
        gsize length;
        GError *error = NULL;
@@ -63,7 +65,10 @@ insert_html_file_ready_cb (GFile *file,
                return;
        }
 
-       e_html_editor_view_insert_html (e_html_editor_get_view (editor), contents);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_content (
+               cnt_editor, contents, E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
        g_free (contents);
 
        g_object_unref (editor);
@@ -74,6 +79,7 @@ insert_text_file_ready_cb (GFile *file,
                            GAsyncResult *result,
                            EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        gchar *contents;
        gsize length;
        GError *error = NULL;
@@ -97,7 +103,10 @@ insert_text_file_ready_cb (GFile *file,
                return;
        }
 
-       e_html_editor_view_insert_text (e_html_editor_get_view (editor), contents);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_content (
+               cnt_editor, contents, E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
+
        g_free (contents);
 
        g_object_unref (editor);
@@ -108,168 +117,170 @@ insert_text_file_ready_cb (GFile *file,
  *****************************************************************************/
 
 static void
-html_editor_call_simple_extension_function (EHTMLEditor *editor,
-                                        const gchar *function)
-{
-       EHTMLEditorView *view;
-
-       view = e_html_editor_get_view (editor);
-
-       e_html_editor_view_call_simple_extension_function (view, function);
-}
-
-static void
 action_context_delete_cell_contents_cb (GtkAction *action,
                                EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogDeleteCellContents");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_delete_cell_contents (cnt_editor);
 }
 
 static void
 action_context_delete_column_cb (GtkAction *action,
                                  EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogDeleteColumn");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_delete_column (cnt_editor);
 }
 
 static void
 action_context_delete_row_cb (GtkAction *action,
                               EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogDeleteRow");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_delete_row (cnt_editor);
 }
 
 static void
 action_context_delete_table_cb (GtkAction *action,
                                 EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogDeleteTable");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_delete_table (cnt_editor);
 }
 
 static void
 action_context_insert_column_after_cb (GtkAction *action,
                                        EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogInsertColumnAfter");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_column_after (cnt_editor);
 }
 
 static void
 action_context_insert_column_before_cb (GtkAction *action,
                                         EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogInsertColumnBefore");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_column_before (cnt_editor);
 }
 
 static void
 action_context_insert_row_above_cb (GtkAction *action,
                                     EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogInsertRowAbove");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_row_above (cnt_editor);
 }
 
 static void
 action_context_insert_row_below_cb (GtkAction *action,
                                     EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorDialogInsertRowBelow");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_row_below (cnt_editor);
 }
 
 static void
 action_context_remove_link_cb (GtkAction *action,
                                EHTMLEditor *editor)
 {
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorSelectionDOMUnlink");
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_selection_unlink (cnt_editor);
 }
 
 static void
 action_context_spell_add_cb (GtkAction *action,
                              EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
-       EHTMLEditorSelection *selection;
        gchar *word;
 
-       spell_checker = e_html_editor_view_get_spell_checker (
-               editor->priv->html_editor_view);
-       selection = e_html_editor_view_get_selection (editor->priv->html_editor_view);
-
-       word = e_html_editor_selection_get_caret_word (selection);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
+       word = e_content_editor_get_caret_word (cnt_editor);
        if (word && *word)
                e_spell_checker_learn_word (spell_checker, word);
+       g_free (word);
 }
 
 static void
 action_context_spell_ignore_cb (GtkAction *action,
                                 EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
-       EHTMLEditorSelection *selection;
        gchar *word;
 
-       spell_checker = e_html_editor_view_get_spell_checker (
-               editor->priv->html_editor_view);
-       selection = e_html_editor_view_get_selection (editor->priv->html_editor_view);
-
-       word = e_html_editor_selection_get_caret_word (selection);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
+       word = e_content_editor_get_caret_word (cnt_editor);
        if (word && *word)
                e_spell_checker_ignore_word (spell_checker, word);
+       g_free (word);
 }
 
 static void
 action_copy_cb (GtkAction *action,
                 EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       webkit_web_view_execute_editing_command (
-               WEBKIT_WEB_VIEW (view), WEBKIT_EDITING_COMMAND_COPY);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_copy (cnt_editor);
 }
 
 static void
 action_cut_cb (GtkAction *action,
                EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
-
-       html_editor_call_simple_extension_function (
-               editor, "EHTMLEditorActionsSaveHistoryForCut");
+       EContentEditor *cnt_editor;
 
-       webkit_web_view_execute_editing_command (
-               WEBKIT_WEB_VIEW (view), WEBKIT_EDITING_COMMAND_CUT);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_cut (cnt_editor);
 }
 
 static void
 action_indent_cb (GtkAction *action,
                   EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               e_html_editor_selection_indent (editor->priv->selection);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               e_content_editor_selection_indent (cnt_editor);
 }
 
 static void
 action_insert_emoticon_cb (GtkAction *action,
                            EHTMLEditor *editor)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EEmoticon *emoticon;
 
-       emoticon = e_emoticon_chooser_get_current_emoticon (
-                                       E_EMOTICON_CHOOSER (action));
+       emoticon = e_emoticon_chooser_get_current_emoticon (E_EMOTICON_CHOOSER (action));
        g_return_if_fail (emoticon != NULL);
 
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_insert_smiley (view, emoticon);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_emoticon (cnt_editor, emoticon);
 }
 
 static void
@@ -316,13 +327,13 @@ action_insert_image_cb (GtkAction *action,
        dialog = e_image_chooser_dialog_new (C_("dialog-title", "Insert Image"), NULL);
 
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
-               EHTMLEditorView *view;
+               EContentEditor *cnt_editor;
                gchar *uri;
 
                uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
 
-               view = e_html_editor_get_view (editor);
-               e_html_editor_view_insert_image (view, uri);
+               cnt_editor = e_html_editor_get_content_editor (editor);
+               e_content_editor_insert_image (cnt_editor, uri);
 
                g_free (uri);
        }
@@ -403,14 +414,14 @@ action_language_cb (GtkToggleAction *toggle_action,
                     EHTMLEditor *editor)
 {
        ESpellChecker *checker;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *language_code;
        GtkAction *add_action;
        gchar *action_name;
        gboolean active;
 
-       view = e_html_editor_get_view (editor);
-       checker = e_html_editor_view_get_spell_checker (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       checker = e_content_editor_get_spell_checker (cnt_editor);
        language_code = gtk_action_get_name (GTK_ACTION (toggle_action));
 
        active = gtk_toggle_action_get_active (toggle_action);
@@ -431,15 +442,15 @@ static gboolean
 update_mode_combobox (gpointer data)
 {
        EHTMLEditor *editor = data;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkAction *action;
        gboolean is_html;
 
        if (!E_IS_HTML_EDITOR (editor))
                return FALSE;
 
-       view = e_html_editor_get_view (editor);
-       is_html = e_html_editor_view_get_html_mode (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       is_html = e_content_editor_get_html_mode (cnt_editor);
 
        action = gtk_action_group_get_action (
                editor->priv->core_editor_actions, "mode-html");
@@ -454,13 +465,13 @@ action_mode_cb (GtkRadioAction *action,
                 GtkRadioAction *current,
                 EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        GtkActionGroup *action_group;
-       EHTMLEditorView *view;
        GtkWidget *style_combo_box;
        gboolean is_html;
 
-       view = e_html_editor_get_view (editor);
-       is_html = e_html_editor_view_get_html_mode (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       is_html = e_content_editor_get_html_mode (cnt_editor);
 
        /* This must be done from idle callback, because apparently we can change
         * current value in callback of current value change */
@@ -505,37 +516,82 @@ static void
 action_paste_cb (GtkAction *action,
                  EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       webkit_web_view_execute_editing_command (
-               WEBKIT_WEB_VIEW (view), WEBKIT_EDITING_COMMAND_PASTE);
-       e_html_editor_view_force_spell_check (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_paste (cnt_editor);
+}
+
+static void
+clipboard_text_received_for_paste_as_text (GtkClipboard *clipboard,
+                                           const gchar *text,
+                                           EHTMLEditor *editor)
+{
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_content (
+               cnt_editor,
+               text,
+               E_CONTENT_EDITOR_INSERT_CONVERT |
+               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
 }
 
 static void
 action_paste_as_text_cb (GtkAction *action,
                          EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
+       GtkClipboard *clipboard;
 
-       if (!gtk_widget_has_focus (GTK_WIDGET (view)))
-               gtk_widget_grab_focus (GTK_WIDGET (view));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (!gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
 
-       e_html_editor_view_paste_as_text (view);
-       e_html_editor_view_force_spell_check (view);
+       clipboard = gtk_clipboard_get_for_display (
+               gdk_display_get_default (),
+               GDK_SELECTION_CLIPBOARD);
+
+       gtk_clipboard_request_text (
+               clipboard,
+               (GtkClipboardTextReceivedFunc) clipboard_text_received_for_paste_as_text,
+               editor);
+}
+
+static void
+clipboard_text_received_for_paste_quote (GtkClipboard *clipboard,
+                                         const gchar *text,
+                                         EHTMLEditor *editor)
+{
+       EContentEditor *cnt_editor;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_insert_content (
+               cnt_editor,
+               text,
+               E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT |
+               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
 }
 
 static void
 action_paste_quote_cb (GtkAction *action,
                        EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
+       GtkClipboard *clipboard;
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (!gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
 
-       if (!gtk_widget_has_focus (GTK_WIDGET (view)))
-               gtk_widget_grab_focus (GTK_WIDGET (view));
+       clipboard = gtk_clipboard_get_for_display (
+               gdk_display_get_default (),
+               GDK_SELECTION_CLIPBOARD);
 
-       e_html_editor_view_paste_clipboard_quoted (view);
-       e_html_editor_view_force_spell_check (view);
+       gtk_clipboard_request_text (
+               clipboard,
+               (GtkClipboardTextReceivedFunc) clipboard_text_received_for_paste_quote,
+               editor);
 }
 
 static void
@@ -639,21 +695,22 @@ static void
 action_redo_cb (GtkAction *action,
                 EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               e_html_editor_view_redo (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               e_content_editor_redo (cnt_editor);
 }
 
 static void
 action_select_all_cb (GtkAction *action,
                       EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               webkit_web_view_execute_editing_command (
-                       WEBKIT_WEB_VIEW (view), WEBKIT_EDITING_COMMAND_SELECT_ALL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               e_content_editor_select_all (cnt_editor);
 }
 
 static void
@@ -707,45 +764,44 @@ static void
 action_undo_cb (GtkAction *action,
                 EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               e_html_editor_view_undo (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor))) {
+               e_content_editor_undo (cnt_editor);
+       }
 }
 
 static void
 action_unindent_cb (GtkAction *action,
                     EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               html_editor_call_simple_extension_function (
-                       editor, "DOMSelectionUnindent");
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               e_content_editor_selection_unindent (cnt_editor);
 }
 
 static void
 action_wrap_lines_cb (GtkAction *action,
                       EHTMLEditor *editor)
 {
-       EHTMLEditorView *view = e_html_editor_get_view (editor);
+       EContentEditor *cnt_editor;
 
-       if (gtk_widget_has_focus (GTK_WIDGET (view)))
-               html_editor_call_simple_extension_function (
-                       editor, "DOMSelectionWrap");
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       if (gtk_widget_has_focus (GTK_WIDGET (cnt_editor)))
+               e_content_editor_selection_wrap (cnt_editor);
 }
 
 static void
 action_show_webkit_inspector_cb (GtkAction *action,
                                  EHTMLEditor *editor)
 {
-       WebKitWebInspector *inspector;
-       EHTMLEditorView *view;
-
-       view = e_html_editor_get_view (editor);
-       inspector = webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (view));
+       EContentEditor *cnt_editor;
 
-       webkit_web_inspector_show (inspector);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_show_inspector (cnt_editor);
 }
 
 /*****************************************************************************
@@ -944,21 +1000,21 @@ static GtkRadioActionEntry core_justify_entries[] = {
          N_("_Center"),
          "<Control>e",
          N_("Center Alignment"),
-         E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER },
+         E_CONTENT_EDITOR_ALIGNMENT_CENTER },
 
        { "justify-left",
          "format-justify-left",
          N_("_Left"),
          "<Control>l",
          N_("Left Alignment"),
-         E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT },
+         E_CONTENT_EDITOR_ALIGNMENT_LEFT },
 
        { "justify-right",
          "format-justify-right",
          N_("_Right"),
          "<Control>r",
          N_("Right Alignment"),
-         E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT }
+         E_CONTENT_EDITOR_ALIGNMENT_RIGHT }
 };
 
 static GtkRadioActionEntry core_mode_entries[] = {
@@ -968,14 +1024,14 @@ static GtkRadioActionEntry core_mode_entries[] = {
          N_("_HTML"),
          NULL,
          N_("HTML editing mode"),
-         TRUE },       /* e_html_editor_view_set_html_mode */
+         TRUE },       /* e_content_editor_set_html_mode */
 
        { "mode-plain",
          NULL,
          N_("Plain _Text"),
          NULL,
          N_("Plain text editing mode"),
-         FALSE }       /* e_html_editor_view_set_html_mode */
+         FALSE }       /* e_content_editor_set_html_mode */
 };
 
 static GtkRadioActionEntry core_style_entries[] = {
@@ -985,98 +1041,98 @@ static GtkRadioActionEntry core_style_entries[] = {
          N_("_Normal"),
          "<Control>0",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH },
 
        { "style-h1",
          NULL,
          N_("Header _1"),
          "<Control>1",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H1 },
 
        { "style-h2",
          NULL,
          N_("Header _2"),
          "<Control>2",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H2 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H2 },
 
        { "style-h3",
          NULL,
          N_("Header _3"),
          "<Control>3",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H3 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H3 },
 
        { "style-h4",
          NULL,
          N_("Header _4"),
          "<Control>4",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H4 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H4 },
 
        { "style-h5",
          NULL,
          N_("Header _5"),
          "<Control>5",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H5 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H5 },
 
        { "style-h6",
          NULL,
          N_("Header _6"),
          "<Control>6",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6 },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_H6 },
 
         { "style-preformat",
           NULL,
           N_("_Preformatted"),
           "<Control>7",
           NULL,
-          E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE },
+          E_CONTENT_EDITOR_BLOCK_FORMAT_PRE },
 
        { "style-address",
          NULL,
          N_("A_ddress"),
          "<Control>8",
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_ADDRESS },
 
         { "style-blockquote",
           NULL,
           N_("_Blockquote"),
           "<Control>9",
           NULL,
-          E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE },
+          E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE },
 
        { "style-list-bullet",
          NULL,
          N_("_Bulleted List"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST },
 
        { "style-list-roman",
          NULL,
          N_("_Roman Numeral List"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN },
 
        { "style-list-number",
          NULL,
          N_("Numbered _List"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST },
+         E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST },
 
        { "style-list-alpha",
          NULL,
          N_("_Alphabetical List"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA }
+         E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA }
 };
 
 /*****************************************************************************
@@ -1237,7 +1293,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("-2"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_TINY },
+         E_CONTENT_EDITOR_FONT_SIZE_TINY },
 
        { "size-minus-one",
          NULL,
@@ -1245,7 +1301,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("-1"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_SMALL },
+         E_CONTENT_EDITOR_FONT_SIZE_SMALL },
 
        { "size-plus-zero",
          NULL,
@@ -1253,7 +1309,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("+0"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL },
+         E_CONTENT_EDITOR_FONT_SIZE_NORMAL },
 
        { "size-plus-one",
          NULL,
@@ -1261,7 +1317,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("+1"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_BIG },
+         E_CONTENT_EDITOR_FONT_SIZE_BIG },
 
        { "size-plus-two",
          NULL,
@@ -1269,7 +1325,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("+2"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_BIGGER },
+         E_CONTENT_EDITOR_FONT_SIZE_BIGGER },
 
        { "size-plus-three",
          NULL,
@@ -1277,7 +1333,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("+3"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_LARGE },
+         E_CONTENT_EDITOR_FONT_SIZE_LARGE },
 
        { "size-plus-four",
          NULL,
@@ -1285,7 +1341,7 @@ static GtkRadioActionEntry html_size_entries[] = {
          N_("+4"),
          NULL,
          NULL,
-         E_HTML_EDITOR_SELECTION_FONT_SIZE_VERY_LARGE }
+         E_CONTENT_EDITOR_FONT_SIZE_VERY_LARGE }
 };
 
 /*****************************************************************************
@@ -1514,7 +1570,7 @@ static void
 editor_actions_setup_languages_menu (EHTMLEditor *editor)
 {
        ESpellChecker *checker;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkUIManager *manager;
        GtkActionGroup *action_group;
        GList *list = NULL, *link;
@@ -1522,8 +1578,8 @@ editor_actions_setup_languages_menu (EHTMLEditor *editor)
 
        manager = editor->priv->manager;
        action_group = editor->priv->language_actions;
-       view = e_html_editor_get_view (editor);
-       checker = e_html_editor_view_get_spell_checker (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       checker = e_content_editor_get_spell_checker (cnt_editor);
        merge_id = gtk_ui_manager_new_merge_id (manager);
 
        list = e_spell_checker_list_available_dicts (checker);
@@ -1577,6 +1633,7 @@ editor_actions_setup_languages_menu (EHTMLEditor *editor)
 static void
 editor_actions_setup_spell_check_menu (EHTMLEditor *editor)
 {
+       EContentEditor *cnt_editor;
        ESpellChecker *checker;
        GtkUIManager *manager;
        GtkActionGroup *action_group;
@@ -1585,7 +1642,8 @@ editor_actions_setup_spell_check_menu (EHTMLEditor *editor)
 
        manager = editor->priv->manager;
        action_group = editor->priv->spell_check_actions;;
-       checker = e_html_editor_view_get_spell_checker (editor->priv->html_editor_view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       checker = e_content_editor_get_spell_checker (cnt_editor);
        available_dicts = e_spell_checker_list_available_dicts (checker);
        merge_id = gtk_ui_manager_new_merge_id (manager);
 
@@ -1688,7 +1746,7 @@ editor_actions_init (EHTMLEditor *editor)
        gtk_action_group_add_radio_actions (
                action_group, core_justify_entries,
                G_N_ELEMENTS (core_justify_entries),
-               E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT,
+               E_CONTENT_EDITOR_ALIGNMENT_LEFT,
                NULL, NULL);
        gtk_action_group_add_radio_actions (
                action_group, core_mode_entries,
@@ -1698,7 +1756,7 @@ editor_actions_init (EHTMLEditor *editor)
        gtk_action_group_add_radio_actions (
                action_group, core_style_entries,
                G_N_ELEMENTS (core_style_entries),
-               E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH,
+               E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH,
                NULL, NULL);
        gtk_ui_manager_insert_action_group (manager, action_group, 0);
 
@@ -1725,7 +1783,7 @@ editor_actions_init (EHTMLEditor *editor)
        gtk_action_group_add_radio_actions (
                action_group, html_size_entries,
                G_N_ELEMENTS (html_size_entries),
-               E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL,
+               E_CONTENT_EDITOR_FONT_SIZE_NORMAL,
                NULL, NULL);
        gtk_ui_manager_insert_action_group (manager, action_group, 0);
 
@@ -1803,97 +1861,101 @@ editor_actions_bind (EHTMLEditor *editor)
 {
        GtkAction *action;
        GtkActionGroup *action_group;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_HTML_EDITOR (editor));
 
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        action_group = editor->priv->core_editor_actions;
        action = gtk_action_group_get_action (action_group, "mode-html");
        e_binding_bind_property (
-               view, "html-mode",
+               cnt_editor, "html-mode",
                action, "current-value",
                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 
        /* Synchronize widget mode with the buttons */
-       e_html_editor_view_set_html_mode (view, TRUE);
+       e_content_editor_set_html_mode (cnt_editor, TRUE);
 
        e_binding_bind_property (
-               view, "can-redo",
+               cnt_editor, "can-redo",
                ACTION (REDO), "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "can-undo",
+               cnt_editor, "can-undo",
                ACTION (UNDO), "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "can-copy",
+               cnt_editor, "can-copy",
                ACTION (COPY), "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "can-cut",
+               cnt_editor, "can-cut",
                ACTION (CUT), "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "can-paste",
+               cnt_editor, "can-paste",
                ACTION (PASTE), "sensitive",
                G_BINDING_SYNC_CREATE);
+       e_binding_bind_property (
+               cnt_editor, "can-paste",
+               ACTION (PASTE_QUOTE), "sensitive",
+               G_BINDING_SYNC_CREATE);
 
        /* This is connected to JUSTIFY_LEFT action only, but
         * it automatically applies on all actions in the group. */
        e_binding_bind_property (
-               editor->priv->selection, "alignment",
+               cnt_editor, "alignment",
                ACTION (JUSTIFY_LEFT), "current-value",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "bold",
+               cnt_editor, "bold",
                ACTION (BOLD), "active",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "font-size",
+               cnt_editor, "font-size",
                ACTION (FONT_SIZE_GROUP), "current-value",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "block-format",
+               cnt_editor, "block-format",
                ACTION (STYLE_NORMAL), "current-value",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "indented",
+               cnt_editor, "indented",
                ACTION (UNINDENT), "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               editor->priv->selection, "italic",
+               cnt_editor, "italic",
                ACTION (ITALIC), "active",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "monospaced",
+               cnt_editor, "monospaced",
                ACTION (MONOSPACED), "active",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "strikethrough",
+               cnt_editor, "strikethrough",
                ACTION (STRIKETHROUGH), "active",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               editor->priv->selection, "underline",
+               cnt_editor, "underline",
                ACTION (UNDERLINE), "active",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
 
        /* Disable all actions and toolbars when editor is not editable */
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                editor->priv->core_editor_actions, "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                editor->priv->html_actions, "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                editor->priv->spell_check_actions, "sensitive",
                G_BINDING_SYNC_CREATE);
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                editor->priv->suggestion_actions, "sensitive",
                G_BINDING_SYNC_CREATE);
 }
diff --git a/e-util/e-html-editor-actions.h b/e-util/e-html-editor-actions.h
index d2e80df..6e0a568 100644
--- a/e-util/e-html-editor-actions.h
+++ b/e-util/e-html-editor-actions.h
@@ -111,6 +111,8 @@
        E_HTML_EDITOR_ACTION ((editor), "monospaced")
 #define E_HTML_EDITOR_ACTION_PASTE(editor) \
        E_HTML_EDITOR_ACTION ((editor), "paste")
+#define E_HTML_EDITOR_ACTION_PASTE_QUOTE(editor) \
+       E_HTML_EDITOR_ACTION ((editor), "paste-quote")
 #define E_HTML_EDITOR_ACTION_PROPERTIES_RULE(editor) \
        E_HTML_EDITOR_ACTION ((editor), "properties-rule")
 #define E_HTML_EDITOR_ACTION_PROPERTIES_TABLE(editor) \
diff --git a/e-util/e-html-editor-cell-dialog.c b/e-util/e-html-editor-cell-dialog.c
index e70f52e..396b02b 100644
--- a/e-util/e-html-editor-cell-dialog.c
+++ b/e-util/e-html-editor-cell-dialog.c
@@ -107,294 +107,153 @@ static  void
 html_editor_cell_dialog_set_valign (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementVAlign",
-               g_variant_new (
-                       "(tsu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_combo_box_get_active_id (
-                               GTK_COMBO_BOX (dialog->priv->valign_combo)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_v_align (
+               cnt_editor,
+               gtk_combo_box_get_active_id (
+                       GTK_COMBO_BOX (dialog->priv->valign_combo)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_halign (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementAlign",
-               g_variant_new (
-                       "(tsu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_combo_box_get_active_id (
-                               GTK_COMBO_BOX (dialog->priv->halign_combo)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_align (
+               cnt_editor,
+               gtk_combo_box_get_active_id (
+                       GTK_COMBO_BOX (dialog->priv->halign_combo)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_wrap_text (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementNoWrap",
-               g_variant_new (
-                       "(tbu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       !gtk_combo_box_get_active (
-                               GTK_COMBO_BOX (dialog->priv->wrap_text_check)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_wrap (
+               cnt_editor,
+               gtk_combo_box_get_active (
+                       GTK_COMBO_BOX (dialog->priv->wrap_text_check)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_header_style (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementHeaderStyle",
-               g_variant_new (
-                       "(tbu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_toggle_button_get_active (
-                               GTK_TOGGLE_BUTTON (
-                                       dialog->priv->header_style_check)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_header_style (
+               cnt_editor,
+               gtk_toggle_button_get_active (
+                       GTK_TOGGLE_BUTTON (dialog->priv->header_style_check)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_width (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       gchar *width;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (!gtk_toggle_button_get_active (
+       if (gtk_toggle_button_get_active (
                GTK_TOGGLE_BUTTON (dialog->priv->width_check))) {
 
-               width = g_strdup ("auto");
-       } else {
-
-               width = g_strdup_printf (
-                       "%d%s",
+               e_content_editor_cell_set_width (
+                       cnt_editor,
                        gtk_spin_button_get_value_as_int (
                                GTK_SPIN_BUTTON (dialog->priv->width_edit)),
-                       ((gtk_combo_box_get_active (
+                       (gtk_combo_box_get_active (
                                GTK_COMBO_BOX (dialog->priv->width_units)) == 0) ?
-                                       "px" : "%"));
-       }
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementWidth",
-               g_variant_new (
-                       "(tsu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       width,
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-
-       g_free (width);
+                                       E_CONTENT_EDITOR_UNIT_PIXEL :
+                                       E_CONTENT_EDITOR_UNIT_PERCENTAGE,
+                       dialog->priv->scope);
+       } else
+               e_content_editor_cell_set_width (
+                       cnt_editor, 0, E_CONTENT_EDITOR_UNIT_AUTO, dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_column_span (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementColSpan",
-               g_variant_new (
-                       "(tiu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_spin_button_get_value_as_int (
-                               GTK_SPIN_BUTTON (dialog->priv->col_span_edit)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_col_span (
+               cnt_editor,
+               gtk_spin_button_get_value_as_int (
+                       GTK_SPIN_BUTTON (dialog->priv->col_span_edit)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_row_span (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementRowSpan",
-               g_variant_new (
-                       "(tiu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_spin_button_get_value_as_int (
-                               GTK_SPIN_BUTTON (dialog->priv->row_span_edit)),
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_row_span (
+               cnt_editor,
+               gtk_spin_button_get_value_as_int (
+                       GTK_SPIN_BUTTON (dialog->priv->row_span_edit)),
+               dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_background_color (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       gchar *color;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
-       if (rgba.alpha != 0.0)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-       else
-               color = g_strdup ("");
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogSetElementBgColor",
-               g_variant_new (
-                       "(tsu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       color,
-                       dialog->priv->scope),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-
-       g_free (color);
+       e_content_editor_cell_set_background_color (cnt_editor, &rgba, dialog->priv->scope);
 }
 
 static void
 html_editor_cell_dialog_set_background_image (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        gchar *uri;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        uri = gtk_file_chooser_get_uri (
                GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
 
-       if (uri && *uri)
-               g_dbus_proxy_call (
-                       web_extension,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new (
-                               "(ts)",
-                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                               "#-x-evo-current-cell"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
-       else
-               e_html_editor_view_replace_image_src (view, "#-x-evo-current-cell", uri);
+       e_content_editor_cell_set_background_image_uri (cnt_editor, uri);
 
        gtk_widget_set_sensitive (dialog->priv->remove_image_button, uri && *uri);
 
@@ -405,27 +264,12 @@ static void
 html_editor_cell_dialog_remove_image (EHTMLEditorCellDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "RemoveImageAttributesFromElementBySelector",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "#-x-evo-current-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_cell_set_background_image_uri (cnt_editor, NULL);
 
        gtk_file_chooser_unselect_all (
                GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
@@ -437,237 +281,72 @@ static void
 html_editor_cell_dialog_show (GtkWidget *widget)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
+       EContentEditorUnit unit;
        EHTMLEditorCellDialog *dialog;
-       GDBusProxy *web_extension;
-       GVariant *result;
-       GdkRGBA color;
+       GdkRGBA rgba;
+       gchar *alignment, *uri;
+       gint width;
 
        dialog = E_HTML_EDITOR_CELL_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorCellDialogMarkCurrentCellElement",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-table-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_cell_dialog_open (cnt_editor);
 
        gtk_toggle_button_set_active (
                GTK_TOGGLE_BUTTON (dialog->priv->scope_cell_button), TRUE);
 
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-cell", "align");
-
-       if (result) {
-               const gchar *align;
+       alignment = e_content_editor_cell_get_align (cnt_editor);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->halign_combo),
+               (alignment && *alignment) ? alignment : "left");
+       g_free (alignment);
 
-               g_variant_get (result, "(&s)", &align);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->halign_combo),
-                       (align && *align) ? align : "left");
-               g_variant_unref (result);
-       }
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-cell", "valign");
-
-       if (result) {
-               const gchar *v_align;
-
-               g_variant_get (result, "(&s)", &v_align);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->valign_combo),
-                       (v_align && *v_align) ? v_align : "middle");
-               g_variant_unref (result);
-       }
+       alignment = e_content_editor_cell_get_v_align (cnt_editor);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->valign_combo),
+               (alignment && *alignment) ? alignment : "middle");
+       g_free (alignment);
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "TableCellElementGetNoWrap",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean no_wrap;
-
-               g_variant_get (result, "(b)", &no_wrap);
-               gtk_toggle_button_set_active (
-                       GTK_TOGGLE_BUTTON (dialog->priv->wrap_text_check), !no_wrap);
-               g_variant_unref (result);
-       }
+       gtk_toggle_button_set_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->wrap_text_check),
+               e_content_editor_cell_get_wrap (cnt_editor));
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ElementGetTagName",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               const gchar *tag_name;
-
-               g_variant_get (result, "(&s)", &tag_name);
-               gtk_toggle_button_set_active (
-                       GTK_TOGGLE_BUTTON (dialog->priv->header_style_check),
-                       (g_ascii_strncasecmp (tag_name, "TH", 2) == 0));
-               g_variant_unref (result);
-       }
+       gtk_toggle_button_set_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->header_style_check),
+               e_content_editor_cell_is_header (cnt_editor));
 
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-cell", "width");
-
-       if (result) {
-               const gchar *width;
-
-               g_variant_get (result, "(&s)", &width);
-               if (width && *width) {
-                       gint val = atoi (width);
-                       gtk_spin_button_set_value (
-                               GTK_SPIN_BUTTON (dialog->priv->width_edit), val);
-                       gtk_toggle_button_set_active (
-                               GTK_TOGGLE_BUTTON (dialog->priv->width_check), TRUE);
-               } else {
-                       gtk_spin_button_set_value (
-                               GTK_SPIN_BUTTON (dialog->priv->width_edit), 0);
-                       gtk_toggle_button_set_active (
-                               GTK_TOGGLE_BUTTON (dialog->priv->width_check), FALSE);
-               }
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->width_units), "units-px");
-               g_variant_unref (result);
-       }
+       width = e_content_editor_cell_get_width (cnt_editor, &unit);
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->width_edit), width);
+       gtk_toggle_button_set_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->width_check),
+               unit != E_CONTENT_EDITOR_UNIT_AUTO);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->width_units),
+               (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "units-px" : "units-percent");
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "TableCellElementGetRowSpan",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               glong row_span;
-
-               g_variant_get (result, "(i)", &row_span);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->row_span_edit), row_span);
-               g_variant_unref (result);
-       }
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->row_span_edit),
+               e_content_editor_cell_get_row_span (cnt_editor));
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "TableCellElementGetColSpan",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-cell"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               glong col_span;
-
-               g_variant_get (result, "(i)", &col_span);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->col_span_edit), col_span);
-               g_variant_unref (result);
-       }
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->col_span_edit),
+               e_content_editor_cell_get_col_span (cnt_editor));
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ElementHasAttribute",
-               g_variant_new (
-                       "(tss)",
-                       webkit_web_view_get_page_id (
-                               WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-cell",
-                       "background"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean has_background;
-
-               g_variant_get (result, "(b)", &has_background);
-               if (has_background) {
-                       g_variant_unref (result);
-
-                       result = e_html_editor_view_get_element_attribute (
-                               view, "#-x-evo-current-cell", "data-uri");
-
-                       if (result) {
-                               const gchar *value;
-
-                               g_variant_get (result, "(&s)", &value);
-
-                               gtk_file_chooser_set_uri (
-                                       GTK_FILE_CHOOSER (dialog->priv->background_image_chooser),
-                                       value);
-
-                               g_variant_unref (result);
-                       }
-               } else {
-                       gtk_file_chooser_unselect_all (
-                               GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
-                       g_variant_unref (result);
-               }
-       }
+       uri = e_content_editor_cell_get_background_image_uri (cnt_editor);
+       if (uri && *uri)
+               gtk_file_chooser_set_uri (
+                       GTK_FILE_CHOOSER (dialog->priv->background_image_chooser), uri);
+       else
+               gtk_file_chooser_unselect_all (
+                       GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
+       g_free (uri);
 
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-cell", "bgcolor");
-
-       if (result) {
-               const gchar *bg_color;
-
-               g_variant_get (result, "(&s)", &bg_color);
-
-               if (bg_color && *bg_color) {
-                       if (gdk_rgba_parse (&color, bg_color)) {
-                               e_color_combo_set_current_color (
-                                       E_COLOR_COMBO (dialog->priv->background_color_picker),
-                                       &color);
-                       } else {
-                               e_color_combo_set_current_color (
-                                       E_COLOR_COMBO (dialog->priv->background_color_picker),
-                                       &transparent);
-                       }
-               }
-               e_color_combo_set_current_color (
-                       E_COLOR_COMBO (dialog->priv->background_color_picker),
-                       &transparent);
-
-               g_variant_unref (result);
-       }
+       e_content_editor_cell_get_background_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
 
        GTK_WIDGET_CLASS (e_html_editor_cell_dialog_parent_class)->show (widget);
 }
@@ -677,14 +356,13 @@ html_editor_cell_dialog_hide (GtkWidget *widget)
 {
        EHTMLEditor *editor;
        EHTMLEditorCellDialog *dialog;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        dialog = E_HTML_EDITOR_CELL_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_call_simple_extension_function_sync (
-               view, "EHTMLEditorCellDialogSaveHistoryOnExit");
+       e_content_editor_on_cell_dialog_close (cnt_editor);
 
        GTK_WIDGET_CLASS (e_html_editor_cell_dialog_parent_class)->hide (widget);
 }
@@ -875,8 +553,8 @@ e_html_editor_cell_dialog_init (EHTMLEditorCellDialog *dialog)
                G_BINDING_SYNC_CREATE);
 
        widget = gtk_combo_box_text_new ();
-       gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "unit-px", "px");
-       gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "unit-percent", "%");
+       gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "units-px", "px");
+       gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "units-percent", "%");
        gtk_grid_attach (grid, widget, 2, 0, 1, 1);
        dialog->priv->width_units = widget;
 
diff --git a/e-util/e-html-editor-dialog.h b/e-util/e-html-editor-dialog.h
index 37fc7a5..d111569 100644
--- a/e-util/e-html-editor-dialog.h
+++ b/e-util/e-html-editor-dialog.h
@@ -62,6 +62,16 @@ struct _EHTMLEditorDialogClass {
        GtkWindowClass parent_class;
 };
 
+#if 0
+struct _EContentEditorDialogInterface {
+       GTypeInterface parent_interface;
+
+       void            (*dialog_opened)                (EContentEditorDialog *dialog);
+
+       void            (*dialog_closed)                (EContentEditorDialog *dialog);
+};
+#endif
+
 GType          e_html_editor_dialog_get_type   (void) G_GNUC_CONST;
 EHTMLEditor *  e_html_editor_dialog_get_editor (EHTMLEditorDialog *dialog);
 GtkBox *       e_html_editor_dialog_get_button_box
diff --git a/e-util/e-html-editor-find-dialog.c b/e-util/e-html-editor-find-dialog.c
index 12b7573..e134d21 100644
--- a/e-util/e-html-editor-find-dialog.c
+++ b/e-util/e-html-editor-find-dialog.c
@@ -25,7 +25,6 @@
 #include "e-html-editor-find-dialog.h"
 #include "e-dialog-widgets.h"
 
-#include <webkit2/webkit2.h>
 #include <glib/gi18n-lib.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -43,7 +42,7 @@ struct _EHTMLEditorFindDialogPrivate {
 
        GtkWidget *result_label;
 
-       WebKitFindController *find_controller;
+       EContentEditorFindController *find_controller;
        gulong found_text_handler_id;
        gulong failed_to_find_text_handler_id;
 };
@@ -63,9 +62,15 @@ reset_dialog (EHTMLEditorFindDialog *dialog)
 static void
 html_editor_find_dialog_hide (GtkWidget *widget)
 {
+       EContentEditor *cnt_editor;
+       EHTMLEditor *editor;
        EHTMLEditorFindDialog *dialog = E_HTML_EDITOR_FIND_DIALOG (widget);
 
-       webkit_find_controller_search_finish (dialog->priv->find_controller);
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_find_controller_search_finish (dialog->priv->find_controller);
+       e_content_editor_on_find_dialog_close (cnt_editor);
 
        /* Chain up to parent's implementation */
        GTK_WIDGET_CLASS (e_html_editor_find_dialog_parent_class)->hide (widget);
@@ -74,8 +79,15 @@ html_editor_find_dialog_hide (GtkWidget *widget)
 static void
 html_editor_find_dialog_show (GtkWidget *widget)
 {
+       EContentEditor *cnt_editor;
+       EHTMLEditor *editor;
        EHTMLEditorFindDialog *dialog = E_HTML_EDITOR_FIND_DIALOG (widget);
 
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_find_dialog_open (cnt_editor);
+
        reset_dialog (dialog);
        gtk_widget_grab_focus (dialog->priv->entry);
 
@@ -84,17 +96,17 @@ html_editor_find_dialog_show (GtkWidget *widget)
 }
 
 static void
-webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
-                                      guint match_count,
-                                      EHTMLEditorFindDialog *dialog)
+content_editor_find_controller_found_text_cb (EContentEditorFindController *find_controller,
+                                              guint match_count,
+                                              EHTMLEditorFindDialog *dialog)
 {
        gtk_widget_hide (dialog->priv->result_label);
        gtk_widget_set_sensitive (dialog->priv->find_button, TRUE);
 }
 
 static void
-webkit_find_controller_failed_to_found_text_cb (WebKitFindController *find_controller,
-                                                EHTMLEditorFindDialog *dialog)
+content_editor_find_controller_failed_to_found_text_cb (EContentEditorFindController *find_controller,
+                                                        EHTMLEditorFindDialog *dialog)
 {
        gtk_label_set_label (
                GTK_LABEL (dialog->priv->result_label), N_("No match found"));
@@ -107,19 +119,18 @@ html_editor_find_dialog_find_cb (EHTMLEditorFindDialog *dialog)
        guint32 flags = 0;
 
        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->case_sensitive)))
-               flags |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+               flags |= E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->backwards)))
-               flags |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+               flags |= E_CONTENT_EDITOR_FIND_BACKWARDS;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap_search)))
-               flags |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+               flags |= E_CONTENT_EDITOR_FIND_WRAP_AROUND;
 
-       webkit_find_controller_search (
+       e_content_editor_find_controller_search (
                dialog->priv->find_controller,
                gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry)),
-               flags,
-               G_MAXUINT);
+               flags);
 }
 
 static gboolean
@@ -169,24 +180,23 @@ html_editor_find_dialog_constructed (GObject *object)
 {
        EHTMLEditor *editor;
        EHTMLEditorFindDialog *dialog;
-       EHTMLEditorView *view;
-       WebKitFindController *find_controller;
+       EContentEditor *cnt_editor;
+       EContentEditorFindController *find_controller;
 
        dialog = E_HTML_EDITOR_FIND_DIALOG (object);
        dialog->priv = E_HTML_EDITOR_FIND_DIALOG_GET_PRIVATE (dialog);
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       find_controller =
-               webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (view));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       find_controller = e_content_editor_get_find_controller (cnt_editor);
 
        dialog->priv->found_text_handler_id = g_signal_connect (
                find_controller, "found-text",
-               G_CALLBACK (webkit_find_controller_found_text_cb), dialog);
+               G_CALLBACK (content_editor_find_controller_found_text_cb), dialog);
 
        dialog->priv->failed_to_find_text_handler_id = g_signal_connect (
                find_controller, "failed-to-find-text",
-               G_CALLBACK (webkit_find_controller_failed_to_found_text_cb), dialog);
+               G_CALLBACK (content_editor_find_controller_failed_to_found_text_cb), dialog);
 
        dialog->priv->find_controller = find_controller;
 
diff --git a/e-util/e-html-editor-hrule-dialog.c b/e-util/e-html-editor-hrule-dialog.c
index 8130eb3..ead01f3 100644
--- a/e-util/e-html-editor-hrule-dialog.c
+++ b/e-util/e-html-editor-hrule-dialog.c
@@ -23,7 +23,6 @@
 #endif
 
 #include "e-html-editor-hrule-dialog.h"
-#include "e-html-editor-view.h"
 
 #include <glib/gi18n-lib.h>
 #include <stdlib.h>
@@ -50,224 +49,133 @@ static void
 html_editor_hrule_dialog_set_alignment (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        value = gtk_combo_box_get_active_id (
                GTK_COMBO_BOX (dialog->priv->alignment_combo));
 
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-hr", "align", value);
+       e_content_editor_h_rule_set_align (cnt_editor, value);
 }
 
 static void
 html_editor_hrule_dialog_get_alignment (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-hr", "align");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
+       value = e_content_editor_h_rule_get_align (cnt_editor);
+       if (value && *value)
                gtk_combo_box_set_active_id (
                        GTK_COMBO_BOX (dialog->priv->alignment_combo), value);
-               g_variant_unref (result);
-       }
+       g_free (value);
 }
 
 static void
 html_editor_hrule_dialog_set_size (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *size;
+       EContentEditor *cnt_editor;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       size = g_strdup_printf (
-               "%d",
-               (gint) gtk_spin_button_get_value (
-                       GTK_SPIN_BUTTON (dialog->priv->size_edit)));
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-hr", "size", size);
-
-       g_free (size);
+       value = gtk_spin_button_get_value_as_int  GTK_SPIN_BUTTON (dialog->priv->size_edit);
+       e_content_editor_h_rule_set_size (cnt_editor, value);
 }
 
 static void
 html_editor_hrule_dialog_get_size (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-hr", "size");
-
-       if (result) {
-               const gchar *value;
-               gint value_int = 0;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value)
-                       value_int = atoi (value);
+       value = e_content_editor_h_rule_get_size (cnt_editor);
 
-               if (value_int == 0)
-                       value_int = 2;
-
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->size_edit),
-                       (gdouble) value_int);
-
-               g_variant_unref (result);
-       }
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->size_edit), (gdouble) value);
 }
 
 static void
 html_editor_hrule_dialog_set_width (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *width, *units;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       units = gtk_combo_box_text_get_active_text (
-                       GTK_COMBO_BOX_TEXT (dialog->priv->unit_combo));
-       width = g_strdup_printf (
-               "%d%s",
-               (gint) gtk_spin_button_get_value (
+       e_content_editor_h_rule_set_width (
+               cnt_editor,
+               gtk_spin_button_get_value_as_int (
                        GTK_SPIN_BUTTON (dialog->priv->width_edit)),
-               units);
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-hr", "width", width);
-
-       g_free (units);
-       g_free (width);
+               (gtk_combo_box_get_active (
+                       GTK_COMBO_BOX (dialog->priv->unit_combo)) == 0) ?
+                               E_CONTENT_EDITOR_UNIT_PIXEL :
+                               E_CONTENT_EDITOR_UNIT_PERCENTAGE);
 }
 
 static void
 html_editor_hrule_dialog_get_width (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       EContentEditorUnit unit;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-hr", "width");
-
-       if (result) {
-               const gchar *value, *units;
-               gint value_int = 0;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value) {
-                       value_int = atoi (value);
-
-                       if (strstr (value, "%") != NULL)
-                               units = "units-percent";
-                       else
-                               units = "units-px";
-
-                       if (value_int == 0) {
-                               value_int = 100;
-                               units = "units-percent";
-                       }
-
-                       gtk_spin_button_set_value (
-                               GTK_SPIN_BUTTON (dialog->priv->width_edit),
-                               (gdouble) value_int);
-                       gtk_combo_box_set_active_id (
-                               GTK_COMBO_BOX (dialog->priv->unit_combo), units);
-               }
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = e_content_editor_h_rule_get_width (cnt_editor, &unit);
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->width_edit),
+               value == 0 && unit == E_CONTENT_EDITOR_UNIT_PERCENTAGE ? 100 : value);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->unit_combo),
+               unit == E_CONTENT_EDITOR_UNIT_PIXEL ? "units-px" : "units-percent");
 }
 
 static void
 html_editor_hrule_dialog_set_shading (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       gboolean value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "HRElementSetNoShade",
-               g_variant_new (
-                       "(tsb)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-hr",
-                       !gtk_toggle_button_get_active (
-                               GTK_TOGGLE_BUTTON (dialog->priv->shaded_check))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = !gtk_toggle_button_get_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->shaded_check));
+
+       e_content_editor_h_rule_set_no_shade (cnt_editor, value);
 }
 
 static void
 html_editor_hrule_dialog_get_shading (EHTMLEditorHRuleDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       gboolean value = FALSE;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "HRElementGetNoShade",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-hr"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean value;
-
-               g_variant_get (result, "(b)", &value);
-               gtk_toggle_button_set_active (
-                       GTK_TOGGLE_BUTTON (dialog->priv->shaded_check), !value);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = e_content_editor_h_rule_get_no_shade (cnt_editor);
+       gtk_toggle_button_set_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->shaded_check), !value);
 }
 
 static void
@@ -275,14 +183,13 @@ html_editor_hrule_dialog_hide (GtkWidget *widget)
 {
        EHTMLEditor *editor;
        EHTMLEditorHRuleDialog *dialog;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        dialog = E_HTML_EDITOR_HRULE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorHRuleDialogSaveHistoryOnExit");
+       e_content_editor_on_h_rule_dialog_close (cnt_editor);
 
        GTK_WIDGET_CLASS (e_html_editor_hrule_dialog_parent_class)->hide (widget);
 }
@@ -292,58 +199,39 @@ html_editor_hrule_dialog_show (GtkWidget *widget)
 {
        EHTMLEditorHRuleDialog *dialog;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       gboolean h_rule_found = FALSE;
 
        dialog = E_HTML_EDITOR_HRULE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorHRuleDialogFindHRule",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean found = FALSE;
-
-               g_variant_get (result, "(b)", found);
-               if (found) {
-                       html_editor_hrule_dialog_get_alignment (dialog);
-                       html_editor_hrule_dialog_get_size (dialog);
-                       html_editor_hrule_dialog_get_width (dialog);
-                       html_editor_hrule_dialog_get_shading (dialog);
-               } else {
-                       /* For new rule reset the values to default */
-                       gtk_spin_button_set_value (
-                               GTK_SPIN_BUTTON (dialog->priv->width_edit), 100.0);
-                       gtk_combo_box_set_active_id (
-                               GTK_COMBO_BOX (dialog->priv->unit_combo), "units-percent");
-                       gtk_spin_button_set_value (
-                               GTK_SPIN_BUTTON (dialog->priv->size_edit), 2.0);
-                       gtk_combo_box_set_active_id (
-                               GTK_COMBO_BOX (dialog->priv->alignment_combo), "left");
-                       gtk_toggle_button_set_active (
-                               GTK_TOGGLE_BUTTON (dialog->priv->shaded_check), FALSE);
-
-                       html_editor_hrule_dialog_set_alignment (dialog);
-                       html_editor_hrule_dialog_set_size (dialog);
-                       html_editor_hrule_dialog_set_alignment (dialog);
-                       html_editor_hrule_dialog_set_shading (dialog);
-
-                       e_html_editor_view_set_changed (view, TRUE);
-               }
-               g_variant_unref (result);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       h_rule_found = e_content_editor_on_h_rule_dialog_open (cnt_editor);
+
+       if (h_rule_found) {
+               html_editor_hrule_dialog_get_alignment (dialog);
+               html_editor_hrule_dialog_get_size (dialog);
+               html_editor_hrule_dialog_get_width (dialog);
+               html_editor_hrule_dialog_get_shading (dialog);
+       } else {
+               /* For new rule reset the values to default */
+               gtk_spin_button_set_value (
+                       GTK_SPIN_BUTTON (dialog->priv->width_edit), 100.0);
+               gtk_combo_box_set_active_id (
+                       GTK_COMBO_BOX (dialog->priv->unit_combo), "units-percent");
+               gtk_spin_button_set_value (
+                       GTK_SPIN_BUTTON (dialog->priv->size_edit), 2.0);
+               gtk_combo_box_set_active_id (
+                       GTK_COMBO_BOX (dialog->priv->alignment_combo), "left");
+               gtk_toggle_button_set_active (
+                       GTK_TOGGLE_BUTTON (dialog->priv->shaded_check), FALSE);
+
+               html_editor_hrule_dialog_set_alignment (dialog);
+               html_editor_hrule_dialog_set_size (dialog);
+               html_editor_hrule_dialog_set_alignment (dialog);
+               html_editor_hrule_dialog_set_shading (dialog);
+
+               e_content_editor_set_changed (cnt_editor, TRUE);
        }
 
        /* Chain up to parent implementation */
diff --git a/e-util/e-html-editor-image-dialog.c b/e-util/e-html-editor-image-dialog.c
index bd7fd71..50db162 100644
--- a/e-util/e-html-editor-image-dialog.c
+++ b/e-util/e-html-editor-image-dialog.c
@@ -60,16 +60,16 @@ static void
 html_editor_image_dialog_set_src (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        gchar *uri;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        uri = gtk_file_chooser_get_uri (
                GTK_FILE_CHOOSER (dialog->priv->file_chooser));
 
-       e_html_editor_view_replace_image_src (view, "img#-x-evo-current-img", uri);
+       e_content_editor_image_set_src (cnt_editor, uri);
 
        g_free (uri);
 }
@@ -78,54 +78,33 @@ static void
 html_editor_image_dialog_set_alt (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        value = gtk_entry_get_text (GTK_ENTRY (dialog->priv->description_edit));
 
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-img", "alt", value);
+       e_content_editor_image_set_alt (cnt_editor, value);
 }
 
 static void
 html_editor_image_dialog_set_width (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
        gint requested;
-       gulong natural = 0;
+       gint32 natural = 0;
        gint width;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetNaturalWidth",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               g_variant_get (result, "(i)", &natural);
-               g_variant_unref (result);
-       }
+       natural = e_content_editor_image_get_natural_width (cnt_editor);
 
        requested = gtk_spin_button_get_value_as_int (
-                       GTK_SPIN_BUTTON (dialog->priv->width_edit));
+               GTK_SPIN_BUTTON (dialog->priv->width_edit));
 
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->priv->width_units))) {
                case 0: /* px */
@@ -144,54 +123,22 @@ html_editor_image_dialog_set_width (EHTMLEditorImageDialog *dialog)
                        return;
        }
 
-       g_dbus_proxy_call (
-               web_extension,
-               "ImageElementSetWidth",
-               g_variant_new (
-                       "(tsi)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img",
-                       width),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       e_content_editor_image_set_width (cnt_editor, width);
 }
 
 static void
 html_editor_image_dialog_set_width_units (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
        gint requested;
-       gulong natural = 0;
+       gint32 natural = 0;
        gint width = 0;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetNaturalWidth",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               g_variant_get (result, "(i)", &natural);
-               g_variant_unref (result);
-       }
+       natural = e_content_editor_image_get_natural_width (cnt_editor);
 
        requested = gtk_spin_button_get_value_as_int (
                        GTK_SPIN_BUTTON (dialog->priv->width_edit));
@@ -205,8 +152,6 @@ html_editor_image_dialog_set_width_units (EHTMLEditorImageDialog *dialog)
                        } else {
                                width = natural;
                        }
-                       e_html_editor_view_remove_element_attribute (
-                               view, "#-x-evo-current-img", "style");
                        gtk_widget_set_sensitive (dialog->priv->width_edit, TRUE);
                        break;
 
@@ -216,18 +161,17 @@ html_editor_image_dialog_set_width_units (EHTMLEditorImageDialog *dialog)
                        } else {
                                width = 100;
                        }
-                       e_html_editor_view_remove_element_attribute (
-                               view, "#-x-evo-current-img", "style");
                        gtk_widget_set_sensitive (dialog->priv->width_edit, TRUE);
                        break;
 
                case 2: /* follow */
-                       e_html_editor_view_set_element_attribute (
-                               view, "#-x-evo-current-img", "style", "width: auto;");
                        gtk_widget_set_sensitive (dialog->priv->width_edit, FALSE);
                        break;
        }
 
+       e_content_editor_image_set_width_follow (
+               cnt_editor, !gtk_widget_get_sensitive (dialog->priv->width_edit));
+
        if (width != 0)
                gtk_spin_button_set_value (
                        GTK_SPIN_BUTTON (dialog->priv->width_edit), width);
@@ -237,38 +181,18 @@ static void
 html_editor_image_dialog_set_height (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
        gint requested;
-       gulong natural = 0;
+       gint32 natural = 0;
        gint height;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetNaturalHeight",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               g_variant_get (result, "(i)", &natural);
-               g_variant_unref (result);
-       }
+       natural = e_content_editor_image_get_natural_height (cnt_editor);
 
        requested = gtk_spin_button_get_value_as_int (
-                       GTK_SPIN_BUTTON (dialog->priv->height_edit));
+               GTK_SPIN_BUTTON (dialog->priv->height_edit));
 
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->priv->height_units))) {
                case 0: /* px */
@@ -287,57 +211,25 @@ html_editor_image_dialog_set_height (EHTMLEditorImageDialog *dialog)
                        return;
        }
 
-       g_dbus_proxy_call (
-               web_extension,
-               "ImageElementSetHeight",
-               g_variant_new (
-                       "(tsi)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img",
-                       height),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       e_content_editor_image_set_height (cnt_editor, height);
 }
 
 static void
 html_editor_image_dialog_set_height_units (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
        gint requested;
        gulong natural = 0;
        gint height = -1;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetNaturalHeight",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               g_variant_get (result, "(i)", &natural);
-               g_variant_unref (result);
-       }
+       natural = e_content_editor_image_get_natural_height (cnt_editor);
 
        requested = gtk_spin_button_get_value_as_int (
-                       GTK_SPIN_BUTTON (dialog->priv->height_edit));
+               GTK_SPIN_BUTTON (dialog->priv->height_edit));
 
        switch (gtk_combo_box_get_active (
                GTK_COMBO_BOX (dialog->priv->height_units))) {
@@ -348,8 +240,6 @@ html_editor_image_dialog_set_height_units (EHTMLEditorImageDialog *dialog)
                        } else {
                                height = natural;
                        }
-                       e_html_editor_view_remove_element_attribute (
-                               view, "#-x-evo-current-img", "style");
                        gtk_widget_set_sensitive (dialog->priv->height_edit, TRUE);
                        break;
 
@@ -359,18 +249,17 @@ html_editor_image_dialog_set_height_units (EHTMLEditorImageDialog *dialog)
                        } else {
                                height = 100;
                        }
-                       e_html_editor_view_remove_element_attribute (
-                               view, "#-x-evo-current-img", "style");
                        gtk_widget_set_sensitive (dialog->priv->height_edit, TRUE);
                        break;
 
                case 2: /* follow */
-                       e_html_editor_view_set_element_attribute (
-                               view, "#-x-evo-current-img", "style", "height: auto;");
                        gtk_widget_set_sensitive (dialog->priv->height_edit, FALSE);
                        break;
        }
 
+       e_content_editor_image_set_height_follow (
+               cnt_editor, !gtk_widget_get_sensitive (dialog->priv->height_edit));
+
        if (height != -1)
                gtk_spin_button_set_value (
                        GTK_SPIN_BUTTON (dialog->priv->height_edit), height);
@@ -380,120 +269,75 @@ static void
 html_editor_image_dialog_set_alignment (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        const gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        value = gtk_combo_box_get_active_id (GTK_COMBO_BOX (dialog->priv->alignment));
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-img", "align", value);
+       e_content_editor_image_set_align (cnt_editor, value);
 }
 
 static void
 html_editor_image_dialog_set_x_padding (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "ImageElementSetHSpace",
-               g_variant_new (
-                       "(tsi)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img",
-                       gtk_spin_button_get_value_as_int (
-                               GTK_SPIN_BUTTON (dialog->priv->x_padding_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = gtk_spin_button_get_value_as_int (
+               GTK_SPIN_BUTTON (dialog->priv->x_padding_edit));
+       e_content_editor_image_set_hspace (cnt_editor, value);
 }
 
 static void
 html_editor_image_dialog_set_y_padding (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "ImageElementSetVSpace",
-               g_variant_new (
-                       "(tsi)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img",
-                       gtk_spin_button_get_value_as_int (
-                               GTK_SPIN_BUTTON (dialog->priv->y_padding_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = gtk_spin_button_get_value_as_int (
+               GTK_SPIN_BUTTON (dialog->priv->y_padding_edit));
+       e_content_editor_image_set_vspace (cnt_editor, value);
 }
 
 static void
 html_editor_image_dialog_set_border (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *value;
+       EContentEditor *cnt_editor;
+       gint value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       value = g_strdup_printf (
-               "%d", gtk_spin_button_get_value_as_int (
-                       GTK_SPIN_BUTTON (dialog->priv->border_edit)));
+       value = gtk_spin_button_get_value_as_int (
+               GTK_SPIN_BUTTON (dialog->priv->border_edit));
 
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-img", "border", value);
-
-       g_free (value);
+       e_content_editor_image_set_border (cnt_editor, value);
 }
 
 static void
 html_editor_image_dialog_set_url (EHTMLEditorImageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       const gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorImageDialogSetElementUrl",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       value = gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit));
+
+       e_content_editor_image_set_url (cnt_editor, value);
 }
 
 static void
@@ -511,173 +355,70 @@ html_editor_image_dialog_show (GtkWidget *widget)
 {
        EHTMLEditor *editor;
        EHTMLEditorImageDialog *dialog;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gchar *value;
 
        dialog = E_HTML_EDITOR_IMAGE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorImageDialogMarkImage");
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-img", "data-uri");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value) {
-                       gtk_file_chooser_set_uri (
-                               GTK_FILE_CHOOSER (dialog->priv->file_chooser), value);
-                       gtk_widget_set_sensitive (
-                               GTK_WIDGET (dialog->priv->file_chooser), TRUE);
-               } else {
-                       gtk_file_chooser_set_uri (
-                               GTK_FILE_CHOOSER (dialog->priv->file_chooser), "");
-                       gtk_widget_set_sensitive (
-                               GTK_WIDGET (dialog->priv->file_chooser), FALSE);
-               }
-               g_variant_unref (result);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_image_dialog_open (cnt_editor);
+
+       value = e_content_editor_image_get_src (cnt_editor);
+       if (value && *value) {
+               gtk_file_chooser_set_uri (
+                       GTK_FILE_CHOOSER (dialog->priv->file_chooser), value);
+               gtk_widget_set_sensitive (
+                       GTK_WIDGET (dialog->priv->file_chooser), TRUE);
+       } else {
+               gtk_file_chooser_set_uri (
+                       GTK_FILE_CHOOSER (dialog->priv->file_chooser), "");
+               gtk_widget_set_sensitive (
+                       GTK_WIDGET (dialog->priv->file_chooser), FALSE);
        }
+       g_free (value);
 
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-img", "alt");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               gtk_entry_set_text (
-                       GTK_ENTRY (dialog->priv->description_edit),
-                       value ? value : "");
-               g_variant_unref (result);
-       }
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetWidth",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               glong value = 0;
-
-               g_variant_get (result, "(&i)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->width_edit), value);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->width_units), "units-px");
-               g_variant_unref (result);
-       }
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetHeight",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               glong value;
-
-               g_variant_get (result, "(i)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->height_edit), value);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->height_units), "units-px");
-               g_variant_unref (result);
-       }
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-img", "border");
-
-       if (result) {
-               const gchar *value;
+       value = e_content_editor_image_get_alt (cnt_editor);
+       gtk_entry_set_text (
+               GTK_ENTRY (dialog->priv->description_edit), value ? value : "");
+       g_free (value);
 
-               g_variant_get (result, "(&s)", &value);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->alignment),
-                       (value && *value) ? value : "bottom");
-               g_variant_unref (result);
-       }
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->width_edit),
+               e_content_editor_image_get_width (cnt_editor));
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetHSpace",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->width_units), "units-px");
 
-       if (result) {
-               glong value = 0;
-
-               g_variant_get (result, "(&i)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->x_padding_edit), value);
-               g_variant_unref (result);
-       }
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->height_edit),
+               e_content_editor_image_get_height (cnt_editor));
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ImageElementGetVSpace",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-img"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->height_units), "units-px");
 
-       if (result) {
-               glong value = 0;
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->border_edit),
+               e_content_editor_image_get_border (cnt_editor));
 
-               g_variant_get (result, "(&i)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->y_padding_edit), value);
-               g_variant_unref (result);
-       }
+       value = e_content_editor_image_get_align (cnt_editor);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->alignment),
+               (value && *value) ? value : "bottom");
+       g_free (value);
 
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorImageDialogGetElementUrl",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->y_padding_edit),
+               e_content_editor_image_get_hspace (cnt_editor));
 
-       if (result) {
-               const gchar *value;
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->y_padding_edit),
+               e_content_editor_image_get_vspace (cnt_editor));
 
-               g_variant_get (result, "(&s)", &value);
+       value = e_content_editor_image_get_url (cnt_editor);
+       if (value && *value)
                gtk_entry_set_text (GTK_ENTRY (dialog->priv->url_edit), value);
-               g_variant_unref (result);
-       }
+       g_free (value);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_image_dialog_parent_class)->show (widget);
@@ -688,14 +429,13 @@ html_editor_image_dialog_hide (GtkWidget *widget)
 {
        EHTMLEditor *editor;
        EHTMLEditorImageDialog *dialog;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        dialog = E_HTML_EDITOR_IMAGE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorImageDialogSaveHistoryOnExit");
+       e_content_editor_on_image_dialog_close (cnt_editor);
 
        GTK_WIDGET_CLASS (e_html_editor_image_dialog_parent_class)->hide (widget);
 }
diff --git a/e-util/e-html-editor-link-dialog.c b/e-util/e-html-editor-link-dialog.c
index 0c79a57..9d788e1 100644
--- a/e-util/e-html-editor-link-dialog.c
+++ b/e-util/e-html-editor-link-dialog.c
@@ -23,8 +23,6 @@
 #endif
 
 #include "e-html-editor-link-dialog.h"
-#include "e-html-editor-selection.h"
-#include "e-html-editor-view.h"
 
 #include <glib/gi18n-lib.h>
 
@@ -87,42 +85,27 @@ static void
 html_editor_link_dialog_remove_link (EHTMLEditorLinkDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorSelectionDOMUnlink");
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       gtk_widget_hide (GTK_WIDGET (dialog));
+       e_content_editor_selection_unlink (cnt_editor);
 }
 
 static void
 html_editor_link_dialog_ok (EHTMLEditorLinkDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorLinkDialogOk",
-               g_variant_new (
-                       "(tss)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit)),
-                       gtk_entry_get_text (GTK_ENTRY (dialog->priv->label_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_link_set_values (
+               cnt_editor,
+               gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit)),
+               gtk_entry_get_text (GTK_ENTRY (dialog->priv->label_edit)));
 
        gtk_widget_hide (GTK_WIDGET (dialog));
 }
@@ -146,16 +129,12 @@ html_editor_link_dialog_show (GtkWidget *widget)
 {
        EHTMLEditor *editor;
        EHTMLEditorLinkDialog *dialog;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gchar *href = NULL, *text = NULL;
 
        dialog = E_HTML_EDITOR_LINK_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* Reset to default values */
        gtk_entry_set_text (GTK_ENTRY (dialog->priv->url_edit), "http://";);
@@ -164,39 +143,22 @@ html_editor_link_dialog_show (GtkWidget *widget)
        gtk_widget_set_sensitive (dialog->priv->remove_link_button, TRUE);
 
        dialog->priv->label_autofill = TRUE;
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorLinkDialogShow",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
 
-       if (result) {
-               const gchar *href, *inner_text;
-
-               g_variant_get (result, "(&s&s)", &href, &inner_text);
-
-               if (href && *href) {
-                       gtk_entry_set_text (
-                               GTK_ENTRY (dialog->priv->url_edit), href);
-               }
-
-               if (inner_text && *inner_text) {
-                       gtk_widget_set_sensitive (
-                               dialog->priv->label_edit, TRUE);
-                       if (!href || !*href) {
-                               gtk_widget_set_sensitive (
-                                       dialog->priv->label_edit, FALSE);
-                               gtk_widget_set_sensitive (
-                                       dialog->priv->remove_link_button, FALSE);
-                       }
-               }
-               g_variant_unref (result);
+       e_content_editor_link_get_values (cnt_editor, &href, &text);
+       if (href && *href)
+               gtk_entry_set_text (
+                       GTK_ENTRY (dialog->priv->url_edit), href);
+       else {
+               gtk_widget_set_sensitive (
+                       dialog->priv->remove_link_button, FALSE);
+       }
+       g_free (href);
+
+       if (text && *text) {
+               gtk_entry_set_text (
+                       GTK_ENTRY (dialog->priv->label_edit), text);
        }
+       g_free (text);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_link_dialog_parent_class)->show (widget);
diff --git a/e-util/e-html-editor-page-dialog.c b/e-util/e-html-editor-page-dialog.c
index 10f7cb2..2399566 100644
--- a/e-util/e-html-editor-page-dialog.c
+++ b/e-util/e-html-editor-page-dialog.c
@@ -148,102 +148,64 @@ static void
 html_editor_page_dialog_set_text_color (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
-       gchar *color;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->text_color_picker), &rgba);
 
-       color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-
-       e_html_editor_view_set_element_attribute (
-               view, "body", "text", color);
-
-       g_free (color);
+       e_content_editor_page_set_text_color (cnt_editor, &rgba);
 }
 
 static void
 html_editor_page_dialog_set_link_color (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
-       gchar *color;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->link_color_picker), &rgba);
 
-       color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-
-       e_html_editor_view_set_element_attribute (
-               view, "body", "link", color);
-
-       g_free (color);
+       e_content_editor_page_set_link_color (cnt_editor, &rgba);
 }
 
 static void
 html_editor_page_dialog_set_visited_link_color (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
-       gchar *color;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->visited_link_color_picker), &rgba);
 
-       color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-
-       e_html_editor_view_set_element_attribute (
-               view, "body", "vlink", color);
-
-       g_free (color);
+       e_content_editor_page_set_visited_link_color (cnt_editor, &rgba);
 }
 
 static void
 html_editor_page_dialog_set_background_color (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
-       gchar *color;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
-       if (rgba.alpha != 0.0)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-       else
-               color = g_strdup ("");
-
-       e_html_editor_view_set_element_attribute (
-               view, "body", "bgcolor", color);
 
-       g_free (color);
+       e_content_editor_page_set_background_color (cnt_editor, &rgba);
 }
 
 static void
@@ -286,34 +248,16 @@ static void
 html_editor_page_dialog_set_background_image (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        gchar *uri;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        uri = gtk_file_chooser_get_uri (
                GTK_FILE_CHOOSER (dialog->priv->background_image_filechooser));
 
-       if (uri && *uri)
-               e_html_editor_view_replace_image_src (view, "body", uri);
-       else
-               g_dbus_proxy_call (
-                       web_extension,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new (
-                               "(ts)",
-                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                               "body"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
+       e_content_editor_page_set_background_image_uri (cnt_editor, uri);
 
        gtk_widget_set_sensitive (dialog->priv->remove_image_button, uri && *uri);
 
@@ -324,27 +268,12 @@ static void
 html_editor_page_dialog_remove_image (EHTMLEditorPageDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "RemoveImageAttributesFromElementBySelector",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "body"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_page_set_background_image_uri (cnt_editor, NULL);
 
        gtk_file_chooser_unselect_all (
                GTK_FILE_CHOOSER (dialog->priv->background_image_filechooser));
@@ -356,118 +285,53 @@ static void
 html_editor_page_dialog_show (GtkWidget *widget)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EHTMLEditorPageDialog *dialog;
-       GDBusProxy *web_extension;
        GdkRGBA rgba;
-       GVariant *result;
+       gchar *uri;
 
        dialog = E_HTML_EDITOR_PAGE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorPageDialogSaveHistory");
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "body", "data-uri");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-
-               if (value && *value) {
-                       gint ii;
-                       gchar *fname = g_filename_from_uri (value, NULL, NULL);
-                       for (ii = 0; ii < G_N_ELEMENTS (templates); ii++) {
-                               const Template *tmplt = &templates[ii];
-
-                               if (g_strcmp0 (tmplt->filename, fname) == 0) {
-                                       gtk_combo_box_set_active (
-                                               GTK_COMBO_BOX (dialog->priv->background_template_combo),
-                                               ii);
-                                       break;
-                               }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_page_dialog_open (cnt_editor);
+
+       uri = e_content_editor_page_get_background_image_uri (cnt_editor);
+       if (uri && *uri) {
+               gint ii;
+               gchar *fname = g_filename_from_uri (uri, NULL, NULL);
+               for (ii = 0; ii < G_N_ELEMENTS (templates); ii++) {
+                       const Template *tmplt = &templates[ii];
+
+                       if (g_strcmp0 (tmplt->filename, fname) == 0) {
+                               gtk_combo_box_set_active (
+                                       GTK_COMBO_BOX (dialog->priv->background_template_combo),
+                                       ii);
+                               break;
                        }
-                       g_free (fname);
-               } else {
-                       gtk_combo_box_set_active (
-                               GTK_COMBO_BOX (dialog->priv->background_template_combo), 0);
                }
-               g_variant_unref (result);
-       }
-
-       result = e_html_editor_view_get_element_attribute (view, "body", "text");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (!value || !*value || !gdk_rgba_parse (&rgba, value))
-                       e_utils_get_theme_color (
-                               widget,
-                               "theme_text_color",
-                               E_UTILS_DEFAULT_THEME_TEXT_COLOR,
-                               &rgba);
-               e_color_combo_set_current_color (
-                       E_COLOR_COMBO (dialog->priv->text_color_picker), &rgba);
-               g_variant_unref (result);
-       }
-
-       result = e_html_editor_view_get_element_attribute (view, "body", "link");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (!gdk_rgba_parse (&rgba, value)) {
-                       rgba.alpha = 1;
-                       rgba.red = 0;
-                       rgba.green = 0;
-                       rgba.blue = 1;
-               }
-               e_color_combo_set_current_color (
-                       E_COLOR_COMBO (dialog->priv->link_color_picker), &rgba);
-               g_variant_unref (result);
+               g_free (fname);
+       } else {
+               gtk_combo_box_set_active (
+                       GTK_COMBO_BOX (dialog->priv->background_template_combo), 0);
        }
+       g_free (uri);
 
-       result = e_html_editor_view_get_element_attribute (view, "body", "vlink");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (!gdk_rgba_parse (&rgba, value)) {
-                       rgba.alpha = 1;
-                       rgba.red = 1;
-                       rgba.green = 0;
-                       rgba.blue = 0;
-               }
-               e_color_combo_set_current_color (
-                       E_COLOR_COMBO (dialog->priv->visited_link_color_picker), &rgba);
-               g_variant_unref (result);
-       }
+       e_content_editor_page_get_text_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->text_color_picker), &rgba);
 
-       result = e_html_editor_view_get_element_attribute (view, "body", "bgcolor");
+       e_content_editor_page_get_link_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->link_color_picker), &rgba);
 
-       if (result) {
-               const gchar *value;
+       e_content_editor_page_get_visited_link_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->visited_link_color_picker), &rgba);
 
-               g_variant_get (result, "(&s)", &value);
-               if (!value || !*value || !gdk_rgba_parse (&rgba, value))
-                       e_utils_get_theme_color (
-                       widget,
-                       "theme_base_color",
-                       E_UTILS_DEFAULT_THEME_BASE_COLOR,
-                       &rgba);
-               e_color_combo_set_current_color (
-                       E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
-               g_variant_unref (result);
-       }
+       e_content_editor_page_get_background_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
 
        GTK_WIDGET_CLASS (e_html_editor_page_dialog_parent_class)->show (widget);
 }
@@ -476,15 +340,14 @@ static void
 html_editor_page_dialog_hide (GtkWidget *widget)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EHTMLEditorPageDialog *dialog;
 
        dialog = E_HTML_EDITOR_PAGE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorPageDialogSaveHistoryOnExit");
+       e_content_editor_on_page_dialog_close (cnt_editor);
 
        GTK_WIDGET_CLASS (e_html_editor_page_dialog_parent_class)->hide (widget);
 }
diff --git a/e-util/e-html-editor-private.h b/e-util/e-html-editor-private.h
index f0524d0..46a1e14 100644
--- a/e-util/e-html-editor-private.h
+++ b/e-util/e-html-editor-private.h
@@ -36,7 +36,6 @@
 #include <e-html-editor-spell-check-dialog.h>
 #include <e-html-editor-table-dialog.h>
 #include <e-html-editor-text-dialog.h>
-#include <e-html-editor-view.h>
 
 #ifdef HAVE_XFREE
 #include <X11/XF86keysym.h>
@@ -84,8 +83,9 @@ struct _EHTMLEditorPrivate {
        GtkWidget *style_combo_box;
        GtkWidget *scrolled_window;
 
-       EHTMLEditorView *html_editor_view;
-       EHTMLEditorSelection *selection;
+       GList *content_editors;
+
+       EContentEditorNodeFlags node_flags;
 
        gchar *filename;
 
diff --git a/e-util/e-html-editor-replace-dialog.c b/e-util/e-html-editor-replace-dialog.c
index 6700309..b846711 100644
--- a/e-util/e-html-editor-replace-dialog.c
+++ b/e-util/e-html-editor-replace-dialog.c
@@ -23,8 +23,8 @@
 #endif
 
 #include "e-html-editor-replace-dialog.h"
+#include "e-content-editor-find-controller.h"
 
-#include <webkit2/webkit2.h>
 #include <glib/gi18n-lib.h>
 
 #define E_HTML_EDITOR_REPLACE_DIALOG_GET_PRIVATE(obj) \
@@ -52,12 +52,10 @@ struct _EHTMLEditorReplaceDialogPrivate {
 
        EHTMLEditor *editor;
 
-       gboolean replace_all;
-
-       WebKitFindController *find_controller;
+       EContentEditorFindController *find_controller;
        gulong found_text_handler_id;
        gulong failed_to_find_text_handler_id;
-       gulong counted_matches_handler_id;
+       gulong replace_all_finished_handler_id;
 };
 
 enum {
@@ -66,54 +64,42 @@ enum {
 };
 
 static void
-webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
-                                      guint match_count,
-                                      EHTMLEditorReplaceDialog *dialog)
+content_editor_find_controller_found_text_cb (EContentEditorFindController *find_controller,
+                                              guint match_count,
+                                              EHTMLEditorReplaceDialog *dialog)
 {
        gtk_widget_hide (dialog->priv->result_label);
 }
 
 static void
-webkit_find_controller_failed_to_found_text_cb (WebKitFindController *find_controller,
-                                                EHTMLEditorReplaceDialog *dialog)
+content_editor_find_controller_failed_to_found_text_cb (EContentEditorFindController *find_controller,
+                                                        EHTMLEditorReplaceDialog *dialog)
 {
-       if (!dialog->priv->replace_all) {
-               gtk_label_set_label (
-                       GTK_LABEL (dialog->priv->result_label), N_("No match found"));
-               gtk_widget_show (dialog->priv->result_label);
-       }
-
-       dialog->priv->replace_all = FALSE;
+       gtk_label_set_label (
+               GTK_LABEL (dialog->priv->result_label), N_("No match found"));
+       gtk_widget_show (dialog->priv->result_label);
 }
 
 static void
 replace_occurance (EHTMLEditorReplaceDialog *dialog)
 {
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
 
-       selection = e_html_editor_view_get_selection (E_HTML_EDITOR_VIEW (
-               webkit_find_controller_get_web_view (dialog->priv->find_controller)));
+       cnt_editor = e_html_editor_get_content_editor (dialog->priv->editor);
 
        gtk_widget_hide (dialog->priv->result_label);
 
-       e_html_editor_selection_replace (
-               selection,
+       e_content_editor_selection_replace (
+               cnt_editor,
                gtk_entry_get_text (GTK_ENTRY (dialog->priv->replace_entry)));
 }
 
 static void
-webkit_find_controller_counted_matches_cb (WebKitFindController *find_controller,
-                                           guint match_count,
-                                           EHTMLEditorReplaceDialog *dialog)
+content_editor_find_controller_replace_all_finished_cb (EContentEditorFindController *find_controller,
+                                                        guint match_count,
+                                                        EHTMLEditorReplaceDialog *dialog)
 {
        gchar *result;
-       guint ii = 0;
-
-       for (ii = 0; ii < match_count; ii++) {
-               replace_occurance (dialog);
-
-               webkit_find_controller_search_next (dialog->priv->find_controller);
-       }
 
        result = g_strdup_printf (ngettext("%d occurrence replaced",
                                           "%d occurrences replaced",
@@ -131,25 +117,24 @@ search (EHTMLEditorReplaceDialog *dialog)
        guint32 flags = 0;
 
        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->case_sensitive)))
-               flags |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+               flags |= E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->backwards)))
-               flags |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+               flags |= E_CONTENT_EDITOR_FIND_BACKWARDS;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap)))
-               flags |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+               flags |= E_CONTENT_EDITOR_FIND_WRAP_AROUND;
 
-       webkit_find_controller_search (
+       e_content_editor_find_controller_search (
                dialog->priv->find_controller,
                gtk_entry_get_text (GTK_ENTRY (dialog->priv->search_entry)),
-               flags,
-               G_MAXUINT);
+               flags);
 }
 
 static void
 html_editor_replace_dialog_skip_cb (EHTMLEditorReplaceDialog *dialog)
 {
-       webkit_find_controller_search_next (dialog->priv->find_controller);
+       e_content_editor_find_controller_search_next (dialog->priv->find_controller);
 }
 
 static void
@@ -158,7 +143,7 @@ html_editor_replace_dialog_replace_cb (EHTMLEditorReplaceDialog *dialog)
        replace_occurance (dialog);
 
        /* Jump to next matching word */
-       webkit_find_controller_search_next (dialog->priv->find_controller);
+       e_content_editor_find_controller_search_next (dialog->priv->find_controller);
 }
 
 static void
@@ -167,21 +152,19 @@ html_editor_replace_dialog_replace_all_cb (EHTMLEditorReplaceDialog *dialog)
        guint32 flags = 0;
 
        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->case_sensitive)))
-               flags |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+               flags |= E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->backwards)))
-               flags |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+               flags |= E_CONTENT_EDITOR_FIND_BACKWARDS;
 
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap)))
-               flags |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+               flags |= E_CONTENT_EDITOR_FIND_WRAP_AROUND;
 
-       webkit_find_controller_count_matches (
+       e_content_editor_find_controller_replace_all (
                dialog->priv->find_controller,
                gtk_entry_get_text (GTK_ENTRY (dialog->priv->search_entry)),
-               flags,
-               G_MAXUINT);
-
-       dialog->priv->replace_all = TRUE;
+               gtk_entry_get_text (GTK_ENTRY (dialog->priv->replace_entry)),
+               flags);
 }
 
 static void
@@ -202,8 +185,15 @@ html_editor_replace_dialog_entry_changed (EHTMLEditorReplaceDialog *dialog)
 static void
 html_editor_replace_dialog_show (GtkWidget *widget)
 {
+       EContentEditor *cnt_editor;
+       EHTMLEditor *editor;
        EHTMLEditorReplaceDialog *dialog = E_HTML_EDITOR_REPLACE_DIALOG (widget);
 
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_replace_dialog_open (cnt_editor);
+
        gtk_widget_grab_focus (dialog->priv->search_entry);
        gtk_widget_hide (dialog->priv->result_label);
 
@@ -214,9 +204,15 @@ html_editor_replace_dialog_show (GtkWidget *widget)
 static void
 html_editor_replace_dialog_hide (GtkWidget *widget)
 {
+       EContentEditor *cnt_editor;
+       EHTMLEditor *editor;
        EHTMLEditorReplaceDialog *dialog = E_HTML_EDITOR_REPLACE_DIALOG (widget);
 
-       webkit_find_controller_search_finish (dialog->priv->find_controller);
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_find_controller_search_finish (dialog->priv->find_controller);
+       e_content_editor_on_spell_check_dialog_close (cnt_editor);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_replace_dialog_parent_class)->hide (widget);
@@ -225,30 +221,29 @@ html_editor_replace_dialog_hide (GtkWidget *widget)
 static void
 html_editor_replace_dialog_constructed (GObject *object)
 {
+       EContentEditor *cnt_editor;
        EHTMLEditor *editor;
        EHTMLEditorReplaceDialog *dialog;
-       EHTMLEditorView *view;
-       WebKitFindController *find_controller;
+       EContentEditorFindController *find_controller;
 
        dialog = E_HTML_EDITOR_REPLACE_DIALOG (object);
        dialog->priv = E_HTML_EDITOR_REPLACE_DIALOG_GET_PRIVATE (dialog);
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       find_controller =
-               webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (view));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       find_controller = e_content_editor_get_find_controller (cnt_editor);
 
        dialog->priv->found_text_handler_id = g_signal_connect (
                find_controller, "found-text",
-               G_CALLBACK (webkit_find_controller_found_text_cb), dialog);
+               G_CALLBACK (content_editor_find_controller_found_text_cb), dialog);
 
        dialog->priv->failed_to_find_text_handler_id = g_signal_connect (
                find_controller, "failed-to-find-text",
-               G_CALLBACK (webkit_find_controller_failed_to_found_text_cb), dialog);
+               G_CALLBACK (content_editor_find_controller_failed_to_found_text_cb), dialog);
 
-       dialog->priv->counted_matches_handler_id = g_signal_connect (
-               find_controller, "counted-matches",
-               G_CALLBACK (webkit_find_controller_counted_matches_cb), dialog);
+       dialog->priv->replace_all_finished_handler_id = g_signal_connect (
+               find_controller, "replace-all-finished",
+               G_CALLBACK (content_editor_find_controller_replace_all_finished_cb), dialog);
 
        dialog->priv->find_controller = find_controller;
 
@@ -276,11 +271,11 @@ html_editor_replace_dialog_dispose (GObject *object)
                priv->failed_to_find_text_handler_id = 0;
        }
 
-       if (priv->counted_matches_handler_id > 0) {
+       if (priv->replace_all_finished_handler_id > 0) {
                g_signal_handler_disconnect (
                        priv->find_controller,
-                       priv->counted_matches_handler_id);
-               priv->counted_matches_handler_id = 0;
+                       priv->replace_all_finished_handler_id);
+               priv->replace_all_finished_handler_id = 0;
        }
 
        /* Chain up to parent's dispose() method. */
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index 547e489..4755799 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -73,8 +73,8 @@ struct _EHTMLEditorSelectionPrivate {
 
        guint font_size;
 
-       EHTMLEditorSelectionAlignment alignment;
-       EHTMLEditorSelectionBlockFormat block_format;
+       EContentEditorAlignment alignment;
+       EContentEditorBlockFormat block_format;
 };
 
 enum {
@@ -168,8 +168,7 @@ web_extension_properties_changed_cb (GDBusProxy *proxy,
                        } else if (g_strcmp0 (key, "HTMLMode") != 0 &&
                                   g_strcmp0 (key, "Changed") != 0 &&
                                   g_strcmp0 (key, "MagicLinks") != 0 &&
-                                  g_strcmp0 (key, "MagicSmileys") != 0 &&
-                                  g_strcmp0 (key, "InlineSpelling") != 0)
+                                  g_strcmp0 (key, "MagicSmileys") != 0)
                                g_warning ("UNKNOWN PROPERTY %s IN %s", key, G_STRFUNC);
                        if (camel_debug ("wex"))
                                g_print ("      %s -> %s\n", key, value_str);
@@ -510,9 +509,9 @@ e_html_editor_selection_class_init (EHTMLEditorSelectionClass *class)
                        "alignment",
                        NULL,
                        NULL,
-                       E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT,
-                       E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT,
-                       E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT,
+                       E_CONTENT_EDITOR_ALIGNMENT_LEFT,
+                       E_CONTENT_EDITOR_ALIGNMENT_RIGHT,
+                       E_CONTENT_EDITOR_ALIGNMENT_LEFT,
                        G_PARAM_READWRITE));
 
        /**
@@ -535,9 +534,9 @@ e_html_editor_selection_class_init (EHTMLEditorSelectionClass *class)
         * EHTMLEditorSelection:block-format
         *
         * Holds block format of current paragraph. See
-        * #EHTMLEditorSelectionBlockFormat for valid values.
+        * #EContentEditorBlockFormat for valid values.
         */
-       /* FIXME Convert the EHTMLEditorSelectionBlockFormat
+       /* FIXME Convert the EContentEditorBlockFormat
         *       enum to a proper type. */
        g_object_class_install_property (
                object_class,
@@ -772,8 +771,8 @@ static void
 e_html_editor_selection_init (EHTMLEditorSelection *selection)
 {
        selection->priv = E_HTML_EDITOR_SELECTION_GET_PRIVATE (selection);
-       selection->priv->block_format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
-       selection->priv->font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+       selection->priv->block_format = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
+       selection->priv->font_size = E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
 }
 
 /**
@@ -793,177 +792,6 @@ e_html_editor_selection_ref_html_editor_view (EHTMLEditorSelection *selection)
        return g_weak_ref_get (&selection->priv->html_editor_view);
 }
 
-/**
- * e_html_editor_selection_has_text:
- * @selection: an #EHTMLEditorSelection
- *
- * Returns whether current selection contains any text.
- *
- * Returns: @TRUE when current selection contains text, @FALSE otherwise.
- */
-gboolean
-e_html_editor_selection_has_text (EHTMLEditorSelection *selection)
-{
-       EHTMLEditorView *view;
-       gboolean ret_val = FALSE;
-       GDBusProxy *web_extension;
-       GVariant *result;
-
-       g_return_val_if_fail (E_IS_HTML_EDITOR_SELECTION (selection), ret_val);
-
-       view = e_html_editor_selection_ref_html_editor_view (selection);
-       g_return_val_if_fail (view != NULL, ret_val);
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMSelectionHasText",
-               g_variant_new (
-                       "(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(b)", &ret_val);
-               g_variant_unref (result);
-       }
- out:
-       g_object_unref (view);
-
-       return ret_val;
-}
-
-/**
- * e_html_editor_selection_get_caret_word:
- * @selection: an #EHTMLEditorSelection
- *
- * Returns word under cursor.
- *
- * Returns: A newly allocated string with current caret word or @NULL when there
- * is no text under cursor or when selection is active. [transfer-full].
- */
-gchar *
-e_html_editor_selection_get_caret_word (EHTMLEditorSelection *selection)
-{
-       EHTMLEditorView *view;
-       gchar *ret_val = NULL;
-       GDBusProxy *web_extension;
-       GVariant *result;
-
-       g_return_val_if_fail (E_IS_HTML_EDITOR_SELECTION (selection), ret_val);
-
-       view = e_html_editor_selection_ref_html_editor_view (selection);
-       g_return_val_if_fail (view != NULL, ret_val);
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMGetCaretWord",
-               g_variant_new (
-                       "(t)", webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(s)", &ret_val);
-               g_variant_unref (result);
-       }
- out:
-       g_object_unref (view);
-
-       return ret_val;
-}
-
-/**
- * e_html_editor_selection_replace_caret_word:
- * @selection: an #EHTMLEditorSelection
- * @replacement: a string to replace current caret word with
- *
- * Replaces current word under cursor with @replacement.
- */
-void
-e_html_editor_selection_replace_caret_word (EHTMLEditorSelection *selection,
-                                            const gchar *replacement)
-{
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-
-       g_return_if_fail (E_IS_HTML_EDITOR_SELECTION (selection));
-       g_return_if_fail (replacement != NULL);
-
-       view = e_html_editor_selection_ref_html_editor_view (selection);
-       g_return_if_fail (view != NULL);
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "DOMReplaceCaretWord",
-               g_variant_new ("(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       replacement),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-
- out:
-       g_object_unref (view);
-}
-
-/**
- * e_html_editor_selection_replace:
- * @selection: an #EHTMLEditorSelection
- * @replacement: a string to replace current selection with
- *
- * Replaces currently selected text with @replacement.
- */
-void
-e_html_editor_selection_replace (EHTMLEditorSelection *selection,
-                                 const gchar *replacement)
-{
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-
-       if (camel_debug ("wex"))
-               printf ("%s\n", G_STRFUNC);
-       g_return_if_fail (E_IS_HTML_EDITOR_SELECTION (selection));
-
-       view = e_html_editor_selection_ref_html_editor_view (selection);
-       g_return_if_fail (view != NULL);
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMSelectionReplace",
-               g_variant_new ("(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       replacement),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
- out:
-       g_object_unref (view);
-}
-
 static const gchar *
 html_editor_selection_get_format_string (EHTMLEditorSelection *selection,
                                          const gchar *format_name)
@@ -1098,14 +926,14 @@ html_editor_selection_set_format_unsigned (EHTMLEditorSelection *selection,
  *
  * Returns alignment of current paragraph
  *
- * Returns: #EHTMLEditorSelectionAlignment
+ * Returns: #EContentEditorAlignment
  */
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
 e_html_editor_selection_get_alignment (EHTMLEditorSelection *selection)
 {
        g_return_val_if_fail (
                E_IS_HTML_EDITOR_SELECTION (selection),
-               E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT);
+               E_CONTENT_EDITOR_ALIGNMENT_LEFT);
 
        return selection->priv->alignment;
 }
@@ -1113,13 +941,13 @@ e_html_editor_selection_get_alignment (EHTMLEditorSelection *selection)
 /**
  * e_html_editor_selection_set_alignment:
  * @selection: an #EHTMLEditorSelection
- * @alignment: an #EHTMLEditorSelectionAlignment value to apply
+ * @alignment: an #EContentEditorAlignment value to apply
  *
  * Sets alignment of current paragraph to give @alignment.
  */
 void
 e_html_editor_selection_set_alignment (EHTMLEditorSelection *selection,
-                                       EHTMLEditorSelectionAlignment alignment)
+                                       EContentEditorAlignment alignment)
 {
        g_return_if_fail (E_IS_HTML_EDITOR_SELECTION (selection));
 
@@ -1134,14 +962,14 @@ e_html_editor_selection_set_alignment (EHTMLEditorSelection *selection,
  *
  * Returns block format of current paragraph.
  *
- * Returns: #EHTMLEditorSelectionBlockFormat
+ * Returns: #EContentEditorBlockFormat
  */
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
 e_html_editor_selection_get_block_format (EHTMLEditorSelection *selection)
 {
        g_return_val_if_fail (
                E_IS_HTML_EDITOR_SELECTION (selection),
-               E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH);
+               E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH);
 
        return selection->priv->block_format;
 }
@@ -1149,13 +977,13 @@ e_html_editor_selection_get_block_format (EHTMLEditorSelection *selection)
 /**
  * e_html_editor_selection_set_block_format:
  * @selection: an #EHTMLEditorSelection
- * @format: an #EHTMLEditorSelectionBlockFormat value
+ * @format: an #EContentEditorBlockFormat value
  *
  * Changes block format of current paragraph to @format.
  */
 void
 e_html_editor_selection_set_block_format (EHTMLEditorSelection *selection,
-                                          EHTMLEditorSelectionBlockFormat format)
+                                          EContentEditorBlockFormat format)
 {
        g_return_if_fail (E_IS_HTML_EDITOR_SELECTION (selection));
 
@@ -1348,7 +1176,7 @@ e_html_editor_selection_get_font_size (EHTMLEditorSelection *selection)
 {
        g_return_val_if_fail (
                E_IS_HTML_EDITOR_SELECTION (selection),
-               E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL);
+               E_CONTENT_EDITOR_FONT_SIZE_NORMAL);
 
        return selection->priv->font_size;
 }
@@ -1697,71 +1525,3 @@ e_html_editor_selection_set_underline (EHTMLEditorSelection *selection,
        html_editor_selection_set_format_boolean (
                selection, "DOMSelectionSetUnderline", underline);
 }
-
-static void
-html_editor_selection_modify (EHTMLEditorSelection *selection,
-                              const gchar *alter,
-                              gboolean forward,
-                              EHTMLEditorSelectionGranularity granularity)
-{
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-
-       view = e_html_editor_selection_ref_html_editor_view (selection);
-       g_return_if_fail (view != NULL);
-
-       e_html_editor_view_set_changed (view, TRUE);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               goto out;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "DOMSelectionModify",
-               g_variant_new (
-                       "(tsbi)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       alter,
-                       forward,
-                       granularity),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-
- out:
-       g_object_unref (view);
-}
-
-/**
- * e_html_editor_selection_extend:
- * @selection: an #EHTMLEditorSelection
- * @forward: whether to extend selection forward or backward
- * @granularity: granularity of the extension
- *
- * Extends current selection in given direction by given granularity.
- */
-void
-e_html_editor_selection_extend (EHTMLEditorSelection *selection,
-                                gboolean forward,
-                                EHTMLEditorSelectionGranularity granularity)
-{
-       html_editor_selection_modify (selection, "extend", forward, granularity);
-}
-
-/**
- * e_html_editor_selection_move:
- * @selection: an #EHTMLEditorSelection
- * @forward: whether to move the selection forward or backward
- * @granularity: granularity of the movement
- *
- * Moves current selection in given direction by given granularity
- */
-void
-e_html_editor_selection_move (EHTMLEditorSelection *selection,
-                              gboolean forward,
-                              EHTMLEditorSelectionGranularity granularity)
-{
-       html_editor_selection_modify (selection, "move", forward, granularity);
-}
diff --git a/e-util/e-html-editor-selection.h b/e-util/e-html-editor-selection.h
index 6737a90..9d10ba8 100644
--- a/e-util/e-html-editor-selection.h
+++ b/e-util/e-html-editor-selection.h
@@ -26,7 +26,7 @@
 #define E_HTML_EDITOR_SELECTION_H
 
 #include <gtk/gtk.h>
-#include <e-util/e-util-enums.h>
+#include <e-util/e-content-editor-enums.h>
 
 /* Standard GObject macros */
 #define E_TYPE_HTML_EDITOR_SELECTION \
@@ -77,19 +77,12 @@ void                e_html_editor_selection_unblock_selection_changed
                                                (EHTMLEditorSelection *selection);
 gint           e_html_editor_selection_get_word_wrap_length
                                                (EHTMLEditorSelection *selection);
-gboolean       e_html_editor_selection_has_text
-                                               (EHTMLEditorSelection *selection);
-gchar *                e_html_editor_selection_get_caret_word
-                                               (EHTMLEditorSelection *selection);
-void           e_html_editor_selection_replace_caret_word
-                                               (EHTMLEditorSelection *selection,
-                                                const gchar *replacement);
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
                e_html_editor_selection_get_alignment
                                                (EHTMLEditorSelection *selection);
 void           e_html_editor_selection_set_alignment
                                                (EHTMLEditorSelection *selection,
-                                                EHTMLEditorSelectionAlignment alignment);
+                                                EContentEditorAlignment alignment);
 const gchar *  e_html_editor_selection_get_background_color
                                                (EHTMLEditorSelection *selection);
 void           e_html_editor_selection_set_background_color
@@ -111,12 +104,12 @@ guint             e_html_editor_selection_get_font_size
 void           e_html_editor_selection_set_font_size
                                                (EHTMLEditorSelection *selection,
                                                 guint font_size);
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
                e_html_editor_selection_get_block_format
                                                (EHTMLEditorSelection *selection);
 void           e_html_editor_selection_set_block_format
                                                (EHTMLEditorSelection *selection,
-                                                EHTMLEditorSelectionBlockFormat format);
+                                                EContentEditorBlockFormat format);
 gboolean       e_html_editor_selection_is_citation
                                                (EHTMLEditorSelection *selection);
 gboolean       e_html_editor_selection_is_indented
@@ -166,21 +159,6 @@ gboolean   e_html_editor_selection_is_collapsed
                                                (EHTMLEditorSelection *selection);
 const gchar *  e_html_editor_selection_get_string
                                                (EHTMLEditorSelection *selection);
-void           e_html_editor_selection_replace (EHTMLEditorSelection *selection,
-                                                const gchar *new_string);
-void           e_html_editor_selection_insert_as_text
-                                               (EHTMLEditorSelection *selection,
-                                                const gchar *html_text);
-void           e_html_editor_selection_save    (EHTMLEditorSelection *selection);
-void           e_html_editor_selection_restore (EHTMLEditorSelection *selection);
-void           e_html_editor_selection_move    (EHTMLEditorSelection *selection,
-                                                gboolean forward,
-                                                EHTMLEditorSelectionGranularity granularity);
-void           e_html_editor_selection_extend  (EHTMLEditorSelection *selection,
-                                                gboolean forward,
-                                                EHTMLEditorSelectionGranularity granularity);
-void           e_html_editor_selection_scroll_to_caret
-                                               (EHTMLEditorSelection *selection);
 G_END_DECLS
 
 #endif /* E_HTML_EDITOR_SELECTION_H */
diff --git a/e-util/e-html-editor-spell-check-dialog.c b/e-util/e-html-editor-spell-check-dialog.c
index 5d21b2d..6d22c98 100644
--- a/e-util/e-html-editor-spell-check-dialog.c
+++ b/e-util/e-html-editor-spell-check-dialog.c
@@ -27,7 +27,6 @@
 #include <glib/gi18n-lib.h>
 #include <enchant/enchant.h>
 
-#include "e-html-editor-view.h"
 #include "e-spell-checker.h"
 #include "e-spell-dictionary.h"
 
@@ -50,10 +49,6 @@ struct _EHTMLEditorSpellCheckDialogPrivate {
 
        gchar *word;
        ESpellDictionary *current_dict;
-
-       WebKitFindController *find_controller;
-       gulong found_text_handler_id;
-       gchar *replacement;
 };
 
 enum {
@@ -68,25 +63,11 @@ G_DEFINE_TYPE (
        E_TYPE_HTML_EDITOR_DIALOG)
 
 static void
-webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
-                                      guint match_count,
-                                      EHTMLEditorSpellCheckDialog *dialog)
-{
-       /* Repeatedly search for 'word', then replace selection by
-        * 'replacement'. Repeat until there's at least one occurrence of
-        * 'word' in the document */
-       e_html_editor_view_insert_html (
-               E_HTML_EDITOR_VIEW (webkit_find_controller_get_web_view (find_controller)), 
dialog->priv->replacement);
-
-       webkit_find_controller_search_next (find_controller);
-}
-
-static void
 html_editor_spell_check_dialog_set_word (EHTMLEditorSpellCheckDialog *dialog,
                                          const gchar *word)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkTreeView *tree_view;
        GtkListStore *store;
        gchar *markup;
@@ -143,58 +124,27 @@ html_editor_spell_check_dialog_set_word (EHTMLEditorSpellCheckDialog *dialog,
         * given to WebKit, because this dialog is modal, but it satisfies
         * it in a way that it paints the selection :) */
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       gtk_widget_grab_focus (GTK_WIDGET (view));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
 }
 
 static gboolean
-move_to_another_word (EHTMLEditorSpellCheckDialog *dialog,
-                      const gchar *dom_function)
+html_editor_spell_check_dialog_next (EHTMLEditorSpellCheckDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
-       gchar **active_languages;
+       EContentEditor *cnt_editor;
+       gchar *next_word;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return FALSE;
-
-       active_languages = e_spell_checker_list_active_languages (
-               e_html_editor_view_get_spell_checker (view), NULL);
-       if (!active_languages)
-               return FALSE;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               dom_function,
-               g_variant_new (
-                       "(ts^as)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       dialog->priv->word ? dialog->priv->word : "",
-                       active_languages),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       g_strfreev (active_languages);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               const gchar *next_word;
-
-               g_variant_get (result, "(&s)", &next_word);
-               if (next_word && *next_word) {
-                       html_editor_spell_check_dialog_set_word (dialog, next_word);
-                       g_variant_unref (result);
-                       return TRUE;
-               }
-
-               g_variant_unref (result);
+       next_word = e_content_editor_spell_check_next_word (cnt_editor, dialog->priv->word);
+       if (next_word && *next_word) {
+               html_editor_spell_check_dialog_set_word (dialog, next_word);
+               g_free (next_word);
+               return TRUE;
        }
+       g_free (next_word);
 
        /* Close the dialog */
        gtk_widget_hide (GTK_WIDGET (dialog));
@@ -202,15 +152,26 @@ move_to_another_word (EHTMLEditorSpellCheckDialog *dialog,
 }
 
 static gboolean
-html_editor_spell_check_dialog_next (EHTMLEditorSpellCheckDialog *dialog)
-{
-       return move_to_another_word (dialog, "EHTMLEditorSpellCheckDialogNext");
-}
-
-static gboolean
 html_editor_spell_check_dialog_prev (EHTMLEditorSpellCheckDialog *dialog)
 {
-       return move_to_another_word (dialog, "EHTMLEditorSpellCheckDialogPrev");
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
+       gchar *prev_word;
+
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       prev_word = e_content_editor_spell_check_prev_word (cnt_editor, dialog->priv->word);
+       if (prev_word && *prev_word) {
+               html_editor_spell_check_dialog_set_word (dialog, prev_word);
+               g_free (prev_word);
+               return TRUE;
+       }
+       g_free (prev_word);
+
+       /* Close the dialog */
+       gtk_widget_hide (GTK_WIDGET (dialog));
+       return FALSE;
 }
 
 static gboolean
@@ -230,21 +191,24 @@ static void
 html_editor_spell_check_dialog_replace (EHTMLEditorSpellCheckDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkTreeModel *model;
        GtkTreeSelection *selection;
        GtkTreeIter iter;
        gchar *replacement;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        selection = gtk_tree_view_get_selection (
                GTK_TREE_VIEW (dialog->priv->tree_view));
        gtk_tree_selection_get_selected (selection, &model, &iter);
        gtk_tree_model_get (model, &iter, 0, &replacement, -1);
 
-       e_html_editor_view_insert_html (view, replacement);
+       e_content_editor_insert_content (
+               cnt_editor,
+               replacement,
+               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
 
        g_free (replacement);
 
@@ -255,29 +219,28 @@ static void
 html_editor_spell_check_dialog_replace_all (EHTMLEditorSpellCheckDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
+       EContentEditorFindController *find_controller;
        GtkTreeModel *model;
        GtkTreeSelection *selection;
        GtkTreeIter iter;
-       WebKitFindController *find_controller;
-
-       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       find_controller = webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (view));
+       gchar *replacement;
 
        selection = gtk_tree_view_get_selection (
                GTK_TREE_VIEW (dialog->priv->tree_view));
        gtk_tree_selection_get_selected (selection, &model, &iter);
-       if (dialog->priv->replacement)
-               g_free (dialog->priv->replacement);
-       gtk_tree_model_get (model, &iter, 0, &dialog->priv->replacement, -1);
+       gtk_tree_model_get (model, &iter, 0, &replacement, -1);
 
-       webkit_find_controller_search (
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       find_controller = e_content_editor_get_find_controller (cnt_editor);
+
+       e_content_editor_find_controller_replace_all (
                find_controller,
                dialog->priv->word,
-               WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
-               WEBKIT_FIND_OPTIONS_WRAP_AROUND,
-               G_MAXUINT);
+               replacement,
+               E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE |
+               E_CONTENT_EDITOR_FIND_WRAP_AROUND);
 
        g_idle_add (html_editor_spell_check_dialog_next_idle_cb, g_object_ref (dialog));
 }
@@ -345,9 +308,14 @@ html_editor_spell_check_dialog_show (GtkWidget *widget)
 static void
 html_editor_spell_check_dialog_hide (GtkWidget *widget)
 {
+       EContentEditor *cnt_editor;
+       EHTMLEditor *editor;
        EHTMLEditorSpellCheckDialog *dialog = E_HTML_EDITOR_SPELL_CHECK_DIALOG (widget);
 
-       webkit_find_controller_search_finish (dialog->priv->find_controller);
+       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_on_spell_check_dialog_close (cnt_editor);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_spell_check_dialog_parent_class)->hide (widget);
@@ -361,55 +329,21 @@ html_editor_spell_check_dialog_finalize (GObject *object)
        priv = E_HTML_EDITOR_SPELL_CHECK_DIALOG_GET_PRIVATE (object);
 
        g_free (priv->word);
-       g_free (priv->replacement);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_html_editor_spell_check_dialog_parent_class)->finalize (object);
 }
 
 static void
-html_editor_spell_check_dialog_dispose (GObject *object)
-{
-       EHTMLEditorSpellCheckDialogPrivate *priv;
-
-       priv = E_HTML_EDITOR_SPELL_CHECK_DIALOG_GET_PRIVATE (object);
-
-       if (priv->found_text_handler_id > 0) {
-               g_signal_handler_disconnect (
-                       priv->find_controller,
-                       priv->found_text_handler_id);
-               priv->found_text_handler_id = 0;
-       }
-
-       /* Chain up to parent's dispose() method. */
-       G_OBJECT_CLASS (e_html_editor_spell_check_dialog_parent_class)->dispose (object);
-}
-
-static void
 html_editor_spell_check_dialog_constructed (GObject *object)
 {
        EHTMLEditorSpellCheckDialog *dialog;
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       WebKitFindController *find_controller;
 
        /* Chain up to parent's constructed() method. */
        G_OBJECT_CLASS (e_html_editor_spell_check_dialog_parent_class)->constructed (object);
 
        dialog = E_HTML_EDITOR_SPELL_CHECK_DIALOG (object);
 
-       editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       find_controller = webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (view));
-
-       dialog->priv->found_text_handler_id = g_signal_connect (
-               find_controller, "found-text",
-               G_CALLBACK (webkit_find_controller_found_text_cb), dialog);
-
-       dialog->priv->find_controller = find_controller;
-       dialog->priv->replacement = NULL;
-
        e_html_editor_spell_check_dialog_update_dictionaries (dialog);
 }
 
@@ -425,7 +359,6 @@ e_html_editor_spell_check_dialog_class_init (EHTMLEditorSpellCheckDialogClass *c
        object_class = G_OBJECT_CLASS (class);
        object_class->finalize = html_editor_spell_check_dialog_finalize;
        object_class->constructed = html_editor_spell_check_dialog_constructed;
-       object_class->dispose = html_editor_spell_check_dialog_dispose;
 
        widget_class = GTK_WIDGET_CLASS (class);
        widget_class->show = html_editor_spell_check_dialog_show;
@@ -572,7 +505,7 @@ void
 e_html_editor_spell_check_dialog_update_dictionaries (EHTMLEditorSpellCheckDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
        GtkComboBox *combo_box;
        GtkListStore *store = NULL;
@@ -584,8 +517,8 @@ e_html_editor_spell_check_dialog_update_dictionaries (EHTMLEditorSpellCheckDialo
        g_return_if_fail (E_IS_HTML_EDITOR_SPELL_CHECK_DIALOG (dialog));
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       spell_checker = e_html_editor_view_get_spell_checker (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
 
        languages = e_spell_checker_list_active_languages (
                spell_checker, &n_languages);
diff --git a/e-util/e-html-editor-table-dialog.c b/e-util/e-html-editor-table-dialog.c
index 92e606f..be2505d 100644
--- a/e-util/e-html-editor-table-dialog.c
+++ b/e-util/e-html-editor-table-dialog.c
@@ -49,8 +49,8 @@ struct _EHTMLEditorTableDialogPrivate {
 
        GtkWidget *alignment_combo;
 
-       GtkWidget *background_color_button;
-       GtkWidget *background_image_button;
+       GtkWidget *background_color_picker;
+       GtkWidget *background_image_chooser;
        GtkWidget *image_chooser_dialog;
 
        GtkWidget *remove_image_button;
@@ -67,489 +67,278 @@ static void
 html_editor_table_dialog_set_row_count (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorTableDialogSetRowCount",
-               g_variant_new (
-                       "(tu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_spin_button_get_value (
-                               GTK_SPIN_BUTTON (dialog->priv->rows_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_table_set_row_count (
+               cnt_editor,
+               gtk_spin_button_get_value (
+                       GTK_SPIN_BUTTON (dialog->priv->rows_edit)));
 }
 
 static void
 html_editor_table_dialog_get_row_count (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorTableDialogGetRowCount",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gulong value;
-
-               g_variant_get (result, "(u)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->rows_edit), value);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->rows_edit),
+               e_content_editor_table_get_row_count (cnt_editor));
 }
 
 static void
 html_editor_table_dialog_set_column_count (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "EHTMLEditorTableDialogSetColumnCount",
-               g_variant_new (
-                       "(tu)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       gtk_spin_button_get_value (
-                               GTK_SPIN_BUTTON (dialog->priv->columns_edit))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_table_set_column_count (
+               cnt_editor,
+               gtk_spin_button_get_value (
+                       GTK_SPIN_BUTTON (dialog->priv->columns_edit)));
 }
 
 static void
 html_editor_table_dialog_get_column_count (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorTableDialogGetColumnCount",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gulong value;
-
-               g_variant_get (result, "(u)", &value);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->columns_edit), value);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->columns_edit),
+               e_content_editor_table_get_column_count (cnt_editor));
 }
 
 static void
 html_editor_table_dialog_set_width (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *width;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (gtk_toggle_button_get_active (
                        GTK_TOGGLE_BUTTON (dialog->priv->width_check))) {
-               gchar *units;
 
-               units = gtk_combo_box_text_get_active_text (
-                               GTK_COMBO_BOX_TEXT (dialog->priv->width_units));
-               width = g_strdup_printf (
-                       "%d%s",
+               e_content_editor_table_set_width (
+                       cnt_editor,
                        gtk_spin_button_get_value_as_int (
                                GTK_SPIN_BUTTON (dialog->priv->width_edit)),
-                       units);
-               g_free (units);
+                       (gtk_combo_box_get_active (
+                               GTK_COMBO_BOX (dialog->priv->width_units)) == 0) ?
+                                       E_CONTENT_EDITOR_UNIT_PIXEL :
+                                       E_CONTENT_EDITOR_UNIT_PERCENTAGE);
 
                gtk_widget_set_sensitive (dialog->priv->width_edit, TRUE);
                gtk_widget_set_sensitive (dialog->priv->width_units, TRUE);
        } else {
-               width = g_strdup ("auto");
+               e_content_editor_table_set_width (
+                       cnt_editor, 0, E_CONTENT_EDITOR_UNIT_AUTO);
 
                gtk_widget_set_sensitive (dialog->priv->width_edit, FALSE);
                gtk_widget_set_sensitive (dialog->priv->width_units, FALSE);
        }
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "width", width);
-
-       g_free (width);
 }
 
 static void
 html_editor_table_dialog_get_width (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
-       const gchar *width;
+       EContentEditor *cnt_editor;
+       EContentEditorUnit unit;
+       gint width;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "width");
-
-       if (!result)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       g_variant_get (result, "(&s)", &width);
-
-       if (!width || !*width || g_ascii_strncasecmp (width, "auto", 4) == 0) {
-               gtk_toggle_button_set_active (
-                       GTK_TOGGLE_BUTTON (dialog->priv->width_check), FALSE);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->width_edit), 100);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->width_units), "units-percent");
-       } else {
-               gint width_int = atoi (width);
-
-               gtk_toggle_button_set_active (
-                       GTK_TOGGLE_BUTTON (dialog->priv->width_check), TRUE);
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->width_edit), width_int);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->width_units),
-                       ((strstr (width, "%") == NULL) ?
-                               "units-px" : "units-percent"));
-       }
+       width = e_content_editor_table_get_width (cnt_editor, &unit);
 
-       g_variant_unref (result);
+       gtk_toggle_button_set_active (
+               GTK_TOGGLE_BUTTON (dialog->priv->width_check),
+               unit != E_CONTENT_EDITOR_UNIT_AUTO);
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->width_edit),
+               unit == E_CONTENT_EDITOR_UNIT_AUTO ? 100 : width);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->width_units),
+               unit == E_CONTENT_EDITOR_UNIT_PIXEL ? "units-px" : "units-percent");
 }
 
 static void
 html_editor_table_dialog_set_alignment (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       const gchar *value;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       value = gtk_combo_box_get_active_id (
-               GTK_COMBO_BOX (dialog->priv->alignment_combo));
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "alignment", value);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
+       e_content_editor_table_set_align (
+               cnt_editor,
+               gtk_combo_box_get_active_id (
+                       GTK_COMBO_BOX (dialog->priv->alignment_combo)));
 }
 
 static void
 html_editor_table_dialog_get_alignment (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gchar *value;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "align");
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               gtk_combo_box_set_active_id (
-                       GTK_COMBO_BOX (dialog->priv->alignment_combo), value);
-               g_variant_unref (result);
-       }
+       value = e_content_editor_table_get_align (cnt_editor);
+       gtk_combo_box_set_active_id (
+               GTK_COMBO_BOX (dialog->priv->alignment_combo), value);
+       g_free (value);
 }
 
 static void
 html_editor_table_dialog_set_padding (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *padding;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       padding = g_strdup_printf (
-               "%d",
+       e_content_editor_table_set_padding (
+               cnt_editor,
                gtk_spin_button_get_value_as_int (
                        GTK_SPIN_BUTTON (dialog->priv->padding_edit)));
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "cellpadding", padding);
-
-       g_free (padding);
 }
 
 static void
 html_editor_table_dialog_get_padding (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "cellpadding");
-
-       if (result) {
-               const gchar *value;
-               gint value_int;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value)
-                       value_int = atoi (value);
-               else
-                       value_int = 0;
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->padding_edit), value_int);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->padding_edit),
+               e_content_editor_table_get_padding (cnt_editor));
 }
 
 static void
 html_editor_table_dialog_set_spacing (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *spacing;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       spacing = g_strdup_printf (
-               "%d",
+       e_content_editor_table_set_spacing (
+               cnt_editor,
                gtk_spin_button_get_value_as_int (
                        GTK_SPIN_BUTTON (dialog->priv->spacing_edit)));
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "cellspacing", spacing);
-
-       g_free (spacing);
 }
 
 static void
 html_editor_table_dialog_get_spacing (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "cellspacing");
-
-       if (result) {
-               const gchar *value;
-               gint value_int;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value)
-                       value_int = atoi (value);
-               else
-                       value_int = 0;
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->spacing_edit), value_int);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->spacing_edit),
+               e_content_editor_table_get_spacing (cnt_editor));
 }
 
 static void
 html_editor_table_dialog_set_border (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *border;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       border = g_strdup_printf (
-               "%d",
+       e_content_editor_table_set_border (
+               cnt_editor,
                gtk_spin_button_get_value_as_int (
                        GTK_SPIN_BUTTON (dialog->priv->border_edit)));
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "border", border);
-
-       g_free (border);
 }
 
 static void
 html_editor_table_dialog_get_border (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "border");
-
-       if (result) {
-               const gchar *value;
-               gint value_int;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value)
-                       value_int = atoi (value);
-               else
-                       value_int = 0;
-               gtk_spin_button_set_value (
-                       GTK_SPIN_BUTTON (dialog->priv->border_edit), value_int);
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       gtk_spin_button_set_value (
+               GTK_SPIN_BUTTON (dialog->priv->border_edit),
+               e_content_editor_table_get_border (cnt_editor));
 }
 
 static void
 html_editor_table_dialog_set_background_color (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       gchar *color;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
-               E_COLOR_COMBO (dialog->priv->background_color_button), &rgba);
-       if (rgba.alpha != 0.0)
-               color = g_strdup_printf ("#%06x", e_rgba_to_value (&rgba));
-       else
-               color = g_strdup ("");
-
-       e_html_editor_view_set_element_attribute (
-               view, "#-x-evo-current-table", "bgcolor", color);
-
-       g_free (color);
+               E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
+       e_content_editor_table_set_background_color (cnt_editor, &rgba);
 }
 
 static void
 html_editor_table_dialog_get_background_color (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       GdkRGBA rgba;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-
-       result = e_html_editor_view_get_element_attribute (
-               view, "#-x-evo-current-table", "bgcolor");
-
-       if (result) {
-               const gchar *value;
-
-               g_variant_get (result, "(&s)", &value);
-               if (value && *value) {
-                       GdkRGBA rgba;
-
-                       if (gdk_rgba_parse (&rgba, value))
-                               e_color_combo_set_current_color (
-                                       E_COLOR_COMBO (dialog->priv->background_color_button),
-                                       &rgba);
-                       else
-                               e_color_combo_set_current_color (
-                                       E_COLOR_COMBO (dialog->priv->background_color_button),
-                                       &transparent);
-               } else
-                       e_color_combo_set_current_color (
-                               E_COLOR_COMBO (dialog->priv->background_color_button),
-                               &transparent);
-
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_table_get_background_color (cnt_editor, &rgba);
+       e_color_combo_set_current_color (
+               E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
 }
 
 static void
 html_editor_table_dialog_set_background_image (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
        gchar *uri;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        uri = gtk_file_chooser_get_uri (
-               GTK_FILE_CHOOSER (dialog->priv->background_image_button));
+               GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
 
-       if (uri && *uri)
-               e_html_editor_view_replace_image_src (view, "#-x-evo-current-table", uri);
-       else
-               g_dbus_proxy_call (
-                       web_extension,
-                       "RemoveImageAttributesFromElementBySelector",
-                       g_variant_new (
-                               "(ts)",
-                               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                               "#-x-evo-current-table"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
+       e_content_editor_table_set_background_image_uri (cnt_editor, uri);
 
        gtk_widget_set_sensitive (dialog->priv->remove_image_button, uri && *uri);
 
@@ -560,57 +349,21 @@ static void
 html_editor_table_dialog_get_background_image (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
+       gchar *uri;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "ElementHasAttribute",
-               g_variant_new (
-                       "(tss)",
-                       webkit_web_view_get_page_id (
-                               WEBKIT_WEB_VIEW (view)),
-                       "-x-evo-current-table",
-                       "background"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean has_background;
-
-               g_variant_get (result, "(b)", &has_background);
-               if (has_background) {
-                       g_variant_unref (result);
-
-                       result = e_html_editor_view_get_element_attribute (
-                               view, "#-x-evo-current-table", "data-uri");
-
-                       if (result) {
-                               const gchar *value;
-
-                               g_variant_get (result, "(&s)", &value);
-
-                               gtk_file_chooser_set_uri (
-                                       GTK_FILE_CHOOSER (dialog->priv->background_image_button),
-                                       value);
-
-                               g_variant_unref (result);
-                       }
-               } else {
-                       gtk_file_chooser_unselect_all (
-                               GTK_FILE_CHOOSER (dialog->priv->background_image_button));
-                       g_variant_unref (result);
-               }
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       uri = e_content_editor_table_get_background_image_uri (cnt_editor);
+       if (uri && *uri)
+               gtk_file_chooser_set_uri (
+                       GTK_FILE_CHOOSER (dialog->priv->background_image_chooser), uri);
+       else
+               gtk_file_chooser_unselect_all (
+                       GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
+
+       g_free (uri);
 }
 
 static void
@@ -652,10 +405,10 @@ html_editor_table_dialog_reset_values (EHTMLEditorTableDialog *dialog)
                GTK_SPIN_BUTTON (dialog->priv->border_edit), 1);
 
        e_color_combo_set_current_color (
-               E_COLOR_COMBO (dialog->priv->background_color_button), &transparent);
+               E_COLOR_COMBO (dialog->priv->background_color_picker), &transparent);
 
        gtk_file_chooser_unselect_all (
-               GTK_FILE_CHOOSER (dialog->priv->background_image_button));
+               GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
 
        html_editor_table_dialog_set_row_count (dialog);
        html_editor_table_dialog_set_column_count (dialog);
@@ -673,39 +426,16 @@ html_editor_table_dialog_show (GtkWidget *widget)
 {
        EHTMLEditorTableDialog *dialog;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
-       GVariant *result;
+       EContentEditor *cnt_editor;
 
        dialog = E_HTML_EDITOR_TABLE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "EHTMLEditorTableDialogShow",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               gboolean created;
-
-               g_variant_get (result, "(b)", &created);
-               if (created)
-                       html_editor_table_dialog_reset_values (dialog);
-               else
-                       html_editor_table_dialog_get_values (dialog);
-
-               g_variant_unref (result);
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       if (e_content_editor_on_table_dialog_open (cnt_editor))
+               html_editor_table_dialog_reset_values (dialog);
+       else
+               html_editor_table_dialog_get_values (dialog);
 
        /* Chain up to parent implementation */
        GTK_WIDGET_CLASS (e_html_editor_table_dialog_parent_class)->show (widget);
@@ -715,30 +445,15 @@ static void
 html_editor_table_dialog_remove_image (EHTMLEditorTableDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "RemoveImageAttributesFromElementBySelector",
-               g_variant_new (
-                       "(ts)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       "#-x-evo-current-table"),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       e_content_editor_table_set_background_image_uri (cnt_editor, NULL);
 
        gtk_file_chooser_unselect_all (
-               GTK_FILE_CHOOSER (dialog->priv->background_image_button));
+               GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
 
        gtk_widget_set_sensitive (dialog->priv->remove_image_button, FALSE);
 }
@@ -748,14 +463,13 @@ html_editor_table_dialog_hide (GtkWidget *widget)
 {
        EHTMLEditorTableDialog *dialog;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        dialog = E_HTML_EDITOR_TABLE_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_call_simple_extension_function (
-               view, "EHTMLEditorTableDialogSaveHistoryOnExit");
+       e_content_editor_on_table_dialog_close (cnt_editor);
 
        GTK_WIDGET_CLASS (e_html_editor_table_dialog_parent_class)->hide (widget);
 }
@@ -955,12 +669,12 @@ e_html_editor_table_dialog_init (EHTMLEditorTableDialog *dialog)
        g_signal_connect_swapped (
                widget, "notify::current-color",
                G_CALLBACK (html_editor_table_dialog_set_background_color), dialog);
-       dialog->priv->background_color_button = widget;
+       dialog->priv->background_color_picker = widget;
 
        widget = gtk_label_new_with_mnemonic (_("_Color:"));
        gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
        gtk_label_set_mnemonic_widget (
-               GTK_LABEL (widget), dialog->priv->background_color_button);
+               GTK_LABEL (widget), dialog->priv->background_color_picker);
        gtk_grid_attach (grid, widget, 0, 0, 1, 1);
 
        /* Image */
@@ -981,12 +695,12 @@ e_html_editor_table_dialog_init (EHTMLEditorTableDialog *dialog)
        g_signal_connect_swapped (
                widget, "file-set",
                G_CALLBACK (html_editor_table_dialog_set_background_image), dialog);
-       dialog->priv->background_image_button = widget;
+       dialog->priv->background_image_chooser = widget;
 
        widget =gtk_label_new_with_mnemonic (_("Image:"));
        gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
        gtk_label_set_mnemonic_widget (
-               GTK_LABEL (widget), dialog->priv->background_image_button);
+               GTK_LABEL (widget), dialog->priv->background_image_chooser);
        gtk_grid_attach (grid, widget, 0, 1, 1, 1);
 
        box = e_html_editor_dialog_get_button_box (E_HTML_EDITOR_DIALOG (dialog));
diff --git a/e-util/e-html-editor-text-dialog.c b/e-util/e-html-editor-text-dialog.c
index 9edb8e5..b859d6a 100644
--- a/e-util/e-html-editor-text-dialog.c
+++ b/e-util/e-html-editor-text-dialog.c
@@ -51,15 +51,13 @@ static void
 html_editor_text_dialog_set_bold (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_selection_set_bold (
-               selection,
+       e_content_editor_set_bold (
+               cnt_editor,
                gtk_toggle_button_get_active (
                        GTK_TOGGLE_BUTTON (dialog->priv->bold_check)));
 }
@@ -68,15 +66,13 @@ static void
 html_editor_text_dialog_set_italic (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_selection_set_italic (
-               selection,
+       e_content_editor_set_italic (
+               cnt_editor,
                gtk_toggle_button_get_active (
                        GTK_TOGGLE_BUTTON (dialog->priv->italic_check)));
 }
@@ -85,15 +81,13 @@ static void
 html_editor_text_dialog_set_underline (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_selection_set_underline (
-               selection,
+       e_content_editor_set_underline (
+               cnt_editor,
                gtk_toggle_button_get_active (
                        GTK_TOGGLE_BUTTON (dialog->priv->underline_check)));
 }
@@ -102,15 +96,13 @@ static void
 html_editor_text_dialog_set_strikethrough (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_selection_set_strikethrough (
-               selection,
+       e_content_editor_set_strikethrough (
+               cnt_editor,
                gtk_toggle_button_get_active (
                        GTK_TOGGLE_BUTTON (dialog->priv->strikethrough_check)));
 }
@@ -119,33 +111,29 @@ static void
 html_editor_text_dialog_set_color (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
        GdkRGBA rgba;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_color_combo_get_current_color (
                E_COLOR_COMBO (dialog->priv->color_check), &rgba);
-       e_html_editor_selection_set_font_color (selection, &rgba);
+       e_content_editor_set_font_color (cnt_editor, &rgba);
 }
 
 static void
 html_editor_text_dialog_set_size (EHTMLEditorTextDialog *dialog)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
        gint size;
 
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
        size = gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->priv->size_check));
 
-       e_html_editor_selection_set_font_size (selection, size + 1);
+       e_content_editor_set_font_size (cnt_editor, size + 1);
 }
 
 static void
@@ -153,35 +141,33 @@ html_editor_text_dialog_show (GtkWidget *widget)
 {
        EHTMLEditorTextDialog *dialog;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
-       GdkRGBA rgba;
+       EContentEditor *cnt_editor;
+       const GdkRGBA *rgba;
 
        dialog = E_HTML_EDITOR_TEXT_DIALOG (widget);
        editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        gtk_toggle_button_set_active (
                GTK_TOGGLE_BUTTON (dialog->priv->bold_check),
-               e_html_editor_selection_is_bold (selection));
+               e_content_editor_is_bold (cnt_editor));
        gtk_toggle_button_set_active (
                GTK_TOGGLE_BUTTON (dialog->priv->italic_check),
-               e_html_editor_selection_is_italic (selection));
+               e_content_editor_is_italic (cnt_editor));
        gtk_toggle_button_set_active (
                GTK_TOGGLE_BUTTON (dialog->priv->underline_check),
-               e_html_editor_selection_is_underline (selection));
+               e_content_editor_is_underline (cnt_editor));
        gtk_toggle_button_set_active (
                GTK_TOGGLE_BUTTON (dialog->priv->strikethrough_check),
-               e_html_editor_selection_is_strikethrough (selection));
+               e_content_editor_is_strikethrough (cnt_editor));
 
        gtk_combo_box_set_active (
                GTK_COMBO_BOX (dialog->priv->size_check),
-               e_html_editor_selection_get_font_size (selection) - 1);
+               e_content_editor_get_font_size (cnt_editor) - 1);
 
-       e_html_editor_selection_get_font_color (selection, &rgba);
+       rgba = e_content_editor_get_font_color (cnt_editor);
        e_color_combo_set_current_color (
-               E_COLOR_COMBO (dialog->priv->color_check), &rgba);
+               E_COLOR_COMBO (dialog->priv->color_check), rgba);
 
        GTK_WIDGET_CLASS (e_html_editor_text_dialog_parent_class)->show (widget);
 }
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 191d148..e084bcf 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -225,20 +225,6 @@ e_html_editor_view_redo (EHTMLEditorView *view)
 
 
 static void
-html_editor_view_move_selection_on_point (GtkWidget *widget)
-{
-       gint x, y;
-       GdkDeviceManager *device_manager;
-       GdkDevice *pointer;
-
-       device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
-       pointer = gdk_device_manager_get_client_pointer (device_manager);
-       gdk_window_get_device_position (gtk_widget_get_window (widget), pointer, &x, &y, NULL);
-
-       e_html_editor_view_move_selection_on_point (E_HTML_EDITOR_VIEW (widget), x, y, TRUE);
-}
-
-static void
 set_web_extension_boolean_property (EHTMLEditorView *view,
                                     const gchar *property_name,
                                     gboolean value)
@@ -409,44 +395,6 @@ insert_and_convert_html_into_selection (EHTMLEditorView *view,
 }
 
 static void
-clipboard_text_received_for_paste_as_text (GtkClipboard *clipboard,
-                                           const gchar *text,
-                                           EHTMLEditorView *view)
-{
-       insert_and_convert_html_into_selection (view, text, TRUE);
-}
-
-static void
-clipboard_text_received (GtkClipboard *clipboard,
-                         const gchar *text,
-                         EHTMLEditorView *view)
-{
-       GDBusProxy *web_extension;
-
-       g_return_if_fail (view != NULL);
-
-       if (!text || !*text)
-               return;
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "DOMQuoteAndInsertTextIntoSelection",
-               g_variant_new (
-                       "(tsb)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       text),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-}
-
-static void
 html_editor_view_set_property (GObject *object,
                                guint property_id,
                                const GValue *value,
@@ -695,143 +643,6 @@ html_editor_view_constructed (GObject *object)
        webkit_web_view_load_html (WEBKIT_WEB_VIEW (object), "", "file://");
 }
 
-void
-e_html_editor_view_move_selection_on_point (EHTMLEditorView *view,
-                                            gint x,
-                                            gint y,
-                                            gboolean cancel_if_not_collapsed)
-{
-       GDBusProxy *web_extension;
-
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
-       g_return_if_fail (x >= 0);
-       g_return_if_fail (y >= 0);
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMMoveSelectionOnPoint",
-               g_variant_new (
-                       "(tiib)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       x,
-                       y,
-                       cancel_if_not_collapsed),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-}
-
-static gboolean
-html_editor_view_button_press_event (GtkWidget *widget,
-                                     GdkEventButton *event)
-{
-       EHTMLEditorView *view;
-       gboolean event_handled;
-
-       view = E_HTML_EDITOR_VIEW (widget);
-
-       if (event->button == 2) {
-               /* Middle click paste */
-               html_editor_view_move_selection_on_point (widget);
-               /* Remember, that we are pasting primary clipboard to return
-                * correct value in e_html_editor_view_is_pasting_content_from_itself. */
-               view->priv->pasting_primary_clipboard = TRUE;
-               html_editor_update_pasting_content_from_itself (view);
-               g_signal_emit (widget, signals[PASTE_PRIMARY_CLIPBOARD], 0);
-               event_handled = TRUE;
-       } else if (event->button == 3) {
-               html_editor_view_move_selection_on_point (widget);
-               g_signal_emit (
-                       widget, signals[POPUP_EVENT],
-                       0, event, &event_handled);
-       } else {
-               event_handled = FALSE;
-       }
-
-       if (event_handled)
-               return TRUE;
-
-       /* Chain up to parent's button_press_event() method. */
-       return GTK_WIDGET_CLASS (e_html_editor_view_parent_class)->
-               button_press_event (widget, event);
-}
-
-static void
-editor_view_mouse_target_changed_cb (EHTMLEditorView *view,
-                                     WebKitHitTestResult *hit_test_result,
-                                     guint modifiers,
-                                     gpointer user_data)
-{
-       /* Ctrl + Left Click on link opens it. */
-       if (webkit_hit_test_result_context_is_link (hit_test_result) &&
-           (modifiers & GDK_CONTROL_MASK)) {
-               GdkScreen *screen;
-               const gchar *uri;
-               GtkWidget *toplevel;
-
-               toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
-               screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
-
-               uri = webkit_hit_test_result_get_link_uri (hit_test_result);
-
-               gtk_show_uri (screen, uri, GDK_CURRENT_TIME, NULL);
-       }
-}
-
-static gboolean
-html_editor_view_key_press_event (GtkWidget *widget,
-                                  GdkEventKey *event)
-{
-       if (event->keyval == GDK_KEY_Menu) {
-               gboolean event_handled;
-
-               html_editor_view_move_selection_on_point (widget);
-               g_signal_emit (
-                       widget, signals[POPUP_EVENT],
-                       0, event, &event_handled);
-
-               return event_handled;
-       }
-
-       /* Chain up to parent's key_press_event() method. */
-       return GTK_WIDGET_CLASS (e_html_editor_view_parent_class)->key_press_event (widget, event);
-}
-
-static void
-html_editor_view_paste_as_text (EHTMLEditorView *view)
-{
-       GtkClipboard *clipboard;
-
-       clipboard = gtk_clipboard_get_for_display (
-               gdk_display_get_default (),
-               GDK_SELECTION_CLIPBOARD);
-
-       gtk_clipboard_request_text (
-               clipboard,
-               (GtkClipboardTextReceivedFunc) clipboard_text_received_for_paste_as_text,
-               view);
-}
-
-static void
-html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
-{
-       GtkClipboard *clipboard;
-
-       clipboard = gtk_clipboard_get_for_display (
-               gdk_display_get_default (),
-               GDK_SELECTION_CLIPBOARD);
-
-       gtk_clipboard_request_text (
-               clipboard,
-               (GtkClipboardTextReceivedFunc) clipboard_text_received,
-               view);
-}
-
 static void
 web_extension_proxy_created_cb (GDBusProxy *proxy,
                                 GAsyncResult *result,
@@ -851,7 +662,6 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
 
        set_web_extension_boolean_property (view, "MagicSmileys", view->priv->magic_smileys);
        set_web_extension_boolean_property (view, "MagicLinks", view->priv->magic_links);
-       set_web_extension_boolean_property (view, "InlineSpelling", view->priv->inline_spelling);
 
        if (view->priv->inline_spelling)
                e_html_editor_view_force_spell_check (view);
@@ -1081,7 +891,6 @@ static void
 e_html_editor_view_class_init (EHTMLEditorViewClass *class)
 {
        GObjectClass *object_class;
-       GtkWidgetClass *widget_class;
 
        g_type_class_add_private (class, sizeof (EHTMLEditorViewPrivate));
 
@@ -1093,11 +902,6 @@ e_html_editor_view_class_init (EHTMLEditorViewClass *class)
        object_class->finalize = html_editor_view_finalize;
        object_class->constructed = html_editor_view_constructed;
 
-       widget_class = GTK_WIDGET_CLASS (class);
-       widget_class->button_press_event = html_editor_view_button_press_event;
-       widget_class->key_press_event = html_editor_view_key_press_event;
-
-       class->paste_clipboard_quoted = html_editor_view_paste_clipboard_quoted;
 
        /**
         * EHTMLEditorView:can-copy
@@ -1550,7 +1354,6 @@ html_editor_view_load_changed_cb (EHTMLEditorView *view,
        }
 
        view->priv->reload_in_progress = FALSE;
-
 }
 
 /**
@@ -1690,9 +1493,6 @@ e_html_editor_view_init (EHTMLEditorView *view)
        g_signal_connect (
                view, "load-changed",
                G_CALLBACK (html_editor_view_load_changed_cb), NULL);
-       g_signal_connect (
-               view, "mouse-target-changed",
-               G_CALLBACK (editor_view_mouse_target_changed_cb), NULL);
 
        view->priv->selection = g_object_new (
                E_TYPE_HTML_EDITOR_SELECTION,
@@ -1854,8 +1654,8 @@ e_html_editor_view_set_magic_links (EHTMLEditorView *view,
 }
 
 void
-e_html_editor_view_insert_smiley (EHTMLEditorView *view,
-                                  EEmoticon *emoticon)
+e_html_editor_view_insert_emoticon (EHTMLEditorView *view,
+                                    EEmoticon *emoticon)
 {
        GDBusProxy *web_extension;
 
@@ -2404,39 +2204,6 @@ e_html_editor_view_set_text_plain (EHTMLEditorView *view,
                NULL);
 }
 
-/**
- * e_html_editor_view_paste_as_text:
- * @view: an #EHTMLEditorView
- *
- * Pastes current content of clipboard into the editor without formatting
- */
-void
-e_html_editor_view_paste_as_text (EHTMLEditorView *view)
-{
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
-
-       html_editor_view_paste_as_text (view);
-}
-
-/**
- * e_html_editor_view_paste_clipboard_quoted:
- * @view: an #EHTMLEditorView
- *
- * Pastes current content of clipboard into the editor as quoted text
- */
-void
-e_html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
-{
-       EHTMLEditorViewClass *class;
-
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
-
-       class = E_HTML_EDITOR_VIEW_GET_CLASS (view);
-       g_return_if_fail (class->paste_clipboard_quoted != NULL);
-
-       class->paste_clipboard_quoted (view);
-}
-
 void
 e_html_editor_view_embed_styles (EHTMLEditorView *view)
 {
@@ -3038,320 +2805,6 @@ e_html_editor_view_set_is_editting_message (EHTMLEditorView *view,
        view->priv->is_editting_message = value;
 }
 
-void
-e_html_editor_view_scroll_to_caret (EHTMLEditorView *view)
-{
-       e_html_editor_view_call_simple_extension_function (view, "DOMScrollToCaret");
-}
-
-/************************* image_load_and_insert_async() *************************/
-
-typedef struct _LoadContext LoadContext;
-
-struct _LoadContext {
-       EHTMLEditorView *view;
-       GInputStream *input_stream;
-       GOutputStream *output_stream;
-       GFile *file;
-       GFileInfo *file_info;
-       goffset total_num_bytes;
-       gssize bytes_read;
-       const gchar *content_type;
-       const gchar *filename;
-       const gchar *selector;
-       gchar buffer[4096];
-};
-
-/* Forward Declaration */
-static void
-image_load_stream_read_cb (GInputStream *input_stream,
-                           GAsyncResult *result,
-                           LoadContext *load_context);
-
-static LoadContext *
-image_load_context_new (EHTMLEditorView *view)
-{
-       LoadContext *load_context;
-
-       load_context = g_slice_new0 (LoadContext);
-       load_context->view = view;
-
-       return load_context;
-}
-
-static void
-image_load_context_free (LoadContext *load_context)
-{
-       if (load_context->input_stream != NULL)
-               g_object_unref (load_context->input_stream);
-
-       if (load_context->output_stream != NULL)
-               g_object_unref (load_context->output_stream);
-
-       if (load_context->file_info != NULL)
-               g_object_unref (load_context->file_info);
-
-       if (load_context->file != NULL)
-               g_object_unref (load_context->file);
-
-       g_slice_free (LoadContext, load_context);
-}
-
-static void
-replace_base64_image_src (EHTMLEditorView *view,
-                          const gchar *selector,
-                          const gchar *base64_content,
-                          const gchar *filename,
-                          const gchar *uri)
-{
-       GDBusProxy *web_extension;
-
-       e_html_editor_view_set_changed (view, TRUE);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "DOMReplaceBase64ImageSrc",
-               g_variant_new (
-                       "(tssss)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       selector,
-                       base64_content,
-                       filename,
-                       uri),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-}
-
-static void
-insert_base64_image (EHTMLEditorView *view,
-                     const gchar *base64_content,
-                     const gchar *filename,
-                     const gchar *uri)
-{
-       GDBusProxy *web_extension;
-
-       e_html_editor_view_set_changed (view, TRUE);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       g_dbus_proxy_call (
-               web_extension,
-               "DOMSelectionInsertBase64Image",
-               g_variant_new (
-                       "(tsss)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
-                       base64_content,
-                       filename,
-                       uri),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL,
-               NULL);
-}
-
-static void
-image_load_finish (LoadContext *load_context)
-{
-       EHTMLEditorView *view;
-       GMemoryOutputStream *output_stream;
-       const gchar *selector;
-       gchar *base64_encoded, *mime_type, *output, *uri;
-       gsize size;
-       gpointer data;
-
-       output_stream = G_MEMORY_OUTPUT_STREAM (load_context->output_stream);
-
-       view = load_context->view;
-
-       mime_type = g_content_type_get_mime_type (load_context->content_type);
-
-       data = g_memory_output_stream_get_data (output_stream);
-       size = g_memory_output_stream_get_data_size (output_stream);
-       uri = g_file_get_uri (load_context->file);
-
-       base64_encoded = g_base64_encode ((const guchar *) data, size);
-       output = g_strconcat ("data:", mime_type, ";base64,", base64_encoded, NULL);
-       selector = load_context->selector;
-       if (selector && *selector)
-               replace_base64_image_src (
-                       view, selector, output, load_context->filename, uri);
-       else
-               insert_base64_image (view, output, load_context->filename, uri);
-
-       g_free (base64_encoded);
-       g_free (output);
-       g_free (mime_type);
-       g_free (uri);
-
-       image_load_context_free (load_context);
-}
-
-static void
-image_load_write_cb (GOutputStream *output_stream,
-                     GAsyncResult *result,
-                     LoadContext *load_context)
-{
-       GInputStream *input_stream;
-       gssize bytes_written;
-       GError *error = NULL;
-
-       bytes_written = g_output_stream_write_finish (
-               output_stream, result, &error);
-
-       if (error) {
-               image_load_context_free (load_context);
-               return;
-       }
-
-       input_stream = load_context->input_stream;
-
-       if (bytes_written < load_context->bytes_read) {
-               g_memmove (
-                       load_context->buffer,
-                       load_context->buffer + bytes_written,
-                       load_context->bytes_read - bytes_written);
-               load_context->bytes_read -= bytes_written;
-
-               g_output_stream_write_async (
-                       output_stream,
-                       load_context->buffer,
-                       load_context->bytes_read,
-                       G_PRIORITY_DEFAULT, NULL,
-                       (GAsyncReadyCallback) image_load_write_cb,
-                       load_context);
-       } else
-               g_input_stream_read_async (
-                       input_stream,
-                       load_context->buffer,
-                       sizeof (load_context->buffer),
-                       G_PRIORITY_DEFAULT, NULL,
-                       (GAsyncReadyCallback) image_load_stream_read_cb,
-                       load_context);
-}
-
-static void
-image_load_stream_read_cb (GInputStream *input_stream,
-                           GAsyncResult *result,
-                           LoadContext *load_context)
-{
-       GOutputStream *output_stream;
-       gssize bytes_read;
-       GError *error = NULL;
-
-       bytes_read = g_input_stream_read_finish (
-               input_stream, result, &error);
-
-       if (error) {
-               image_load_context_free (load_context);
-               return;
-       }
-
-       if (bytes_read == 0) {
-               image_load_finish (load_context);
-               return;
-       }
-
-       output_stream = load_context->output_stream;
-       load_context->bytes_read = bytes_read;
-
-       g_output_stream_write_async (
-               output_stream,
-               load_context->buffer,
-               load_context->bytes_read,
-               G_PRIORITY_DEFAULT, NULL,
-               (GAsyncReadyCallback) image_load_write_cb,
-               load_context);
-}
-
-static void
-image_load_file_read_cb (GFile *file,
-                         GAsyncResult *result,
-                         LoadContext *load_context)
-{
-       GFileInputStream *input_stream;
-       GOutputStream *output_stream;
-       GError *error = NULL;
-
-       /* Input stream might be NULL, so don't use cast macro. */
-       input_stream = g_file_read_finish (file, result, &error);
-       load_context->input_stream = (GInputStream *) input_stream;
-
-       if (error) {
-               image_load_context_free (load_context);
-               return;
-       }
-
-       /* Load the contents into a GMemoryOutputStream. */
-       output_stream = g_memory_output_stream_new (
-               NULL, 0, g_realloc, g_free);
-
-       load_context->output_stream = output_stream;
-
-       g_input_stream_read_async (
-               load_context->input_stream,
-               load_context->buffer,
-               sizeof (load_context->buffer),
-               G_PRIORITY_DEFAULT, NULL,
-               (GAsyncReadyCallback) image_load_stream_read_cb,
-               load_context);
-}
-
-static void
-image_load_query_info_cb (GFile *file,
-                          GAsyncResult *result,
-                          LoadContext *load_context)
-{
-       GFileInfo *file_info;
-       GError *error = NULL;
-
-       file_info = g_file_query_info_finish (file, result, &error);
-       if (error) {
-               image_load_context_free (load_context);
-               return;
-       }
-
-       load_context->content_type = g_file_info_get_content_type (file_info);
-       load_context->total_num_bytes = g_file_info_get_size (file_info);
-       load_context->filename = g_file_info_get_name (file_info);
-
-       g_file_read_async (
-               file, G_PRIORITY_DEFAULT,
-               NULL, (GAsyncReadyCallback)
-               image_load_file_read_cb, load_context);
-}
-
-static void
-image_load_and_insert_async (EHTMLEditorView *view,
-                             const gchar *selector,
-                             const gchar *uri)
-{
-       LoadContext *load_context;
-       GFile *file;
-
-       g_return_if_fail (uri && *uri);
-
-       file = g_file_new_for_uri (uri);
-       g_return_if_fail (file != NULL);
-
-       load_context = image_load_context_new (view);
-       load_context->file = file;
-       if (selector && *selector)
-               load_context->selector = g_strdup (selector);
-
-       g_file_query_info_async (
-               file, "standard::*",
-               G_FILE_QUERY_INFO_NONE,G_PRIORITY_DEFAULT,
-               NULL, (GAsyncReadyCallback)
-               image_load_query_info_cb, load_context);
-}
 
 /**
  * e_html_editor_selection_insert_image:
@@ -3365,29 +2818,6 @@ void
 e_html_editor_view_insert_image (EHTMLEditorView *view,
                                  const gchar *image_uri)
 {
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
-       g_return_if_fail (image_uri != NULL);
-
-       if (e_html_editor_view_get_html_mode (view)) {
-               if (strstr (image_uri, ";base64,")) {
-                       if (g_str_has_prefix (image_uri, "data:"))
-                               insert_base64_image (view, image_uri, "", "");
-                       if (strstr (image_uri, ";data")) {
-                               const gchar *base64_data = strstr (image_uri, ";") + 1;
-                               gchar *filename;
-                               glong filename_length;
-
-                               filename_length =
-                                       g_utf8_strlen (image_uri, -1) -
-                                       g_utf8_strlen (base64_data, -1) - 1;
-                               filename = g_strndup (image_uri, filename_length);
-
-                               insert_base64_image (view, base64_data, filename, "");
-                               g_free (filename);
-                       }
-               } else
-                       image_load_and_insert_async (view, NULL, image_uri);
-       }
 }
 
 /**
@@ -3405,36 +2835,6 @@ e_html_editor_view_replace_image_src (EHTMLEditorView *view,
                                       const gchar *selector,
                                       const gchar *image_uri)
 {
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
-       g_return_if_fail (image_uri != NULL);
-       g_return_if_fail (selector && *selector);
-
-       if (strstr (image_uri, ";base64,")) {
-               if (g_str_has_prefix (image_uri, "data:"))
-                       replace_base64_image_src (
-                               view, selector, image_uri, "", "");
-               if (strstr (image_uri, ";data")) {
-                       const gchar *base64_data = strstr (image_uri, ";") + 1;
-                       gchar *filename;
-                       glong filename_length;
-
-                       filename_length =
-                               g_utf8_strlen (image_uri, -1) -
-                               g_utf8_strlen (base64_data, -1) - 1;
-                       filename = g_strndup (image_uri, filename_length);
-
-                       replace_base64_image_src (
-                               view, selector, base64_data, filename, "");
-                       g_free (filename);
-               }
-       } else
-               image_load_and_insert_async (view, selector, image_uri);
-}
-
-void
-e_html_editor_view_check_magic_links (EHTMLEditorView *view)
-{
-       e_html_editor_view_call_simple_extension_function (view, "DOMCheckMagicLinks");
 }
 
 void
@@ -3449,36 +2849,6 @@ e_html_editor_view_save_selection (EHTMLEditorView *view)
        e_html_editor_view_call_simple_extension_function (view, "DOMSaveSelection");
 }
 
-gboolean
-e_html_editor_view_is_selection_saved (EHTMLEditorView *view)
-{
-       GVariant *result;
-       gboolean selection_saved = FALSE;
-
-       g_return_val_if_fail (E_IS_HTML_EDITOR_VIEW (view), FALSE);
-
-       if (!view->priv->web_extension)
-               return FALSE;
-
-       result = g_dbus_proxy_call_sync (
-               view->priv->web_extension,
-               "DOMIsSelectionSaved",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               g_variant_get (result, "(b)", &selection_saved);
-               g_variant_unref (result);
-       }
-
-       return selection_saved;
-}
-
 /* FIXME WK2
    Finish also changes from commit 59e3bb0 Bug 747510 - Add composer option "Inherit theme colors in HTML 
mode"
 static void
diff --git a/e-util/e-html-editor-view.h b/e-util/e-html-editor-view.h
index 14b47c7..20fb7cf 100644
--- a/e-util/e-html-editor-view.h
+++ b/e-util/e-html-editor-view.h
@@ -67,8 +67,6 @@ struct _EHTMLEditorView {
 struct _EHTMLEditorViewClass {
        WebKitWebViewClass parent_class;
 
-       void            (*paste_clipboard_quoted)
-                                               (EHTMLEditorView *view);
        gboolean        (*popup_event)          (EHTMLEditorView *view,
                                                 GdkEventButton *event);
        void            (*paste_primary_clipboard)
@@ -133,7 +131,7 @@ gboolean    e_html_editor_view_get_magic_links
 void           e_html_editor_view_set_magic_links
                                                (EHTMLEditorView *view,
                                                 gboolean magic_links);
-void           e_html_editor_view_insert_smiley
+void           e_html_editor_view_insert_emoticon
                                                (EHTMLEditorView *view,
                                                 EEmoticon *emoticon);
 gboolean       e_html_editor_view_get_magic_smileys
@@ -174,10 +172,6 @@ void               e_html_editor_view_set_text_html
 void           e_html_editor_view_set_text_plain
                                                (EHTMLEditorView *view,
                                                 const gchar *text);
-void           e_html_editor_view_paste_as_text
-                                               (EHTMLEditorView *view);
-void           e_html_editor_view_paste_clipboard_quoted
-                                               (EHTMLEditorView *view);
 void           e_html_editor_view_embed_styles (EHTMLEditorView *view);
 void           e_html_editor_view_remove_embed_styles
                                                (EHTMLEditorView *view);
@@ -203,8 +197,6 @@ void                e_html_editor_view_set_is_message_from_edit_as_new
 void           e_html_editor_view_set_is_editting_message
                                                (EHTMLEditorView *view,
                                                 gboolean value);
-void           e_html_editor_view_scroll_to_caret
-                                               (EHTMLEditorView *view);
 void           e_html_editor_view_replace_image_src
                                                (EHTMLEditorView *view,
                                                 const gchar *selector,
@@ -217,8 +209,6 @@ void                e_html_editor_view_restore_selection
                                                (EHTMLEditorView *view);
 void           e_html_editor_view_save_selection
                                                (EHTMLEditorView *view);
-gboolean       e_html_editor_view_is_selection_saved
-                                               (EHTMLEditorView *view);
 void           e_html_editor_view_move_selection_on_point
                                                (EHTMLEditorView *view,
                                                 gint x,
diff --git a/e-util/e-html-editor.c b/e-util/e-html-editor.c
index 115cde5..7385139 100644
--- a/e-util/e-html-editor.c
+++ b/e-util/e-html-editor.c
@@ -31,9 +31,8 @@
 #include "e-alert-bar.h"
 #include "e-alert-dialog.h"
 #include "e-alert-sink.h"
-#include "e-html-editor-defines.h"
 #include "e-html-editor-private.h"
-#include "e-html-editor-selection.h"
+#include "e-content-editor.h"
 
 #define E_HTML_EDITOR_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -42,8 +41,8 @@
 /**
  * EHTMLEditor:
  *
- * #EHTMLEditor provides GUI for manipulating with properties of #EHTMLEditorView and
- * its #EHTMLEditorSelection - i.e. toolbars and actions.
+ * #EHTMLEditor provides GUI for manipulating with properties of
+ * #EContentEditor i.e. toolbars and actions.
  */
 
 /* This controls how spelling suggestions are divided between the primary
@@ -88,6 +87,8 @@ G_DEFINE_TYPE_WITH_CODE (
        e_html_editor,
        GTK_TYPE_GRID,
        G_IMPLEMENT_INTERFACE (
+               E_TYPE_EXTENSIBLE, NULL)
+       G_IMPLEMENT_INTERFACE (
                E_TYPE_ALERT_SINK,
                e_html_editor_alert_sink_init))
 
@@ -97,24 +98,20 @@ static void
 action_context_spell_suggest_cb (GtkAction *action,
                                  EHTMLEditor *editor)
 {
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
        const gchar *word;
 
        word = g_object_get_data (G_OBJECT (action), "word");
        g_return_if_fail (word != NULL);
 
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
-
-       e_html_editor_selection_replace_caret_word (selection, word);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_replace_caret_word (cnt_editor, word);
 }
 
 static void
 html_editor_inline_spelling_suggestions (EHTMLEditor *editor)
 {
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
        GtkActionGroup *action_group;
        GtkUIManager *manager;
@@ -127,15 +124,12 @@ html_editor_inline_spelling_suggestions (EHTMLEditor *editor)
        guint threshold;
        gint ii;
 
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
-
-       spell_checker = e_html_editor_view_get_spell_checker (view);
-
-       word = e_html_editor_selection_get_caret_word (selection);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       word = e_content_editor_get_caret_word (cnt_editor);
        if (word == NULL || *word == '\0')
                return;
 
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
        suggestions = e_spell_checker_get_guesses_for_word (spell_checker, word);
 
        path = "/context-menu/context-spell-suggest/";
@@ -213,8 +207,7 @@ static void
 html_editor_spell_checkers_foreach (EHTMLEditor *editor,
                                     const gchar *language_code)
 {
-       EHTMLEditorView *view;
-       EHTMLEditorSelection *selection;
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
        ESpellDictionary *dictionary = NULL;
        GtkActionGroup *action_group;
@@ -225,14 +218,13 @@ html_editor_spell_checkers_foreach (EHTMLEditor *editor,
        gint ii = 0;
        guint merge_id;
 
-       view = e_html_editor_get_view (editor);
-       selection = e_html_editor_view_get_selection (view);
-       spell_checker = e_html_editor_view_get_spell_checker (view);
-
-       word = e_html_editor_selection_get_caret_word (selection);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       word = e_content_editor_get_caret_word (cnt_editor);
        if (word == NULL || *word == '\0')
                return;
 
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
+
        dictionary = e_spell_checker_ref_dictionary (
                spell_checker, language_code);
        if (dictionary != NULL) {
@@ -308,11 +300,11 @@ void
 e_html_editor_update_spell_actions (EHTMLEditor *editor)
 {
        ESpellChecker *checker;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        guint count;
 
-       view = e_html_editor_get_view (editor);
-       checker = e_html_editor_view_get_spell_checker (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       checker = e_content_editor_get_spell_checker (cnt_editor);
 
        count = e_spell_checker_count_active_languages (checker);
 
@@ -327,9 +319,8 @@ e_html_editor_update_spell_actions (EHTMLEditor *editor)
 static void
 html_editor_update_actions (EHTMLEditor *editor)
 {
-       EHTMLEditorSelection *selection;
-       EHTMLEditorView *view;
-       GDBusProxy *web_extension;
+       EContentEditor *cnt_editor;
+       EContentEditorNodeFlags flags = editor->priv->node_flags;
        ESpellChecker *spell_checker;
        GtkUIManager *manager;
        GtkActionGroup *action_group;
@@ -338,36 +329,22 @@ html_editor_update_actions (EHTMLEditor *editor)
        guint ii, n_languages;
        gboolean visible;
        guint merge_id;
-       guint flags = 0;
 
-       view = e_html_editor_get_view (editor);
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (web_extension) {
-               GVariant *result;
-
-               result = g_dbus_proxy_get_cached_property (web_extension, "NodeUnderMouseClickFlags");
-               if (result) {
-                       flags = g_variant_get_uint32 (result);
-                       g_variant_unref (result);
-               }
-       }
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        if (camel_debug ("wex"))
                printf ("%s: flags:%d(%x)\n", G_STRFUNC, flags, flags);
-       spell_checker = e_html_editor_view_get_spell_checker (view);
 
-       manager = e_html_editor_get_ui_manager (editor);
-
-       visible = (flags & E_HTML_EDITOR_NODE_IS_IMAGE);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_IMAGE);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_IMAGE), visible);
 
-       visible = (flags & E_HTML_EDITOR_NODE_IS_ANCHOR);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_ANCHOR);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_LINK), visible);
 
-       visible = (flags & E_HTML_EDITOR_NODE_IS_HR);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_H_RULE);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_RULE), visible);
 
-       visible = (flags & E_HTML_EDITOR_NODE_IS_TEXT);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_TEXT);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_TEXT), visible);
 
        visible =
@@ -381,10 +358,10 @@ html_editor_update_actions (EHTMLEditor *editor)
         *   - Cursor is on a link.
         *   - Cursor is on an image that has a URL or target.
         */
-       visible = (flags & E_HTML_EDITOR_NODE_IS_ANCHOR);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_ANCHOR);
        gtk_action_set_visible (ACTION (CONTEXT_REMOVE_LINK), visible);
 
-       visible = (flags & E_HTML_EDITOR_NODE_IS_TABLE_CELL);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_TABLE_CELL);
        gtk_action_set_visible (ACTION (CONTEXT_DELETE_CELL), visible);
        gtk_action_set_visible (ACTION (CONTEXT_DELETE_COLUMN), visible);
        gtk_action_set_visible (ACTION (CONTEXT_DELETE_ROW), visible);
@@ -396,11 +373,12 @@ html_editor_update_actions (EHTMLEditor *editor)
        gtk_action_set_visible (ACTION (CONTEXT_INSERT_TABLE), visible);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_CELL), visible);
 
-       visible = (flags & E_HTML_EDITOR_NODE_IS_TABLE);
+       visible = (flags & E_CONTENT_EDITOR_NODE_IS_TABLE);
        gtk_action_set_visible (ACTION (CONTEXT_PROPERTIES_TABLE), visible);
 
        /********************** Spell Check Suggestions **********************/
 
+       manager = e_html_editor_get_ui_manager (editor);
        action_group = editor->priv->suggestion_actions;
 
        /* Remove the old content from the context menu. */
@@ -419,14 +397,14 @@ html_editor_update_actions (EHTMLEditor *editor)
                list = g_list_delete_link (list, list);
        }
 
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
        languages = e_spell_checker_list_active_languages (
                spell_checker, &n_languages);
 
        /* Decide if we should show spell checking items. */
-       selection = e_html_editor_view_get_selection (view);
        visible = FALSE;
-       if ((n_languages > 0) && e_html_editor_selection_has_text (selection)) {
-               gchar *word = e_html_editor_selection_get_caret_word (selection);
+       if ((n_languages > 0) && e_content_editor_selection_has_text (cnt_editor)) {
+               gchar *word = e_content_editor_get_caret_word (cnt_editor);
                if (word && *word) {
                        visible = !e_spell_checker_check_word (spell_checker, word, -1);
                } else {
@@ -468,51 +446,40 @@ html_editor_update_actions (EHTMLEditor *editor)
 static void
 html_editor_spell_languages_changed (EHTMLEditor *editor)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        ESpellChecker *spell_checker;
-       WebKitWebContext *web_context;
        gchar **languages;
 
-       view = e_html_editor_get_view (editor);
-       spell_checker = e_html_editor_view_get_spell_checker (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       spell_checker = e_content_editor_get_spell_checker (cnt_editor);
 
        languages = e_spell_checker_list_active_languages (spell_checker, NULL);
 
        /* Set the languages for webview to highlight misspelled words */
-       web_context = webkit_web_view_get_context (WEBKIT_WEB_VIEW (view));
-       webkit_web_context_set_spell_checking_languages (web_context, (const gchar * const *) languages);
+       e_content_editor_set_spell_checking_languages (cnt_editor, (const gchar **) languages);
 
        if (editor->priv->spell_check_dialog != NULL)
                e_html_editor_spell_check_dialog_update_dictionaries (
                        E_HTML_EDITOR_SPELL_CHECK_DIALOG (
                        editor->priv->spell_check_dialog));
 
-       if (languages && *languages)
-               e_html_editor_view_force_spell_check (view);
-       else
-               e_html_editor_view_turn_spell_check_off (view);
+       e_content_editor_set_spell_check (cnt_editor, languages && *languages);
 
        g_strfreev (languages);
 }
 
 static gboolean
-html_editor_context_menu_cb (WebKitWebView *webkit_web_view,
-                             WebKitContextMenu *context_menu,
-                             GdkEvent *event,
-                             WebKitHitTestResult *hit_test_result,
-                             EHTMLEditor *editor)
+html_editor_context_menu_requested_cb (EContentEditor *cnt_editor,
+                                       EContentEditorNodeFlags flags,
+                                       GdkEvent *event,
+                                       EHTMLEditor *editor)
 {
        GtkWidget *menu;
-       guint flags = 0;
-
-       if (!hit_test_result)
-               return FALSE;
-
-       webkit_context_menu_remove_all (context_menu);
 
        /* COUNT FLAGS */
        menu = e_html_editor_get_managed_widget (editor, "/context-menu");
 
+       editor->priv->node_flags = flags;
        g_signal_emit (editor, signals[UPDATE_ACTIONS], 0, flags);
 
        if (!gtk_menu_get_attach_widget (GTK_MENU (menu)))
@@ -523,13 +490,13 @@ html_editor_context_menu_cb (WebKitWebView *webkit_web_view,
        if (event)
                gtk_menu_popup (
                        GTK_MENU (menu), NULL, NULL, NULL,
-                       GTK_WIDGET (webkit_web_view),
+                       GTK_WIDGET (cnt_editor),
                        ((GdkEventButton*) event)->button,
                        ((GdkEventButton*) event)->time);
        else
                gtk_menu_popup (
                        GTK_MENU (menu), NULL, NULL, NULL,
-                       GTK_WIDGET (webkit_web_view),
+                       GTK_WIDGET (cnt_editor),
                        0,
                        gtk_get_current_event_time ());
 
@@ -615,6 +582,7 @@ static void
 html_editor_constructed (GObject *object)
 {
        EHTMLEditor *editor = E_HTML_EDITOR (object);
+       EContentEditor *cnt_editor;
        EHTMLEditorPrivate *priv = editor->priv;
        GtkWidget *widget;
        GtkToolbar *toolbar;
@@ -623,6 +591,17 @@ html_editor_constructed (GObject *object)
        /* Chain up to parent's method. */
        G_OBJECT_CLASS (e_html_editor_parent_class)->constructed (object);
 
+       e_extensible_load_extensions (E_EXTENSIBLE (object));
+
+       editor_actions_init (editor);
+       priv->editor_layout_row = 2;
+
+       /* Tweak the main-toolbar style. */
+       widget = e_html_editor_get_managed_widget (editor, "/main-toolbar");
+       gtk_style_context_add_class (
+               gtk_widget_get_style_context (widget),
+               GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+
        /* Construct the editing toolbars. */
 
        widget = e_html_editor_get_managed_widget (editor, "/edit-toolbar");
@@ -655,12 +634,13 @@ html_editor_constructed (GObject *object)
        /* EAlertBar controls its own visibility. */
 
        /* Construct the main editing area. */
-       widget = GTK_WIDGET (e_html_editor_get_view (editor));
+       widget = GTK_WIDGET (e_html_editor_get_content_editor (editor));
        gtk_grid_attach (GTK_GRID (editor), widget, 0, 4, 1, 1);
        gtk_widget_show (widget);
+
        g_signal_connect (
-               widget, "context-menu",
-               G_CALLBACK (html_editor_context_menu_cb), editor);
+               widget, "context-menu-requested",
+               G_CALLBACK (html_editor_context_menu_requested_cb), editor);
 
        /* Add some combo boxes to the "edit" toolbar. */
 
@@ -701,12 +681,14 @@ html_editor_constructed (GObject *object)
        gtk_toolbar_insert (toolbar, tool_item, 0);
        priv->color_combo_box = g_object_ref (widget);
        gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+       cnt_editor = e_html_editor_get_content_editor (editor);
        e_binding_bind_property (
                priv->color_combo_box, "current-color",
-               priv->selection, "font-color",
+               cnt_editor, "font-color",
                G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
        e_binding_bind_property (
-               priv->html_editor_view, "editable",
+               cnt_editor, "editable",
                priv->color_combo_box, "sensitive",
                G_BINDING_SYNC_CREATE);
        editor_actions_bind (editor);
@@ -752,8 +734,6 @@ html_editor_dispose (GObject *object)
        g_clear_object (&priv->size_combo_box);
        g_clear_object (&priv->style_combo_box);
 
-       g_clear_object (&priv->html_editor_view);
-
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_html_editor_parent_class)->dispose (object);
 }
@@ -869,8 +849,7 @@ e_html_editor_init (EHTMLEditor *editor)
        priv->language_actions = gtk_action_group_new ("language");
        priv->spell_check_actions = gtk_action_group_new ("spell-check");
        priv->suggestion_actions = gtk_action_group_new ("suggestion");
-       priv->html_editor_view = g_object_ref_sink (e_html_editor_view_new ());
-       priv->selection = e_html_editor_view_get_selection (priv->html_editor_view);
+       priv->content_editors = NULL;
 
        filename = html_editor_find_ui_file ("e-html-editor-manager.ui");
        if (!gtk_ui_manager_add_ui_from_file (priv->manager, filename, &error)) {
@@ -878,15 +857,6 @@ e_html_editor_init (EHTMLEditor *editor)
                g_clear_error (&error);
        }
        g_free (filename);
-
-       editor_actions_init (editor);
-       priv->editor_layout_row = 2;
-
-       /* Tweak the main-toolbar style. */
-       widget = e_html_editor_get_managed_widget (editor, "/main-toolbar");
-       gtk_style_context_add_class (
-               gtk_widget_get_style_context (widget),
-               GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
 }
 
 /**
@@ -903,17 +873,33 @@ e_html_editor_new (void)
 }
 
 /**
- * e_html_editor_get_view:
+ * e_html_editor_get_content_editor:
  * @editor: an #EHTMLEditor
  *
- * Returns instance of #EHTMLEditorView used in the @editor.
+ * Returns instance of #EContentEditor used in the @editor.
  */
-EHTMLEditorView *
-e_html_editor_get_view (EHTMLEditor *editor)
+EContentEditor *
+e_html_editor_get_content_editor (EHTMLEditor *editor)
 {
        g_return_val_if_fail (E_IS_HTML_EDITOR (editor), NULL);
 
-       return editor->priv->html_editor_view;
+       if (!editor->priv->content_editors)
+               return NULL;
+
+       return editor->priv->content_editors->data;
+}
+
+void
+e_html_editor_register_content_editor (EHTMLEditor *editor,
+                                       EContentEditor *cnt_editor)
+{
+       g_return_if_fail (E_IS_HTML_EDITOR (editor));
+       g_return_if_fail (E_IS_CONTENT_EDITOR (cnt_editor));
+
+       /* FIXME XXX */
+       /* Insert the content editors base on some preferences, so the first
+        * one is the most preferable */
+       editor->priv->content_editors = g_list_append (editor->priv->content_editors, cnt_editor);
 }
 
 /**
@@ -1128,7 +1114,7 @@ e_html_editor_pack_above (EHTMLEditor *editor,
  * @as_html: whether the content should be saved as HTML or plain text
  * @error:[out] a #GError
  *
- * Saves current content of the #EHTMLEditorView into given file. When @as_html
+ * Saves current content of the #EContentEditor into given file. When @as_html
  * is @FALSE, the content is first converted into plain text.
  *
  * Returns: @TRUE when content is succesfully saved, @FALSE otherwise.
@@ -1139,6 +1125,7 @@ e_html_editor_save (EHTMLEditor *editor,
                     gboolean as_html,
                     GError **error)
 {
+       EContentEditor *cnt_editor;
        GFile *file;
        GFileOutputStream *stream;
        gchar *content;
@@ -1150,12 +1137,20 @@ e_html_editor_save (EHTMLEditor *editor,
        if ((error && *error) || !stream)
                return FALSE;
 
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
        if (as_html)
-               content = e_html_editor_view_get_text_html (
-                       E_HTML_EDITOR_VIEW (editor), NULL, NULL);
+               content = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_HTML |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
        else
-               content = e_html_editor_view_get_text_plain (
-                       E_HTML_EDITOR_VIEW (editor));
+               content = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
 
        if (!content || !*content) {
                g_set_error (
@@ -1174,5 +1169,3 @@ e_html_editor_save (EHTMLEditor *editor,
 
        return TRUE;
 }
-
-
diff --git a/e-util/e-html-editor.h b/e-util/e-html-editor.h
index 59cfd1c..884d552 100644
--- a/e-util/e-html-editor.h
+++ b/e-util/e-html-editor.h
@@ -28,7 +28,7 @@
 #include <gtk/gtk.h>
 #include <e-util/e-activity.h>
 #include <e-util/e-activity-bar.h>
-#include <e-util/e-html-editor-view.h>
+#include <e-util/e-content-editor.h>
 
 /* Standard GObject macros */
 #define E_TYPE_HTML_EDITOR \
@@ -71,8 +71,12 @@ struct _EHTMLEditorClass {
 
 GType          e_html_editor_get_type          (void) G_GNUC_CONST;
 GtkWidget *    e_html_editor_new               (void);
-EHTMLEditorView *
-               e_html_editor_get_view          (EHTMLEditor *editor);
+EContentEditor *
+               e_html_editor_get_content_editor
+                                               (EHTMLEditor *editor);
+void           e_html_editor_register_content_editor
+                                               (EHTMLEditor *editor,
+                                                EContentEditor *cnt_editor);
 GtkBuilder *   e_html_editor_get_builder       (EHTMLEditor *editor);
 GtkUIManager * e_html_editor_get_ui_manager    (EHTMLEditor *editor);
 GtkAction *    e_html_editor_get_action        (EHTMLEditor *editor,
diff --git a/e-util/e-mail-signature-editor.c b/e-util/e-mail-signature-editor.c
index a92ab4b..b75b07d 100644
--- a/e-util/e-mail-signature-editor.c
+++ b/e-util/e-mail-signature-editor.c
@@ -101,7 +101,7 @@ mail_signature_editor_loaded_cb (GObject *object,
                                  gpointer user_data)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        ESource *source;
        EMailSignatureEditor *window;
        ESourceMailSignature *extension;
@@ -144,13 +144,21 @@ mail_signature_editor_loaded_cb (GObject *object,
        is_html = (g_strcmp0 (mime_type, "text/html") == 0);
 
        editor = e_mail_signature_editor_get_editor (window);
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_html_mode (view, is_html);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_html_mode (cnt_editor, is_html);
 
        if (is_html)
-               e_html_editor_view_set_text_html (view, contents);
+               e_content_editor_insert_content (
+                       cnt_editor,
+                       contents,
+                       E_CONTENT_EDITOR_INSERT_TEXT_HTML |
+                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
        else
-               e_html_editor_view_set_text_plain (view, contents);
+               e_content_editor_insert_content (
+                       cnt_editor,
+                       contents,
+                       E_CONTENT_EDITOR_INSERT_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
 
        g_free (contents);
 
@@ -172,22 +180,22 @@ mail_signature_editor_delete_event_cb (EMailSignatureEditor *editor,
 }
 
 static void
-can_undo_cb (WebKitWebView *webkit_web_view,
-             GAsyncResult *result,
-             EMailSignatureEditor *window)
+action_close_cb (GtkAction *action,
+                 EMailSignatureEditor *window)
 {
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
        gboolean something_changed = FALSE;
        const gchar *original_name;
        const gchar *signature_name;
-       gboolean can_undo;
+
+       editor = e_mail_signature_editor_get_editor (window);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        original_name = window->priv->original_name;
        signature_name = gtk_entry_get_text (GTK_ENTRY (window->priv->entry));
 
-       can_undo = webkit_web_view_can_execute_editing_command_finish (
-               webkit_web_view, result, NULL);
-
-       something_changed |= can_undo;
+       something_changed |= e_content_editor_can_undo (cnt_editor);
        something_changed |= (strcmp (signature_name, original_name) != 0);
 
        if (something_changed) {
@@ -210,25 +218,6 @@ can_undo_cb (WebKitWebView *webkit_web_view,
        }
 
        gtk_widget_destroy (GTK_WIDGET (window));
-
-}
-
-static void
-action_close_cb (GtkAction *action,
-                 EMailSignatureEditor *window)
-{
-       EHTMLEditor *editor;
-       EHTMLEditorView *view;
-
-       editor = e_mail_signature_editor_get_editor (window);
-       view = e_html_editor_get_view (editor);
-
-       webkit_web_view_can_execute_editing_command (
-               WEBKIT_WEB_VIEW (view),
-               WEBKIT_EDITING_COMMAND_UNDO,
-               NULL, /* cancellable */
-               (GAsyncReadyCallback) can_undo_cb,
-               window);
 }
 
 static void
@@ -501,7 +490,7 @@ mail_signature_editor_constructed (GObject *object)
        GtkActionGroup *action_group;
        EFocusTracker *focus_tracker;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkUIManager *ui_manager;
        GDBusObject *dbus_object;
        ESource *source;
@@ -517,7 +506,7 @@ mail_signature_editor_constructed (GObject *object)
 
        window = E_MAIL_SIGNATURE_EDITOR (object);
        editor = e_mail_signature_editor_get_editor (window);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        ui_manager = e_html_editor_get_ui_manager (editor);
 
@@ -628,7 +617,7 @@ mail_signature_editor_constructed (GObject *object)
        if (source == NULL) {
                gtk_widget_grab_focus (window->priv->entry);
        } else {
-               gtk_widget_grab_focus (GTK_WIDGET (view));
+               gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
        }
 
        /* Load file content only for an existing signature.
@@ -841,7 +830,7 @@ e_mail_signature_editor_commit (EMailSignatureEditor *window,
        const gchar *mime_type;
        gchar *contents;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (window));
 
@@ -849,10 +838,14 @@ e_mail_signature_editor_commit (EMailSignatureEditor *window,
        source = e_mail_signature_editor_get_source (window);
 
        editor = e_mail_signature_editor_get_editor (window);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        mime_type = "text/html";
-       contents = e_html_editor_view_get_body_text_html_for_drafts (view);
+       contents = e_content_editor_get_content (
+               cnt_editor,
+               E_CONTENT_EDITOR_GET_TEXT_HTML |
+               E_CONTENT_EDITOR_GET_BODY,
+               NULL);
 
        extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
        extension = e_source_get_extension (source, extension_name);
diff --git a/e-util/e-mail-signature-manager.c b/e-util/e-mail-signature-manager.c
index 1ebb9a5..cd2f163 100644
--- a/e-util/e-mail-signature-manager.c
+++ b/e-util/e-mail-signature-manager.c
@@ -399,7 +399,7 @@ static void
 mail_signature_manager_add_signature (EMailSignatureManager *manager)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        ESourceRegistry *registry;
        GtkWidget *widget;
 
@@ -409,9 +409,8 @@ mail_signature_manager_add_signature (EMailSignatureManager *manager)
 
        editor = e_mail_signature_editor_get_editor (
                E_MAIL_SIGNATURE_EDITOR (widget));
-       view = e_html_editor_get_view (editor);
-       e_html_editor_view_set_html_mode (
-               view, manager->priv->prefer_html);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       e_content_editor_set_html_mode (cnt_editor, manager->priv->prefer_html);
 
        mail_signature_manager_emit_editor_created (manager, widget);
 
diff --git a/e-util/e-marshal.list b/e-util/e-marshal.list
index ee2106f..1ccafed 100644
--- a/e-util/e-marshal.list
+++ b/e-util/e-marshal.list
@@ -1,6 +1,7 @@
 BOOLEAN:BOXED
 BOOLEAN:BOXED,STRING
 BOOLEAN:INT,INT,BOXED
+BOOLEAN:INT,BOXED
 BOOLEAN:INT,INT,OBJECT,INT,INT,UINT
 BOOLEAN:INT,POINTER,INT,BOXED
 BOOLEAN:INT,POINTER,INT,OBJECT,INT,INT,UINT
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index c985ccc..a587380 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -56,6 +56,7 @@
 #include "e-client-cache.h"
 #include "e-filter-option.h"
 #include "e-util-private.h"
+#include "e-mktemp.h"
 
 typedef struct _WindowData WindowData;
 
@@ -3342,3 +3343,56 @@ e_util_is_main_thread (GThread *thread)
 {
        return thread ? thread == main_thread : g_thread_self () == main_thread;
 }
+
+/**
+ * e_util_save_image_from_clipboard:
+ * @clipboard: a #GtkClipboard
+ * @hint: (allow none): a hint to set, or %NULL to unset
+ *
+ * Saves the image from @clipboard to a temporary file and returns its URI.
+ *
+ * Since: 3.22
+ **/
+gchar *
+e_util_save_image_from_clipboard (GtkClipboard *clipboard)
+{
+       GdkPixbuf *pixbuf = NULL;
+       gchar *filename = NULL;
+       gchar *uri = NULL;
+       GError *error = NULL;
+
+       g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), NULL);
+
+       /* Extract the image data from the clipboard. */
+       pixbuf = gtk_clipboard_wait_for_image (clipboard);
+       g_return_val_if_fail (pixbuf != NULL, FALSE);
+
+       /* Reserve a temporary file. */
+       filename = e_mktemp (NULL);
+       if (filename == NULL) {
+               g_set_error (
+                       &error, G_FILE_ERROR,
+                       g_file_error_from_errno (errno),
+                       "Could not create temporary file: %s",
+                       g_strerror (errno));
+               goto exit;
+       }
+
+       /* Save the pixbuf as a temporary file in image/png format. */
+       if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL))
+               goto exit;
+
+       /* Convert the filename to a URI. */
+       uri = g_filename_to_uri (filename, NULL, &error);
+
+ exit:
+       if (error != NULL) {
+               g_warning ("%s", error->message);
+               g_error_free (error);
+       }
+
+       g_object_unref (pixbuf);
+       g_free (filename);
+
+       return uri;
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index cb78a72..55033ab 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -289,6 +289,8 @@ guint               e_util_normalize_font_size      (GtkWidget *widget,
                                                 gdouble font_size);
 void           e_util_init_main_thread         (GThread *thread);
 gboolean       e_util_is_main_thread           (GThread *thread);
+gchar *                e_util_save_image_from_clipboard
+                                               (GtkClipboard *clipboard);
 
 G_END_DECLS
 
diff --git a/e-util/e-util-enums.h b/e-util/e-util-enums.h
index d24aebd..efa4192 100644
--- a/e-util/e-util-enums.h
+++ b/e-util/e-util-enums.h
@@ -124,209 +124,6 @@ typedef enum {
        E_DURATION_DAYS
 } EDurationType;
 
-typedef enum {
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_NONE = 0,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H2,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H3,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H4,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H5,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN,
-       E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA
-} EHTMLEditorSelectionBlockFormat;
-
-/* The values match the actual size in <font size="n"> */
-typedef enum {
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_TINY          = 1,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_SMALL         = 2,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL        = 3,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_BIG           = 4,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_BIGGER        = 5,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_LARGE         = 6,
-       E_HTML_EDITOR_SELECTION_FONT_SIZE_VERY_LARGE    = 7
-} EHTMLEditorSelectionFontSize;
-
-typedef enum {
-       E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT,
-       E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER,
-       E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT
-} EHTMLEditorSelectionAlignment;
-
-typedef enum {
-       E_HTML_EDITOR_SELECTION_GRANULARITY_CHARACTER,
-       E_HTML_EDITOR_SELECTION_GRANULARITY_WORD
-} EHTMLEditorSelectionGranularity;
-
-/**
- * EHTMLEditorViewCommand:
- * @E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR:
- *   Sets background color to given value.
- * @E_HTML_EDITOR_VIEW_COMMAND_BOLD:
- *   Toggles bold formatting of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_COPY:
- *   Copies current selection to clipboard.
- * @E_HTML_EDITOR_VIEW_COMMAND_CREATE_LINK:
- *   Converts current selection to a link that points to URL in value
- * @E_HTML_EDITOR_VIEW_COMMAND_CUT:
- *   Cuts current selection to clipboard.
- * @E_HTML_EDITOR_VIEW_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR:
- *   (XXX Explain me!)
- * @E_HTML_EDITOR_VIEW_COMMAND_DELETE:
- *   Deletes current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_FIND_STRING:
- *   Highlights given string.
- * @E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME:
- *   Sets font name to given value.
- * @E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE:
- *   Sets font point size to given value (no units, just number)
- * @E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE_DELTA:
- *   Changes font size by given delta value (no units, just number)
- * @E_HTML_EDITOR_VIEW_COMMAND_FORE_COLOR:
- *   Sets font color to given value
- * @E_HTML_EDITOR_VIEW_COMMAND_FORMAT_BLOCK:
- *   Sets block type of current paragraph to given format. Allowed formats
- *   are "BLOCKQUOTE", "H1", "H2", "H3", "H4", "H5", "H6", "P", "PRE" and
- *   "ADDRESS".
- * @E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE:
- *   (XXX Explain me!)
- * @E_HTML_EDITOR_VIEW_COMMAND_HILITE_COLOR:
- *   Sets color in which results of "FindString" command should be
- *   highlighted to given value.
- * @E_HTML_EDITOR_VIEW_COMMAND_INDENT:
- *   Indents current paragraph by one level.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML:
- *   Inserts give HTML code into document.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_HORIZONTAL_RULE:
- *   Inserts a horizontal rule (&lt;HR&gt;) on current line.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_IMAGE:
- *   Inserts an image with given source file.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_LINE_BREAK:
- *   Breaks line at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT:
- *   Breaks citation at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_ORDERED_LIST:
- *   Creates an ordered list environment at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_PARAGRAPH:
- *   Inserts a new paragraph at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT:
- *   Inserts given text at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_INSERT_UNORDERED_LIST:
- *   Creates an undordered list environment at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_ITALIC:
- *   Toggles italic formatting of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_CENTER:
- *   Aligns current paragraph to center.
- * @E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_FULL:
- *   Justifies current paragraph to block.
- * @E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_NONE:
- *   Removes any justification or alignment of current paragraph.
- * @E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_RIGHT:
- *   Aligns current paragraph to right.
- * @E_HTML_EDITOR_VIEW_COMMAND_OUTDENT:
- *   Outdents current paragraph by one level.
- * @E_HTML_EDITOR_VIEW_COMMAND_PASTE:
- *   Pastes clipboard content at current cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_PASTE_AND_MATCH_STYLE:
- *   Pastes clipboard content and matches its style to style at current
- *   cursor position.
- * @E_HTML_EDITOR_VIEW_COMMAND_PASTE_AS_PLAIN_TEXT:
- *   Pastes clipboard content at current cursor position removing any HTML
- *   formatting.
- * @E_HTML_EDITOR_VIEW_COMMAND_PRINT:
- *   Print current document.
- * @E_HTML_EDITOR_VIEW_COMMAND_REDO:
- *   Redoes last action.
- * @E_HTML_EDITOR_VIEW_COMMAND_REMOVE_FORMAT:
- *   Removes any formatting of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_SELECT_ALL:
- *   Extends selects to the entire document.
- * @E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH:
- *   Toggles strikethrough formatting.
- * @E_HTML_EDITOR_VIEW_COMMAND_STYLE_WITH_CSS:
- *   Toggles whether style should be defined in CSS "style" attribute of
- *   elements or whether to use deprecated &lt;FONT&gt; tags. Depends on
- *   whether given value is "true" or "false".
- * @E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT:
- *   Toggles subscript of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT:
- *   Toggles superscript of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_TRANSPOSE:
- *   (XXX Explain me!)
- * @E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE:
- *   Toggles underline formatting of current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_UNDO:
- *   Undoes last action.
- * @E_HTML_EDITOR_VIEW_COMMAND_UNLINK:
- *   Removes active links (&lt;A&gt;) from current selection (if there's any).
- * @E_HTML_EDITOR_VIEW_COMMAND_UNSELECT:
- *   Cancels current selection.
- * @E_HTML_EDITOR_VIEW_COMMAND_USE_CSS:
- *   Whether to allow use of CSS or not depending on whether given value is
- *   "true" or "false".
- *
- * Specifies the DOM command to execute in e_editor_widget_exec_command().
- * Some commands require value to be passed in, which is always stated in the
- * documentation.
- */
-typedef enum {
-       E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR,
-       E_HTML_EDITOR_VIEW_COMMAND_BOLD,
-       E_HTML_EDITOR_VIEW_COMMAND_COPY,
-       E_HTML_EDITOR_VIEW_COMMAND_CREATE_LINK,
-       E_HTML_EDITOR_VIEW_COMMAND_CUT,
-       E_HTML_EDITOR_VIEW_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR,
-       E_HTML_EDITOR_VIEW_COMMAND_DELETE,
-       E_HTML_EDITOR_VIEW_COMMAND_FIND_STRING,
-       E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME,
-       E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE,
-       E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE_DELTA,
-       E_HTML_EDITOR_VIEW_COMMAND_FORE_COLOR,
-       E_HTML_EDITOR_VIEW_COMMAND_FORMAT_BLOCK,
-       E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE,
-       E_HTML_EDITOR_VIEW_COMMAND_HILITE_COLOR,
-       E_HTML_EDITOR_VIEW_COMMAND_INDENT,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_HORIZONTAL_RULE,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_IMAGE,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_LINE_BREAK,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_ORDERED_LIST,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_PARAGRAPH,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT,
-       E_HTML_EDITOR_VIEW_COMMAND_INSERT_UNORDERED_LIST,
-       E_HTML_EDITOR_VIEW_COMMAND_ITALIC,
-       E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_CENTER,
-       E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_FULL,
-       E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_LEFT,
-       E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_NONE,
-       E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_RIGHT,
-       E_HTML_EDITOR_VIEW_COMMAND_OUTDENT,
-       E_HTML_EDITOR_VIEW_COMMAND_PASTE,
-       E_HTML_EDITOR_VIEW_COMMAND_PASTE_AND_MATCH_STYLE,
-       E_HTML_EDITOR_VIEW_COMMAND_PASTE_AS_PLAIN_TEXT,
-       E_HTML_EDITOR_VIEW_COMMAND_PRINT,
-       E_HTML_EDITOR_VIEW_COMMAND_REDO,
-       E_HTML_EDITOR_VIEW_COMMAND_REMOVE_FORMAT,
-       E_HTML_EDITOR_VIEW_COMMAND_SELECT_ALL,
-       E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH,
-       E_HTML_EDITOR_VIEW_COMMAND_STYLE_WITH_CSS,
-       E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT,
-       E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT,
-       E_HTML_EDITOR_VIEW_COMMAND_TRANSPOSE,
-       E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE,
-       E_HTML_EDITOR_VIEW_COMMAND_UNDO,
-       E_HTML_EDITOR_VIEW_COMMAND_UNLINK,
-       E_HTML_EDITOR_VIEW_COMMAND_UNSELECT,
-       E_HTML_EDITOR_VIEW_COMMAND_USE_CSS
-} EHTMLEditorViewCommand;
-
 /**
  * EImageLoadingPolicy:
  * @E_IMAGE_LOADING_POLICY_NEVER:
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 209a0f1..25f0330 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -86,6 +86,9 @@
 #include <e-util/e-config.h>
 #include <e-util/e-conflict-search-selector.h>
 #include <e-util/e-contact-store.h>
+#include <e-util/e-content-editor.h>
+#include <e-util/e-content-editor-find-controller.h>
+#include <e-util/e-content-editor-enums.h>
 #include <e-util/e-content-request.h>
 #include <e-util/e-data-capture.h>
 #include <e-util/e-dateedit.h>
@@ -112,7 +115,6 @@
 #include <e-util/e-filter-part.h>
 #include <e-util/e-filter-rule.h>
 #include <e-util/e-focus-tracker.h>
-#include <e-util/e-html-editor-defines.h>
 #ifndef E_UTIL_INCLUDE_WITHOUT_WEBKIT
 #include <e-util/e-html-editor-actions.h>
 #include <e-util/e-html-editor-cell-dialog.h>
@@ -124,11 +126,9 @@
 #include <e-util/e-html-editor-page-dialog.h>
 #include <e-util/e-html-editor-paragraph-dialog.h>
 #include <e-util/e-html-editor-replace-dialog.h>
-#include <e-util/e-html-editor-selection.h>
 #include <e-util/e-html-editor-spell-check-dialog.h>
 #include <e-util/e-html-editor-table-dialog.h>
 #include <e-util/e-html-editor-text-dialog.h>
-#include <e-util/e-html-editor-view.h>
 #include <e-util/e-html-editor.h>
 #endif
 #include <e-util/e-html-utils.h>
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 417e61a..0fb1db4 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -1076,7 +1076,6 @@ setup_dom_bindings (WebKitWebView *web_view,
 
        web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
 
-
        if (web_extension) {
                if (display->priv->web_extension_headers_collapsed_signal_id == 0) {
                        display->priv->web_extension_headers_collapsed_signal_id =
diff --git a/mail/e-mail-notes.c b/mail/e-mail-notes.c
index 32c9228..ac5ee43 100644
--- a/mail/e-mail-notes.c
+++ b/mail/e-mail-notes.c
@@ -94,12 +94,12 @@ e_mail_notes_extract_text_content (CamelMimePart *part)
 }
 
 static void
-e_mail_notes_extract_text_from_multipart_alternative (EHTMLEditorView *view,
+e_mail_notes_extract_text_from_multipart_alternative (EContentEditor *cnt_editor,
                                                      CamelMultipart *in_multipart)
 {
        guint ii, nparts;
 
-       g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
+       g_return_if_fail (E_IS_CONTENT_EDITOR (cnt_editor));
        g_return_if_fail (CAMEL_IS_MULTIPART (in_multipart));
 
        nparts = camel_multipart_get_number (in_multipart);
@@ -122,8 +122,12 @@ e_mail_notes_extract_text_from_multipart_alternative (EHTMLEditorView *view,
 
                        text = e_mail_notes_extract_text_content (part);
                        if (text) {
-                               e_html_editor_view_set_html_mode (view, TRUE);
-                               e_html_editor_view_set_text_html (view, text);
+                               e_content_editor_set_html_mode (cnt_editor, TRUE);
+                               e_content_editor_insert_content (
+                                       cnt_editor,
+                                       text,
+                                       E_CONTENT_EDITOR_INSERT_TEXT_HTML |
+                                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
                                g_free (text);
                                break;
                        }
@@ -132,7 +136,11 @@ e_mail_notes_extract_text_from_multipart_alternative (EHTMLEditorView *view,
 
                        text = e_mail_notes_extract_text_content (part);
                        if (text) {
-                               e_html_editor_view_set_text_plain (view, text);
+                               e_content_editor_insert_content (
+                                       cnt_editor,
+                                       text,
+                                       E_CONTENT_EDITOR_INSERT_TEXT_PLAIN |
+                                       E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
                                g_free (text);
                        }
                        break;
@@ -144,13 +152,13 @@ static void
 e_mail_notes_editor_extract_text_from_multipart_related (EMailNotesEditor *notes_editor,
                                                         CamelMultipart *multipart)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        guint ii, nparts;
 
        g_return_if_fail (E_IS_MAIL_NOTES_EDITOR (notes_editor));
        g_return_if_fail (CAMEL_IS_MULTIPART (multipart));
 
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
        nparts = camel_multipart_get_number (multipart);
 
        for (ii = 0; ii < nparts; ii++) {
@@ -167,12 +175,11 @@ e_mail_notes_editor_extract_text_from_multipart_related (EMailNotesEditor *notes
                        continue;
 
                if (camel_content_type_is (ct, "image", "*")) {
-                       e_html_editor_view_add_inline_image_from_mime_part (view, part);
+                       e_content_editor_insert_image_from_mime_part (cnt_editor, part);
                } else if (camel_content_type_is (ct, "multipart", "alternative")) {
                        content = camel_medium_get_content (CAMEL_MEDIUM (part));
-                       if (CAMEL_IS_MULTIPART (content)) {
-                               e_mail_notes_extract_text_from_multipart_alternative (view, CAMEL_MULTIPART 
(content));
-                       }
+                       if (CAMEL_IS_MULTIPART (content))
+                               e_mail_notes_extract_text_from_multipart_alternative (cnt_editor, 
CAMEL_MULTIPART (content));
                }
        }
 }
@@ -183,7 +190,7 @@ e_mail_notes_editor_extract_text_from_part (EMailNotesEditor *notes_editor,
 {
        CamelContentType *ct;
        CamelDataWrapper *content;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MAIL_NOTES_EDITOR (notes_editor));
        g_return_if_fail (CAMEL_IS_MIME_PART (part));
@@ -194,7 +201,7 @@ e_mail_notes_editor_extract_text_from_part (EMailNotesEditor *notes_editor,
        g_return_if_fail (content != NULL);
        g_return_if_fail (ct != NULL);
 
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
 
        if (camel_content_type_is (ct, "multipart", "related")) {
                g_return_if_fail (CAMEL_IS_MULTIPART (content));
@@ -202,14 +209,18 @@ e_mail_notes_editor_extract_text_from_part (EMailNotesEditor *notes_editor,
                e_mail_notes_editor_extract_text_from_multipart_related (notes_editor, CAMEL_MULTIPART 
(content));
        } else if (camel_content_type_is (ct, "multipart", "alternative")) {
                if (CAMEL_IS_MULTIPART (content)) {
-                       e_mail_notes_extract_text_from_multipart_alternative (view, CAMEL_MULTIPART 
(content));
+                       e_mail_notes_extract_text_from_multipart_alternative (cnt_editor, CAMEL_MULTIPART 
(content));
                }
        } else if (camel_content_type_is (ct, "text", "plain")) {
                gchar *text;
 
                text = e_mail_notes_extract_text_content (part);
                if (text) {
-                       e_html_editor_view_set_text_plain (view, text);
+                       e_content_editor_insert_content (
+                               cnt_editor,
+                               text,
+                               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN |
+                               E_CONTENT_EDITOR_INSERT_REPLACE_ALL);
                        g_free (text);
                }
        }
@@ -221,7 +232,7 @@ e_mail_notes_editor_extract_text_from_message (EMailNotesEditor *notes_editor,
 {
        CamelContentType *ct;
        CamelDataWrapper *content;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (E_IS_MAIL_NOTES_EDITOR (notes_editor));
        g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
@@ -232,7 +243,7 @@ e_mail_notes_editor_extract_text_from_message (EMailNotesEditor *notes_editor,
        g_return_if_fail (content != NULL);
        g_return_if_fail (ct != NULL);
 
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
 
        if (camel_content_type_is (ct, "multipart", "mixed")) {
                EAttachmentStore *attachment_store;
@@ -276,13 +287,13 @@ e_mail_notes_editor_extract_text_from_message (EMailNotesEditor *notes_editor,
                e_mail_notes_editor_extract_text_from_part (notes_editor, CAMEL_MIME_PART (message));
        }
 
-       e_html_editor_view_set_changed (view, FALSE);
+       e_content_editor_set_changed (cnt_editor, FALSE);
 }
 
 static CamelMimeMessage *
 e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EAttachmentStore *attachment_store;
        CamelMimeMessage *message = NULL;
        gchar *message_uid;
@@ -293,8 +304,8 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
        g_return_val_if_fail (E_IS_MAIL_NOTES_EDITOR (notes_editor), NULL);
        g_return_val_if_fail (notes_editor->editor, NULL);
 
-       view = e_html_editor_get_view (notes_editor->editor);
-       g_return_val_if_fail (E_IS_HTML_EDITOR_VIEW (view), NULL);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
+       g_return_val_if_fail (E_IS_CONTENT_EDITOR (cnt_editor), NULL);
 
        message = camel_mime_message_new ();
        username = g_get_user_name ();
@@ -316,18 +327,23 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
        attachment_store = e_attachment_view_get_store (E_ATTACHMENT_VIEW (notes_editor->attachment_paned));
        has_attachments = e_attachment_store_get_num_attachments (attachment_store) > 0;
 
-       if (e_html_editor_view_get_html_mode (view)) {
+       if (e_content_editor_get_html_mode (cnt_editor)) {
                CamelMultipart *multipart_alternative;
                CamelMultipart *multipart_body;
                CamelMimePart *part;
-               GList *inline_images = NULL;
+               EContentEditorInlineImages *inline_images = NULL;
                gchar *text;
 
                multipart_alternative = camel_multipart_new ();
                camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (multipart_alternative), 
"multipart/alternative");
                camel_multipart_set_boundary (multipart_alternative, NULL);
 
-               text = e_html_editor_view_get_text_plain (view);
+               text = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
+
                if (text && *text) {
                        part = camel_mime_part_new ();
                        camel_mime_part_set_content (part, text, strlen (text), "text/plain");
@@ -340,7 +356,15 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
 
                g_free (text);
 
-               text = e_html_editor_view_get_text_html (view, g_get_host_name (), &inline_images);
+               inline_images = g_new0 (EContentEditorInlineImages, 1);
+               inline_images->from_domain = (gchar *) g_get_host_name ();
+
+               text = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_HTML |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       &inline_images);
+
                if (has_attachments && !has_text && (!text || !*text)) {
                        /* Text is required, thus if there are attachments,
                           but no text, then store at least a space. */
@@ -357,14 +381,15 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
 
                        has_text = TRUE;
                } else {
-                       g_list_free_full (inline_images, g_object_unref);
+                       g_list_free_full (inline_images->images, g_object_unref);
+                       g_free (inline_images);
                        inline_images = NULL;
                }
 
                g_free (text);
 
                if (inline_images) {
-                       GList *link;
+                       GList *link = inline_images->images;
 
                        multipart_body = camel_multipart_new ();
                        camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (multipart_body), 
"multipart/related");
@@ -375,7 +400,7 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
                        camel_multipart_add_part (multipart_body, part);
                        g_object_unref (part);
 
-                       for (link = inline_images; link; link = g_list_next (link)) {
+                       for (; link; link = g_list_next (link)) {
                                CamelMimePart *part = link->data;
 
                                if (!part)
@@ -408,13 +433,18 @@ e_mail_notes_editor_encode_text_to_message (EMailNotesEditor *notes_editor)
 
                camel_medium_set_content (CAMEL_MEDIUM (message), CAMEL_DATA_WRAPPER (multipart_body));
 
-               g_list_free_full (inline_images, g_object_unref);
+               g_list_free_full (inline_images->images, g_object_unref);
+               g_free (inline_images);
                g_clear_object (&multipart_alternative);
                g_clear_object (&multipart_body);
        } else {
                gchar *text;
 
-               text = e_html_editor_view_get_text_plain (view);
+               text = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
 
                if (has_attachments && !has_text && (!text || !*text)) {
                        /* Text is required, thus if there are attachments,
@@ -560,17 +590,17 @@ notes_editor_activity_notify_cb (EActivityBar *activity_bar,
                                 GParamSpec *param,
                                 EMailNotesEditor *notes_editor)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkAction *action;
        gboolean can_edit;
 
        g_return_if_fail (E_IS_ACTIVITY_BAR (activity_bar));
        g_return_if_fail (E_IS_MAIL_NOTES_EDITOR (notes_editor));
 
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
        can_edit = notes_editor->had_message && !e_activity_bar_get_activity (activity_bar);
 
-       webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), can_edit);
+       g_object_set (cnt_editor, "editable", can_edit, NULL);
 
        action = gtk_action_group_get_action (notes_editor->action_group, "save-and-close");
        gtk_action_set_sensitive (action, can_edit);
@@ -711,12 +741,12 @@ static void
 action_close_cb (GtkAction *action,
                 EMailNotesEditor *notes_editor)
 {
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        gboolean something_changed = FALSE;
 
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
 
-       something_changed = e_html_editor_view_get_changed (view);
+       something_changed = e_content_editor_get_changed (cnt_editor);
 
        if (something_changed) {
                gint response;
@@ -921,7 +951,7 @@ e_mail_notes_editor_new (GtkWindow *parent,
        };
 
        EMailNotesEditor *notes_editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EFocusTracker *focus_tracker;
        EActivityBar *activity_bar;
        GtkUIManager *ui_manager;
@@ -951,7 +981,7 @@ e_mail_notes_editor_new (GtkWindow *parent,
        widget = e_html_editor_new ();
 
        notes_editor->editor = E_HTML_EDITOR (widget);
-       view = e_html_editor_get_view (notes_editor->editor);
+       cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
        ui_manager = e_html_editor_get_ui_manager (notes_editor->editor);
 
        /* Because we are loading from a hard-coded string, there is
@@ -996,7 +1026,7 @@ e_mail_notes_editor_new (GtkWindow *parent,
        gtk_widget_show (widget);
 
        e_binding_bind_property (
-               view, "editable",
+               cnt_editor, "editable",
                widget, "sensitive",
                G_BINDING_SYNC_CREATE);
 
@@ -1017,10 +1047,11 @@ e_mail_notes_editor_new (GtkWindow *parent,
 
        notes_editor->focus_tracker = focus_tracker;
 
-       gtk_widget_grab_focus (GTK_WIDGET (view));
+       gtk_widget_grab_focus (GTK_WIDGET (cnt_editor));
 
        settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       e_html_editor_view_set_html_mode (view, g_settings_get_boolean (settings, "composer-send-html"));
+       e_content_editor_set_html_mode (
+               cnt_editor, g_settings_get_boolean (settings, "composer-send-html"));
        g_object_unref (settings);
 
        g_signal_connect (
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 056ab87..5c07f1d 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -534,7 +534,7 @@ composer_presend_check_unwanted_html (EMsgComposer *composer,
 {
        EDestination **recipients;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EComposerHeaderTable *table;
        GSettings *settings;
        gboolean check_passed = TRUE;
@@ -546,8 +546,8 @@ composer_presend_check_unwanted_html (EMsgComposer *composer,
        settings = e_util_ref_settings ("org.gnome.evolution.mail");
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
-       html_mode = e_html_editor_view_get_html_mode (view);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+       html_mode = e_content_editor_get_html_mode (cnt_editor);
 
        table = e_msg_composer_get_header_table (composer);
        recipients = e_composer_header_table_get_destinations (table);
@@ -681,11 +681,12 @@ exit:
 
        if (set_changed) {
                EHTMLEditor *editor;
-               EHTMLEditorView *view;
+               EContentEditor *cnt_editor;
 
                editor = e_msg_composer_get_editor (async_context->composer);
-               view = e_html_editor_get_view (editor);
-               e_html_editor_view_set_changed (view, TRUE);
+               cnt_editor = e_html_editor_get_content_editor (editor);
+
+               e_content_editor_set_changed (cnt_editor, TRUE);
 
                gtk_window_present (GTK_WINDOW (async_context->composer));
        }
@@ -800,14 +801,14 @@ static void
 composer_set_no_change (EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        g_return_if_fail (composer != NULL);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       e_html_editor_view_set_changed (view, FALSE);
+       e_content_editor_set_changed (cnt_editor, FALSE);
 }
 
 /* delete original messages from Outbox folder */
@@ -853,13 +854,13 @@ composer_save_to_drafts_complete (GObject *source_object,
        EActivity *activity;
        AsyncContext *async_context;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GError *local_error = NULL;
 
        async_context = (AsyncContext *) user_data;
 
        editor = e_msg_composer_get_editor (async_context->composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* We don't really care if this failed.  If something other than
         * cancellation happened, emit a runtime warning so the error is
@@ -870,14 +871,13 @@ composer_save_to_drafts_complete (GObject *source_object,
        activity = async_context->activity;
 
        if (e_activity_handle_cancellation (activity, local_error)) {
-               e_html_editor_view_set_changed (view, TRUE);
+               e_content_editor_set_changed (cnt_editor, TRUE);
                g_error_free (local_error);
 
        } else if (local_error != NULL) {
-               e_html_editor_view_set_changed (view, TRUE);
+               e_content_editor_set_changed (cnt_editor, TRUE);
                g_warning ("%s", local_error->message);
                g_error_free (local_error);
-
        } else
                e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
 
@@ -903,14 +903,14 @@ composer_save_to_drafts_cleanup (GObject *source_object,
        EAlertSink *alert_sink;
        GCancellable *cancellable;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        AsyncContext *async_context;
        GError *local_error = NULL;
 
        async_context = (AsyncContext *) user_data;
 
        editor = e_msg_composer_get_editor (async_context->composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        activity = async_context->activity;
        alert_sink = e_activity_get_alert_sink (activity);
@@ -922,7 +922,7 @@ composer_save_to_drafts_cleanup (GObject *source_object,
 
        if (e_activity_handle_cancellation (activity, local_error)) {
                g_warn_if_fail (async_context->message_uid == NULL);
-               e_html_editor_view_set_changed (view, TRUE);
+               e_content_editor_set_changed (cnt_editor, TRUE);
                async_context_free (async_context);
                g_error_free (local_error);
                return;
@@ -933,7 +933,7 @@ composer_save_to_drafts_cleanup (GObject *source_object,
                        alert_sink,
                        "mail-composer:save-to-drafts-error",
                        local_error->message, NULL);
-               e_html_editor_view_set_changed (view, TRUE);
+               e_content_editor_set_changed (cnt_editor, TRUE);
                async_context_free (async_context);
                g_error_free (local_error);
                return;
@@ -998,7 +998,7 @@ composer_save_to_drafts_got_folder (GObject *source_object,
        EActivity *activity;
        CamelFolder *drafts_folder;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        AsyncContext *async_context;
        GError *local_error = NULL;
 
@@ -1007,7 +1007,7 @@ composer_save_to_drafts_got_folder (GObject *source_object,
        activity = async_context->activity;
 
        editor = e_msg_composer_get_editor (async_context->composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        drafts_folder = e_mail_session_uri_to_folder_finish (
                E_MAIL_SESSION (source_object), result, &local_error);
@@ -1018,7 +1018,7 @@ composer_save_to_drafts_got_folder (GObject *source_object,
                ((drafts_folder == NULL) && (local_error != NULL)));
 
        if (e_activity_handle_cancellation (activity, local_error)) {
-               e_html_editor_view_set_changed (view, TRUE);
+               e_content_editor_set_changed (cnt_editor, TRUE);
                async_context_free (async_context);
                g_error_free (local_error);
                return;
@@ -1036,7 +1036,7 @@ composer_save_to_drafts_got_folder (GObject *source_object,
                        GTK_WINDOW (async_context->composer),
                        "mail:ask-default-drafts", NULL);
                if (response != GTK_RESPONSE_YES) {
-                       e_html_editor_view_set_changed (view, TRUE);
+                       e_content_editor_set_changed (cnt_editor, TRUE);
                        async_context_free (async_context);
                        return;
                }
@@ -1360,6 +1360,9 @@ em_utils_compose_new_message (EShell *shell,
                               CamelFolder *folder)
 {
        EMsgComposer *composer;
+       EHTMLEditor *editor;
+       EContentEditor *cnt_editor;
+       EContentEditorContentFlags flags;
 
        g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
@@ -1368,7 +1371,12 @@ em_utils_compose_new_message (EShell *shell,
 
        composer = create_new_composer (shell, "", folder);
        composer_set_no_change (composer);
-       e_msg_composer_is_from_new_message (composer, TRUE);
+       editor = e_msg_composer_get_editor (composer);
+       cnt_editor = e_html_editor_get_content_editor (editor);
+
+       flags = e_content_editor_get_current_content_flags (cnt_editor);
+       flags |= E_CONTENT_EDITOR_MESSAGE_NEW;
+       e_content_editor_set_current_content_flags (cnt_editor, flags);
 
        gtk_widget_show (GTK_WIDGET (composer));
 
@@ -3375,12 +3383,15 @@ em_utils_reply_to_message (EShell *shell,
                CAMEL_MEDIUM (message), "X-Evolution-Content-Source");
        if (g_strcmp0 (evo_source_header, "selection") == 0) {
                EHTMLEditor *editor;
-               EHTMLEditorView *view;
+               EContentEditor *cnt_editor;
+               EContentEditorContentFlags flags;
 
                editor = e_msg_composer_get_editor (composer);
-               view = e_html_editor_get_view (editor);
+               cnt_editor = e_html_editor_get_content_editor (editor);
 
-               e_html_editor_view_set_is_message_from_selection (view, TRUE);
+               flags = e_content_editor_get_current_content_flags (cnt_editor);
+               flags |= E_CONTENT_EDITOR_MESSAGE_FROM_SELECTION;
+               e_content_editor_set_current_content_flags (cnt_editor, flags);
        }
 
        /* If there was no send-account override */
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 5dbe228..8fec148 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -52,6 +52,7 @@ SUBDIRS = \
        startup-wizard \
        vcard-inline \
        web-inspector \
+       webkit-content-editor \
        $(BOGOFILTER_DIR) \
        $(SPAMASSASSIN_DIR) \
        $(TNEF_ATTACHMENT_DIR) \
diff --git a/modules/composer-autosave/e-composer-autosave.c b/modules/composer-autosave/e-composer-autosave.c
index c794593..eabc2e1 100644
--- a/modules/composer-autosave/e-composer-autosave.c
+++ b/modules/composer-autosave/e-composer-autosave.c
@@ -120,15 +120,15 @@ static void
 composer_autosave_changed_cb (EComposerAutosave *autosave)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EExtensible *extensible;
 
        extensible = e_extension_get_extensible (E_EXTENSION (autosave));
 
        editor = e_msg_composer_get_editor (E_MSG_COMPOSER (extensible));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       if (autosave->priv->timeout_id == 0 && e_html_editor_view_get_changed (view)) {
+       if (autosave->priv->timeout_id == 0 && e_content_editor_get_changed (cnt_editor)) {
                autosave->priv->timeout_id = e_named_timeout_add_seconds (
                        AUTOSAVE_INTERVAL,
                        composer_autosave_timeout_cb, autosave);
@@ -160,7 +160,7 @@ static void
 composer_autosave_constructed (GObject *object)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        EExtensible *extensible;
 
        /* Chain up to parent's constructed() method. */
@@ -168,12 +168,12 @@ composer_autosave_constructed (GObject *object)
 
        extensible = e_extension_get_extensible (E_EXTENSION (object));
        editor = e_msg_composer_get_editor (E_MSG_COMPOSER (extensible));
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* Do not use e_signal_connect_notify_swapped() here,
           this module relies on "false" change notifications. */
        g_signal_connect_swapped (
-               view, "notify::changed",
+               cnt_editor, "notify::changed",
                G_CALLBACK (composer_autosave_changed_cb), object);
 }
 
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 1878283..eebd6c3 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -495,11 +495,11 @@ mail_shell_backend_window_added_cb (GtkApplication *application,
 
        /* This applies to both the composer and signature editor. */
        if (editor != NULL) {
-               EHTMLEditorView *view;
+               EContentEditor *cnt_editor;
                GSettings *settings;
                gboolean active = TRUE;
 
-               view = e_html_editor_get_view (editor);
+               cnt_editor = e_html_editor_get_content_editor (editor);
 
                settings = e_util_ref_settings ("org.gnome.evolution.mail");
 
@@ -508,7 +508,7 @@ mail_shell_backend_window_added_cb (GtkApplication *application,
 
                g_object_unref (settings);
 
-               e_html_editor_view_set_html_mode (view, active);
+               e_content_editor_set_html_mode (cnt_editor, active);
        }
 
        if (E_IS_MSG_COMPOSER (window)) {
diff --git a/modules/settings/Makefile.am b/modules/settings/Makefile.am
index e137bea..45db4e8 100644
--- a/modules/settings/Makefile.am
+++ b/modules/settings/Makefile.am
@@ -25,8 +25,8 @@ module_settings_la_SOURCES = \
        e-settings-date-edit.h \
        e-settings-deprecated.c \
        e-settings-deprecated.h \
-       e-settings-html-editor-view.c \
-       e-settings-html-editor-view.h \
+       e-settings-content-editor.c \
+       e-settings-content-editor.h \
        e-settings-mail-browser.c \
        e-settings-mail-browser.h \
        e-settings-mail-formatter.c \
diff --git a/modules/settings/e-settings-html-editor-view.c b/modules/settings/e-settings-content-editor.c
similarity index 56%
rename from modules/settings/e-settings-html-editor-view.c
rename to modules/settings/e-settings-content-editor.c
index c4cb99c..3db53b4 100644
--- a/modules/settings/e-settings-html-editor-view.c
+++ b/modules/settings/e-settings-content-editor.c
@@ -1,5 +1,5 @@
 /*
- * e-settings-html-editor-web-view.c
+ * e-settings-content-editor.c
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -22,39 +22,40 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "e-settings-html-editor-view.h"
+#include "e-settings-content-editor.h"
 
 #include <e-util/e-util.h>
 
-#define E_SETTINGS_HTML_EDITOR_VIEW_GET_PRIVATE(obj) \
+#define E_SETTINGS_CONTENT_EDITOR_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
-       ((obj), E_TYPE_SETTINGS_HTML_EDITOR_VIEW, ESettingsHTMLEditorViewPrivate))
+       ((obj), E_TYPE_SETTINGS_CONTENT_EDITOR, ESettingsContentEditorPrivate))
 
-struct _ESettingsHTMLEditorViewPrivate {
+struct _ESettingsContentEditorPrivate {
        GSettings *settings;
 
        GHashTable *old_settings;
 };
 
 G_DEFINE_DYNAMIC_TYPE (
-       ESettingsHTMLEditorView,
-       e_settings_html_editor_view,
+       ESettingsContentEditor,
+       e_settings_content_editor,
        E_TYPE_EXTENSION)
 
 static void
-settings_html_editor_view_load_style (ESettingsHTMLEditorView *extension)
+settings_content_editor_load_style (ESettingsContentEditor *extension)
 {
        EExtensible *extensible;
+       EContentEditor *cnt_editor;
 
        extensible = e_extension_get_extensible (E_EXTENSION (extension));
-
-       e_html_editor_view_update_fonts (E_HTML_EDITOR_VIEW (extensible));
+       cnt_editor = e_html_editor_get_content_editor (E_HTML_EDITOR (extensible));
+       e_content_editor_update_fonts (cnt_editor);
 }
 
 static void
-settings_html_editor_view_changed_cb (GSettings *settings,
-                                      const gchar *key,
-                                      ESettingsHTMLEditorView *extension)
+settings_content_editor_changed_cb (GSettings *settings,
+                                    const gchar *key,
+                                    ESettingsContentEditor *extension)
 {
        GVariant *new_value, *old_value;
 
@@ -67,15 +68,15 @@ settings_html_editor_view_changed_cb (GSettings *settings,
                else
                        g_hash_table_remove (extension->priv->old_settings, key);
 
-               settings_html_editor_view_load_style (extension);
+               settings_content_editor_load_style (extension);
        } else if (new_value) {
                g_variant_unref (new_value);
        }
 }
 
 static void
-settings_html_editor_view_realize (GtkWidget *widget,
-                                   ESettingsHTMLEditorView *extension)
+settings_content_editor_realize (GtkWidget *widget,
+                                 ESettingsContentEditor *extension)
 {
        GSettings *settings;
 
@@ -101,56 +102,56 @@ settings_html_editor_view_realize (GtkWidget *widget,
                widget, "unicode-smileys",
                G_SETTINGS_BIND_GET);
 
-       settings_html_editor_view_load_style (extension);
+       settings_content_editor_load_style (extension);
 
        /* Reload the web view when certain settings change. */
 
        g_signal_connect (
                settings, "changed::use-custom-font",
-               G_CALLBACK (settings_html_editor_view_changed_cb), extension);
+               G_CALLBACK (settings_content_editor_changed_cb), extension);
 
        g_signal_connect (
                settings, "changed::monospace-font",
-               G_CALLBACK (settings_html_editor_view_changed_cb), extension);
+               G_CALLBACK (settings_content_editor_changed_cb), extension);
 
        g_signal_connect (
                settings, "changed::variable-width-font",
-               G_CALLBACK (settings_html_editor_view_changed_cb), extension);
+               G_CALLBACK (settings_content_editor_changed_cb), extension);
 
        g_signal_connect (
                settings, "changed::mark-citations",
-               G_CALLBACK (settings_html_editor_view_changed_cb), extension);
+               G_CALLBACK (settings_content_editor_changed_cb), extension);
 
        g_signal_connect (
                settings, "changed::citation-color",
-               G_CALLBACK (settings_html_editor_view_changed_cb), extension);
+               G_CALLBACK (settings_content_editor_changed_cb), extension);
 }
 
 static void
-settings_html_editor_view_dispose (GObject *object)
+settings_content_editor_dispose (GObject *object)
 {
-       ESettingsHTMLEditorViewPrivate *priv;
+       ESettingsContentEditorPrivate *priv;
 
-       priv = E_SETTINGS_HTML_EDITOR_VIEW_GET_PRIVATE (object);
+       priv = E_SETTINGS_CONTENT_EDITOR_GET_PRIVATE (object);
 
        if (priv->settings != NULL) {
                g_signal_handlers_disconnect_by_func (
                        priv->settings,
-                       settings_html_editor_view_changed_cb, object);
+                       settings_content_editor_changed_cb, object);
        }
 
        g_clear_object (&priv->settings);
 
        /* Chain up to parent's dispose() method. */
-       G_OBJECT_CLASS (e_settings_html_editor_view_parent_class)->dispose (object);
+       G_OBJECT_CLASS (e_settings_content_editor_parent_class)->dispose (object);
 }
 
 static void
-settings_html_editor_view_finalize (GObject *object)
+settings_content_editor_finalize (GObject *object)
 {
-       ESettingsHTMLEditorViewPrivate *priv;
+       ESettingsContentEditorPrivate *priv;
 
-       priv = E_SETTINGS_HTML_EDITOR_VIEW_GET_PRIVATE (object);
+       priv = E_SETTINGS_CONTENT_EDITOR_GET_PRIVATE (object);
 
        if (priv->old_settings) {
                g_hash_table_destroy (priv->old_settings);
@@ -158,52 +159,54 @@ settings_html_editor_view_finalize (GObject *object)
        }
 
        /* Chain up to parent's finalize() method. */
-       G_OBJECT_CLASS (e_settings_html_editor_view_parent_class)->finalize (object);
+       G_OBJECT_CLASS (e_settings_content_editor_parent_class)->finalize (object);
 }
 
 static void
-settings_html_editor_view_constructed (GObject *object)
+settings_content_editor_constructed (GObject *object)
 {
        EExtensible *extensible;
+       EContentEditor *cnt_editor;
 
        extensible = e_extension_get_extensible (E_EXTENSION (object));
+       cnt_editor = e_html_editor_get_content_editor (E_HTML_EDITOR (extensible));
 
        g_signal_connect (
-               extensible, "realize",
-               G_CALLBACK (settings_html_editor_view_realize), object);
+               cnt_editor, "realize",
+               G_CALLBACK (settings_content_editor_realize), object);
 
        /* Chain up to parent's constructed() method. */
-       G_OBJECT_CLASS (e_settings_html_editor_view_parent_class)->constructed (object);
+       G_OBJECT_CLASS (e_settings_content_editor_parent_class)->constructed (object);
 }
 
 static void
-e_settings_html_editor_view_class_init (ESettingsHTMLEditorViewClass *class)
+e_settings_content_editor_class_init (ESettingsContentEditorClass *class)
 {
        GObjectClass *object_class;
        EExtensionClass *extension_class;
 
-       g_type_class_add_private (class, sizeof (ESettingsHTMLEditorViewPrivate));
+       g_type_class_add_private (class, sizeof (ESettingsContentEditorPrivate));
 
        object_class = G_OBJECT_CLASS (class);
-       object_class->dispose = settings_html_editor_view_dispose;
-       object_class->finalize = settings_html_editor_view_finalize;
-       object_class->constructed = settings_html_editor_view_constructed;
+       object_class->dispose = settings_content_editor_dispose;
+       object_class->finalize = settings_content_editor_finalize;
+       object_class->constructed = settings_content_editor_constructed;
 
        extension_class = E_EXTENSION_CLASS (class);
-       extension_class->extensible_type = E_TYPE_HTML_EDITOR_VIEW;
+       extension_class->extensible_type = E_TYPE_HTML_EDITOR;
 }
 
 static void
-e_settings_html_editor_view_class_finalize (ESettingsHTMLEditorViewClass *class)
+e_settings_content_editor_class_finalize (ESettingsContentEditorClass *class)
 {
 }
 
 static void
-e_settings_html_editor_view_init (ESettingsHTMLEditorView *extension)
+e_settings_content_editor_init (ESettingsContentEditor *extension)
 {
        GSettings *settings;
 
-       extension->priv = E_SETTINGS_HTML_EDITOR_VIEW_GET_PRIVATE (extension);
+       extension->priv = E_SETTINGS_CONTENT_EDITOR_GET_PRIVATE (extension);
 
        settings = e_util_ref_settings ("org.gnome.evolution.mail");
        extension->priv->settings = settings;
@@ -213,11 +216,11 @@ e_settings_html_editor_view_init (ESettingsHTMLEditorView *extension)
 }
 
 void
-e_settings_html_editor_view_type_register (GTypeModule *type_module)
+e_settings_content_editor_type_register (GTypeModule *type_module)
 {
        /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
         *     function, so we have to wrap it with a public function in
         *     order to register types from a separate compilation unit. */
-       e_settings_html_editor_view_register_type (type_module);
+       e_settings_content_editor_register_type (type_module);
 }
 
diff --git a/modules/settings/e-settings-content-editor.h b/modules/settings/e-settings-content-editor.h
new file mode 100644
index 0000000..2b5dc90
--- /dev/null
+++ b/modules/settings/e-settings-content-editor.h
@@ -0,0 +1,64 @@
+/*
+ * e-settings-content-editor.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef E_SETTINGS_CONTENT_EDITOR_H
+#define E_SETTINGS_CONTENT_EDITOR_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SETTINGS_CONTENT_EDITOR \
+       (e_settings_content_editor_get_type ())
+#define E_SETTINGS_CONTENT_EDITOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_SETTINGS_CONTENT_EDITOR, ESettingsContentEditor))
+#define E_SETTINGS_CONTENT_EDITOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_SETTINGS_CONTENT_EDITOR, ESettingsContentEditorClass))
+#define E_IS_SETTINGS_CONTENT_EDITOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_SETTINGS_CONTENT_EDITOR))
+#define E_IS_SETTINGS_CONTENT_EDITOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_SETTINGS_CONTENT_EDITOR))
+#define E_SETTINGS_CONTENT_EDITOR_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_SETTINGS_CONTENT_EDITOR, ESettingsContentEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESettingsContentEditor ESettingsContentEditor;
+typedef struct _ESettingsContentEditorClass ESettingsContentEditorClass;
+typedef struct _ESettingsContentEditorPrivate ESettingsContentEditorPrivate;
+
+struct _ESettingsContentEditor {
+       EExtension parent;
+       ESettingsContentEditorPrivate *priv;
+};
+
+struct _ESettingsContentEditorClass {
+       EExtensionClass parent_class;
+};
+
+GType          e_settings_content_editor_get_type
+                                               (void) G_GNUC_CONST;
+void           e_settings_content_editor_type_register
+                                               (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_SETTINGS_CONTENT_EDITOR_H */
diff --git a/modules/settings/evolution-module-settings.c b/modules/settings/evolution-module-settings.c
index 5b81a94..57abd2b 100644
--- a/modules/settings/evolution-module-settings.c
+++ b/modules/settings/evolution-module-settings.c
@@ -21,7 +21,7 @@
 #include "e-settings-client-cache.h"
 #include "e-settings-date-edit.h"
 #include "e-settings-deprecated.h"
-#include "e-settings-html-editor-view.h"
+#include "e-settings-content-editor.h"
 #include "e-settings-mail-browser.h"
 #include "e-settings-mail-formatter.h"
 #include "e-settings-mail-part-headers.h"
@@ -48,7 +48,7 @@ e_module_load (GTypeModule *type_module)
        e_settings_client_cache_type_register (type_module);
        e_settings_date_edit_type_register (type_module);
        e_settings_deprecated_type_register (type_module);
-       e_settings_html_editor_view_type_register (type_module);
+       e_settings_content_editor_type_register (type_module);
        e_settings_mail_browser_type_register (type_module);
        e_settings_mail_formatter_type_register (type_module);
        e_settings_mail_part_headers_type_register (type_module);
diff --git a/modules/webkit-content-editor/Makefile.am b/modules/webkit-content-editor/Makefile.am
new file mode 100644
index 0000000..424fc77
--- /dev/null
+++ b/modules/webkit-content-editor/Makefile.am
@@ -0,0 +1,31 @@
+module_LTLIBRARIES = module-webkit-content-editor.la
+
+module_webkit_content_editor_la_CPPFLAGS =             \
+       $(AM_CPPFLAGS)                                  \
+       -I$(top_srcdir)                                 \
+       -DEVOLUTION_WEB_EXTENSIONS_COMPOSER_DIR=\""$(webextensionscomposerdir)"\" \
+       -DG_LOG_DOMAIN=\"webkit-content-editor\"        \
+       $(EVOLUTION_DATA_SERVER_CFLAGS)                 \
+       $(GNOME_PLATFORM_CFLAGS)                        \
+       $(CODE_COVERAGE_CFLAGS)                         \
+       $(NULL)
+
+module_webkit_content_editor_la_SOURCES = \
+       evolution-module-webkit-content-editor.c        \
+       e-webkit-editor-extension.c                     \
+       e-webkit-editor-extension.h                     \
+       e-webkit-content-editor.c                       \
+       e-webkit-content-editor.h                       \
+       e-webkit-content-editor-find-controller.c       \
+       e-webkit-content-editor-find-controller.h
+
+module_webkit_content_editor_la_LIBADD = \
+       $(top_builddir)/e-util/libevolution-util.la     \
+       $(EVOLUTION_DATA_SERVER_LIBS)                   \
+       $(GNOME_PLATFORM_LIBS)                          \
+       $(NULL)
+
+module_webkit_content_editor_la_LDFLAGS = \
+       -module -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/webkit-content-editor/e-webkit-content-editor-find-controller.c 
b/modules/webkit-content-editor/e-webkit-content-editor-find-controller.c
new file mode 100644
index 0000000..a824de8
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-content-editor-find-controller.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-webkit-content-editor-find-controller.h"
+#include "e-webkit-content-editor.h"
+
+#include <e-util/e-util.h>
+#include <string.h>
+
+#define E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER, EWebKitContentEditorFindControllerPrivate))
+
+enum {
+       PROP_0,
+       PROP_WEBKIT_CONTENT_EDITOR
+};
+
+struct _EWebKitContentEditorFindControllerPrivate {
+       GWeakRef wk_editor;
+
+       WebKitFindController *find_controller;
+
+       gboolean performing_replace_all;
+       guint replace_all_match_count;
+       gchar *spell_check_replacement;
+
+       gulong found_text_handler_id;
+       gulong failed_to_find_text_handler_id;
+       gulong counted_matches_handler_id;
+};
+
+static void content_editor_content_editor_find_controller_init (EContentEditorFindControllerInterface 
*iface);
+
+G_DEFINE_TYPE_WITH_CODE (
+       EWebKitContentEditorFindController,
+       e_webkit_content_editor_find_controller,
+       G_TYPE_OBJECT,
+       G_IMPLEMENT_INTERFACE (
+               E_TYPE_CONTENT_EDITOR_FIND_CONTROLLER,
+               content_editor_content_editor_find_controller_init));
+
+static EWebKitContentEditor *
+content_editor_find_controller_ref_editor (EWebKitContentEditorFindController *wk_controller)
+{
+       return g_weak_ref_get (&wk_controller->priv->wk_editor);
+}
+
+static void
+webkit_find_controller_found_text_cb (WebKitFindController *find_controller,
+                                      guint match_count,
+                                      EWebKitContentEditorFindController *wk_controller)
+{
+       if (wk_controller->priv->performing_replace_all) {
+               EWebKitContentEditor *wk_editor;
+
+               if (wk_controller->priv->replace_all_match_count == 0)
+                       wk_controller->priv->replace_all_match_count = match_count;
+
+               /* Repeatedly search for 'word', then replace selection by
+                * 'replacement'. Repeat until there's at least one occurrence of
+                * 'word' in the document */
+               wk_editor = content_editor_find_controller_ref_editor (wk_controller);
+
+               e_content_editor_insert_content (
+                       E_CONTENT_EDITOR (wk_editor),
+                       wk_controller->priv->spell_check_replacement,
+                       E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
+
+               g_object_unref (wk_editor);
+
+               webkit_find_controller_search_next (find_controller);
+       } else
+               g_signal_emit_by_name (
+                       E_CONTENT_EDITOR_FIND_CONTROLLER (wk_controller),
+                       "found-text",
+                       0,
+                       match_count);
+}
+
+static void
+webkit_content_editor_find_controller_search_finish (EContentEditorFindController *controller)
+{
+       EWebKitContentEditorFindController *wk_controller;
+
+       wk_controller = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (controller);
+
+       if (wk_controller->priv->performing_replace_all) {
+               g_signal_emit_by_name (
+                       E_CONTENT_EDITOR_FIND_CONTROLLER (controller),
+                       "replace-all-finished",
+                       0,
+                       wk_controller->priv->replace_all_match_count);
+               wk_controller->priv->performing_replace_all = FALSE;
+               wk_controller->priv->replace_all_match_count = 0;
+       }
+
+       webkit_find_controller_search_finish (wk_controller->priv->find_controller);
+}
+
+static void
+webkit_find_controller_failed_to_find_text_cb (WebKitFindController *find_controller,
+                                               EWebKitContentEditorFindController *wk_controller)
+{
+       if (wk_controller->priv->performing_replace_all) {
+               webkit_content_editor_find_controller_search_finish (
+                       E_CONTENT_EDITOR_FIND_CONTROLLER (wk_controller));
+       } else
+               g_signal_emit_by_name (
+                       E_CONTENT_EDITOR_FIND_CONTROLLER (wk_controller),
+                       "failed-to-find-text",
+                       0);
+}
+
+static void
+webkit_find_controller_counted_matches_cb (WebKitFindController *find_controller,
+                                           guint match_count,
+                                           EWebKitContentEditorFindController *wk_controller)
+{
+       g_signal_emit_by_name (
+               E_CONTENT_EDITOR_FIND_CONTROLLER (wk_controller),
+               "counted-matches",
+               0,
+               match_count);
+}
+
+static WebKitFindOptions
+process_find_flags (EContentEditorFindControllerFlags flags)
+{
+       WebKitFindOptions options = 0;
+
+       if (flags & E_CONTENT_EDITOR_FIND_CASE_INSENSITIVE)
+               options |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
+
+       if (flags & E_CONTENT_EDITOR_FIND_WRAP_AROUND)
+               options |= WEBKIT_FIND_OPTIONS_WRAP_AROUND;
+
+       if (flags & E_CONTENT_EDITOR_FIND_BACKWARDS)
+               options |= WEBKIT_FIND_OPTIONS_BACKWARDS;
+
+       return options;
+}
+
+static void
+webkit_content_editor_find_controller_search (EContentEditorFindController *controller,
+                                              const gchar *text,
+                                              EContentEditorFindControllerFlags flags)
+{
+       EWebKitContentEditorFindController *wk_controller;
+
+       wk_controller = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (controller);
+
+       webkit_find_controller_search (
+               wk_controller->priv->find_controller,
+               text,
+               process_find_flags (flags),
+               G_MAXUINT);
+}
+
+static void
+webkit_content_editor_find_controller_search_next (EContentEditorFindController *controller)
+{
+       EWebKitContentEditorFindController *wk_controller;
+
+       wk_controller = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (controller);
+
+       webkit_find_controller_search_next (wk_controller->priv->find_controller);
+}
+
+static void
+webkit_content_editor_find_controller_count_matches (EContentEditorFindController *controller,
+                                                     const gchar *text,
+                                                     EContentEditorFindControllerFlags flags)
+{
+       EWebKitContentEditorFindController *wk_controller;
+
+       wk_controller = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (controller);
+
+       webkit_find_controller_count_matches (
+               wk_controller->priv->find_controller,
+               text,
+               process_find_flags (flags),
+               G_MAXUINT);
+}
+
+static void
+webkit_content_editor_find_controller_replace_all (EContentEditorFindController *controller,
+                                                   const gchar *text,
+                                                   const gchar *replacement,
+                                                   EContentEditorFindControllerFlags flags)
+{
+       EWebKitContentEditorFindController *wk_controller;
+
+       wk_controller = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (controller);
+
+       if (wk_controller->priv->spell_check_replacement)
+               g_free (wk_controller->priv->spell_check_replacement);
+       wk_controller->priv->spell_check_replacement = g_strdup (replacement);
+
+       wk_controller->priv->performing_replace_all = TRUE;
+
+       webkit_find_controller_search (
+               wk_controller->priv->find_controller, text, process_find_flags (flags), G_MAXUINT);
+}
+
+static void
+webkit_content_editor_find_controller_dispose (GObject *object)
+{
+       EWebKitContentEditorFindControllerPrivate *priv;
+
+       priv = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_GET_PRIVATE (object);
+
+       if (priv->found_text_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->find_controller,
+                       priv->found_text_handler_id);
+               priv->found_text_handler_id = 0;
+       }
+
+       if (priv->failed_to_find_text_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->find_controller,
+                       priv->failed_to_find_text_handler_id);
+               priv->failed_to_find_text_handler_id = 0;
+       }
+
+       if (priv->counted_matches_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->find_controller,
+                       priv->counted_matches_handler_id);
+               priv->counted_matches_handler_id = 0;
+       }
+
+       g_weak_ref_set (&priv->wk_editor, NULL);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (e_webkit_content_editor_find_controller_parent_class)->dispose (object);
+}
+
+static void
+webkit_content_editor_find_controller_finalize (GObject *object)
+{
+       EWebKitContentEditorFindControllerPrivate *priv;
+
+       priv = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_GET_PRIVATE (object);
+
+       g_free (priv->spell_check_replacement);
+
+       /* Chain up to parent's finalize() method. */
+       G_OBJECT_CLASS (e_webkit_content_editor_find_controller_parent_class)->finalize (object);
+}
+
+static void
+find_controller_set_content_editor (EWebKitContentEditorFindController *wk_controller,
+                                    EWebKitContentEditor *wk_editor)
+{
+       g_return_if_fail (E_IS_WEBKIT_CONTENT_EDITOR (wk_editor));
+
+       g_weak_ref_set (&wk_controller->priv->wk_editor, wk_editor);
+
+       wk_controller->priv->find_controller =
+               webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (wk_editor));
+
+       wk_controller->priv->found_text_handler_id = g_signal_connect (
+               wk_controller->priv->find_controller, "found-text",
+               (GCallback) webkit_find_controller_found_text_cb, wk_controller);
+
+       wk_controller->priv->failed_to_find_text_handler_id = g_signal_connect (
+               wk_controller->priv->find_controller, "failed-to-find-text",
+               (GCallback) webkit_find_controller_failed_to_find_text_cb, wk_controller);
+
+       wk_controller->priv->counted_matches_handler_id = g_signal_connect (
+               wk_controller->priv->find_controller, "counted-matches",
+               (GCallback) webkit_find_controller_counted_matches_cb, wk_controller);
+}
+
+static void
+webkit_content_editor_find_controller_set_property (GObject *object,
+                                                    guint property_id,
+                                                    const GValue *value,
+                                                    GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_WEBKIT_CONTENT_EDITOR:
+                       find_controller_set_content_editor (
+                               E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER (object),
+                               g_value_get_object (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_webkit_content_editor_find_controller_class_init (EWebKitContentEditorFindControllerClass *class)
+{
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (EWebKitContentEditorFindControllerPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = webkit_content_editor_find_controller_set_property;
+       object_class->dispose = webkit_content_editor_find_controller_dispose;
+       object_class->finalize = webkit_content_editor_find_controller_finalize;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_WEBKIT_CONTENT_EDITOR,
+               g_param_spec_object (
+                       "webkit-content-editor",
+                       NULL,
+                       NULL,
+                       E_TYPE_WEBKIT_CONTENT_EDITOR,
+                       G_PARAM_WRITABLE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_webkit_content_editor_find_controller_init (EWebKitContentEditorFindController *wk_controller)
+{
+       wk_controller->priv = E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_GET_PRIVATE (wk_controller);
+
+       wk_controller->priv->spell_check_replacement = NULL;
+       wk_controller->priv->performing_replace_all = FALSE;
+       wk_controller->priv->replace_all_match_count = 0;
+}
+
+static void
+content_editor_content_editor_find_controller_init (EContentEditorFindControllerInterface *iface)
+{
+       iface->search = webkit_content_editor_find_controller_search;
+       iface->search_next = webkit_content_editor_find_controller_search_next;
+       iface->search_finish = webkit_content_editor_find_controller_search_finish;
+       iface->count_matches = webkit_content_editor_find_controller_count_matches;
+       iface->replace_all = webkit_content_editor_find_controller_replace_all;
+}
diff --git a/modules/webkit-content-editor/e-webkit-content-editor-find-controller.h 
b/modules/webkit-content-editor/e-webkit-content-editor-find-controller.h
new file mode 100644
index 0000000..7573446
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-content-editor-find-controller.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_H
+#define E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_H
+
+#include <webkit2/webkit2.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER \
+       (e_webkit_content_editor_find_controller_get_type ())
+#define E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER, EWebKitContentEditorFindController))
+#define E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER, EWebKitContentEditorFindControllerClass))
+#define E_IS_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER))
+#define E_IS_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER))
+#define E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER, EWebKitContentEditorFindControllerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWebKitContentEditorFindController EWebKitContentEditorFindController;
+typedef struct _EWebKitContentEditorFindControllerClass EWebKitContentEditorFindControllerClass;
+typedef struct _EWebKitContentEditorFindControllerPrivate EWebKitContentEditorFindControllerPrivate;
+
+struct _EWebKitContentEditorFindController {
+       GObject parent;
+
+       EWebKitContentEditorFindControllerPrivate *priv;
+};
+
+struct _EWebKitContentEditorFindControllerClass {
+       GObjectClass parent_class;
+};
+
+GType          e_webkit_content_editor_find_controller_get_type
+                                                       (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* E_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER_H */
diff --git a/modules/webkit-content-editor/e-webkit-content-editor.c 
b/modules/webkit-content-editor/e-webkit-content-editor.c
new file mode 100644
index 0000000..1286627
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-content-editor.c
@@ -0,0 +1,6059 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-webkit-content-editor.h"
+#include "e-webkit-content-editor-find-controller.h"
+
+#include <e-util/e-util.h>
+#include <web-extensions/composer/e-html-editor-web-extension-names.h>
+#include <string.h>
+
+#define E_WEBKIT_CONTENT_EDITOR_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR, EWebKitContentEditorPrivate))
+
+/* FIXME WK2 Move to e-content-editor? */
+#define UNICODE_NBSP "\xc2\xa0"
+#define SPACES_PER_LIST_LEVEL 3
+#define SPACES_ORDERED_LIST_FIRST_LEVEL 6
+
+enum {
+       PROP_0,
+       PROP_CAN_COPY,
+       PROP_CAN_CUT,
+       PROP_CAN_PASTE,
+       PROP_CAN_REDO,
+       PROP_CAN_UNDO,
+       PROP_CHANGED,
+       PROP_EDITABLE,
+       PROP_HTML_MODE,
+       PROP_SPELL_CHECKER,
+
+       PROP_ALIGNMENT,
+       PROP_BACKGROUND_COLOR,
+       PROP_BLOCK_FORMAT,
+       PROP_BOLD,
+       PROP_FONT_COLOR,
+       PROP_FONT_NAME,
+       PROP_FONT_SIZE,
+       PROP_INDENTED,
+       PROP_ITALIC,
+       PROP_MONOSPACED,
+       PROP_STRIKETHROUGH,
+       PROP_SUBSCRIPT,
+       PROP_SUPERSCRIPT,
+       PROP_UNDERLINE
+};
+
+enum {
+       POPUP_EVENT,
+       COPY_CLIPBOARD,
+       CUT_CLIPBOARD,
+       PASTE_CLIPBOARD,
+       PASTE_PRIMARY_CLIPBOARD,
+
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _EWebKitContentEditorPrivate {
+       GDBusProxy *web_extension;
+       guint web_extension_watch_name_id;
+       guint web_extension_selection_changed_cb_id;
+       guint web_extension_content_changed_cb_id;
+
+       gboolean html_mode;
+       gboolean changed;
+       gboolean can_copy;
+       gboolean can_cut;
+       gboolean can_paste;
+       gboolean can_undo;
+       gboolean can_redo;
+
+       gboolean emit_load_finished_when_extension_is_ready;
+       gboolean reload_in_progress;
+       gboolean copy_paste_clipboard_in_view;
+       gboolean copy_paste_primary_in_view;
+       gboolean copy_action_triggered;
+       gboolean pasting_primary_clipboard;
+
+       gboolean is_bold;
+       gboolean is_italic;
+       gboolean is_underline;
+       gboolean is_monospaced;
+       gboolean is_strikethrough;
+       gboolean is_indented;
+       gboolean is_superscript;
+       gboolean is_subscript;
+
+       GdkRGBA *background_color;
+       GdkRGBA *font_color;
+
+       gchar *font_name;
+
+       guint font_size;
+
+       EContentEditorBlockFormat block_format;
+       EContentEditorAlignment alignment;
+
+       gchar *current_user_stylesheet;
+
+       WebKitLoadEvent webkit_load_event;
+
+       GQueue *post_reload_operations;
+
+       GSettings *mail_settings;
+       GSettings *font_settings;
+       GSettings *aliasing_settings;
+
+       GHashTable *old_settings;
+
+       EContentEditorContentFlags content_flags;
+
+       ESpellChecker *spell_checker;
+       EContentEditorFindController *find_controller;
+
+       gulong owner_change_primary_clipboard_cb_id;
+       gulong owner_change_clipboard_cb_id;
+};
+
+static const GdkRGBA black = { 0, 0, 0, 1 };
+static const GdkRGBA white = { 1, 1, 1, 1 };
+static const GdkRGBA transparent = { 0, 0, 0, 0 };
+
+typedef void (*PostReloadOperationFunc) (EWebKitContentEditor *wk_editor, gpointer data, 
EContentEditorInsertContentFlags flags);
+
+typedef struct {
+       PostReloadOperationFunc func;
+       EContentEditorInsertContentFlags flags;
+       gpointer data;
+       GDestroyNotify data_free_func;
+} PostReloadOperation;
+
+static void e_webkit_content_editor_content_editor_init (EContentEditorInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (
+       EWebKitContentEditor,
+       e_webkit_content_editor,
+       WEBKIT_TYPE_WEB_VIEW,
+       G_IMPLEMENT_INTERFACE (
+               E_TYPE_CONTENT_EDITOR,
+               e_webkit_content_editor_content_editor_init));
+
+EWebKitContentEditor *
+e_webkit_content_editor_new (void)
+{
+       return g_object_new (E_TYPE_WEBKIT_CONTENT_EDITOR, NULL);
+}
+
+static void
+webkit_content_editor_can_paste_cb (WebKitWebView *view,
+                                    GAsyncResult *result,
+                                    EWebKitContentEditor *wk_editor)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (view, result, NULL);
+
+       if (wk_editor->priv->can_paste != value) {
+               wk_editor->priv->can_paste = value;
+               g_object_notify (G_OBJECT (wk_editor), "can-paste");
+       }
+}
+
+static gboolean
+webkit_content_editor_can_paste (EWebKitContentEditor *wk_editor)
+{
+       return wk_editor->priv->can_paste;
+}
+
+static void
+webkit_content_editor_can_cut_cb (WebKitWebView *view,
+                                  GAsyncResult *result,
+                                  EWebKitContentEditor *wk_editor)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (view, result, NULL);
+
+       if (wk_editor->priv->can_cut != value) {
+               wk_editor->priv->can_cut = value;
+               g_object_notify (G_OBJECT (wk_editor), "can-cut");
+       }
+}
+
+static gboolean
+webkit_content_editor_can_cut (EWebKitContentEditor *wk_editor)
+{
+       return wk_editor->priv->can_cut;
+}
+
+static void
+webkit_content_editor_can_copy_cb (WebKitWebView *view,
+                                   GAsyncResult *result,
+                                   EWebKitContentEditor *wk_editor)
+{
+       gboolean value;
+
+       value = webkit_web_view_can_execute_editing_command_finish (view, result, NULL);
+
+       if (wk_editor->priv->can_copy != value) {
+               wk_editor->priv->can_copy = value;
+               /* This means that we have an active selection thus the primary
+                * clipboard content is from composer. */
+               if (value)
+                       wk_editor->priv->copy_paste_primary_in_view = TRUE;
+               /* FIXME notify web extension about pasting content from itself */
+               g_object_notify (G_OBJECT (wk_editor), "can-copy");
+       }
+}
+
+static gboolean
+webkit_content_editor_can_copy (EWebKitContentEditor *wk_editor)
+{
+       return wk_editor->priv->can_copy;
+}
+
+static gboolean
+webkit_content_editor_get_changed (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->changed;
+}
+
+static void
+webkit_content_editor_set_changed (EContentEditor *editor,
+                                   gboolean changed)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->changed == changed)
+               return;
+
+       wk_editor->priv->changed = changed;
+
+       g_object_notify (G_OBJECT (wk_editor), "changed");
+}
+
+static void
+web_extension_content_changed_cb (GDBusConnection *connection,
+                                  const gchar *sender_name,
+                                  const gchar *object_path,
+                                  const gchar *interface_name,
+                                  const gchar *signal_name,
+                                  GVariant *parameters,
+                                  EWebKitContentEditor *wk_editor)
+{
+       if (g_strcmp0 (signal_name, "ContentChanged") != 0)
+               return;
+
+       webkit_content_editor_set_changed (E_CONTENT_EDITOR (wk_editor), TRUE);
+}
+
+static void
+web_extension_selection_changed_cb (GDBusConnection *connection,
+                                    const gchar *sender_name,
+                                    const gchar *object_path,
+                                    const gchar *interface_name,
+                                    const gchar *signal_name,
+                                    GVariant *parameters,
+                                    EWebKitContentEditor *wk_editor)
+{
+       gchar *font_color = NULL;
+
+       if (g_strcmp0 (signal_name, "SelectionChanged") != 0)
+               return;
+
+       if (!parameters)
+               return;
+
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (wk_editor),
+               WEBKIT_EDITING_COMMAND_COPY,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) webkit_content_editor_can_copy_cb,
+               wk_editor);
+
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (wk_editor),
+               WEBKIT_EDITING_COMMAND_CUT,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) webkit_content_editor_can_cut_cb,
+               wk_editor);
+
+       webkit_web_view_can_execute_editing_command (
+               WEBKIT_WEB_VIEW (wk_editor),
+               WEBKIT_EDITING_COMMAND_PASTE,
+               NULL, /* cancellable */
+               (GAsyncReadyCallback) webkit_content_editor_can_paste_cb,
+               wk_editor);
+
+       g_object_freeze_notify (G_OBJECT (wk_editor));
+
+       g_variant_get (
+               parameters,
+               "(iibbbbbbbbbis)",
+               &wk_editor->priv->alignment,
+               &wk_editor->priv->block_format,
+               &wk_editor->priv->is_indented,
+               &wk_editor->priv->is_bold,
+               &wk_editor->priv->is_italic,
+               &wk_editor->priv->is_underline,
+               &wk_editor->priv->is_strikethrough,
+               &wk_editor->priv->is_monospaced,
+               &wk_editor->priv->is_subscript,
+               &wk_editor->priv->is_superscript,
+               &wk_editor->priv->is_underline,
+               &wk_editor->priv->font_size,
+               &font_color);
+
+
+       if (wk_editor->priv->html_mode) {
+               GdkRGBA color;
+
+               if (font_color && *font_color && gdk_rgba_parse (&color, font_color)) {
+                       if (wk_editor->priv->font_color)
+                               gdk_rgba_free (wk_editor->priv->font_color);
+                       wk_editor->priv->font_color = gdk_rgba_copy (&color);
+               }
+       }
+       g_free (font_color);
+
+       g_object_notify (G_OBJECT (wk_editor), "alignment");
+       g_object_notify (G_OBJECT (wk_editor), "block-format");
+       g_object_notify (G_OBJECT (wk_editor), "indented");
+
+       if (wk_editor->priv->html_mode) {
+//             g_object_notify (G_OBJECT (wk_editor), "background-color");
+               g_object_notify (G_OBJECT (wk_editor), "bold");
+//             g_object_notify (G_OBJECT (wk_editor), "font-name");
+               g_object_notify (G_OBJECT (wk_editor), "font-size");
+               g_object_notify (G_OBJECT (wk_editor), "font-color");
+               g_object_notify (G_OBJECT (wk_editor), "italic");
+               g_object_notify (G_OBJECT (wk_editor), "monospaced");
+               g_object_notify (G_OBJECT (wk_editor), "strikethrough");
+               g_object_notify (G_OBJECT (wk_editor), "subscript");
+               g_object_notify (G_OBJECT (wk_editor), "superscript");
+               g_object_notify (G_OBJECT (wk_editor), "underline");
+       }
+
+       g_object_thaw_notify (G_OBJECT (wk_editor));
+}
+
+static void
+dispatch_pending_operations (EWebKitContentEditor *wk_editor)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (wk_editor->priv->webkit_load_event != WEBKIT_LOAD_FINISHED)
+               return;
+
+       /* Dispatch queued operations - as we are using this just for load
+        * operations load just the latest request and throw away the rest. */
+       if (wk_editor->priv->post_reload_operations &&
+           !g_queue_is_empty (wk_editor->priv->post_reload_operations)) {
+
+               PostReloadOperation *op;
+
+               op = g_queue_pop_head (wk_editor->priv->post_reload_operations);
+
+               op->func (wk_editor, op->data, op->flags);
+
+               if (op->data_free_func)
+                       op->data_free_func (op->data);
+               g_free (op);
+
+               while ((op = g_queue_pop_head (wk_editor->priv->post_reload_operations))) {
+                       if (op->data_free_func)
+                               op->data_free_func (op->data);
+                       g_free (op);
+               }
+
+               g_queue_clear (wk_editor->priv->post_reload_operations);
+       }
+}
+
+static void
+web_extension_proxy_created_cb (GDBusProxy *proxy,
+                                GAsyncResult *result,
+                                EWebKitContentEditor *wk_editor)
+{
+       GError *error = NULL;
+
+       wk_editor->priv->web_extension = g_dbus_proxy_new_finish (result, &error);
+       if (!wk_editor->priv->web_extension) {
+               g_warning ("Error creating web extension proxy: %s\n", error->message);
+               g_error_free (error);
+
+               return;
+       }
+
+       if (wk_editor->priv->web_extension_selection_changed_cb_id == 0) {
+               wk_editor->priv->web_extension_selection_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,
+                               "SelectionChanged",
+                               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+                               NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE,
+                               (GDBusSignalCallback) web_extension_selection_changed_cb,
+                               wk_editor,
+                               NULL);
+       }
+
+       if (wk_editor->priv->web_extension_content_changed_cb_id == 0) {
+               wk_editor->priv->web_extension_content_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,
+                               "ContentChanged",
+                               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+                               NULL,
+                               G_DBUS_SIGNAL_FLAGS_NONE,
+                               (GDBusSignalCallback) web_extension_content_changed_cb,
+                               wk_editor,
+                               NULL);
+       }
+
+       dispatch_pending_operations (wk_editor);
+
+       if (wk_editor->priv->emit_load_finished_when_extension_is_ready) {
+               g_signal_emit_by_name (E_CONTENT_EDITOR (wk_editor), "load-finished", 0);
+               wk_editor->priv->emit_load_finished_when_extension_is_ready = FALSE;
+       }
+}
+
+static void
+web_extension_appeared_cb (GDBusConnection *connection,
+                           const gchar *name,
+                           const gchar *name_owner,
+                           EWebKitContentEditor *wk_editor)
+{
+       g_dbus_proxy_new (
+               connection,
+               G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
+               G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+               NULL,
+               name,
+               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+               NULL,
+               (GAsyncReadyCallback) web_extension_proxy_created_cb,
+               wk_editor);
+}
+
+static void
+web_extension_vanished_cb (GDBusConnection *connection,
+                           const gchar *name,
+                           EWebKitContentEditor *wk_editor)
+{
+       g_clear_object (&wk_editor->priv->web_extension);
+}
+
+static void
+webkit_content_editor_watch_web_extension (EWebKitContentEditor *wk_editor)
+{
+       wk_editor->priv->web_extension_watch_name_id =
+               g_bus_watch_name (
+                       G_BUS_TYPE_SESSION,
+                       E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
+                       G_BUS_NAME_WATCHER_FLAGS_NONE,
+                       (GBusNameAppearedCallback) web_extension_appeared_cb,
+                       (GBusNameVanishedCallback) web_extension_vanished_cb,
+                       wk_editor,
+                       NULL);
+}
+
+static guint64
+current_page_id (EWebKitContentEditor *wk_editor)
+{
+       return webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (wk_editor));
+}
+
+static void
+webkit_content_editor_call_simple_extension_function (EWebKitContentEditor *wk_editor,
+                                                      const gchar *function)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               function,
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static GVariant *
+webkit_content_editor_get_element_attribute (EWebKitContentEditor *wk_editor,
+                                             const gchar *selector,
+                                             const gchar *attribute)
+{
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       return g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ElementGetAttributeBySelector",
+               g_variant_new ("(tss)", current_page_id (wk_editor), selector, attribute),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_set_element_attribute (EWebKitContentEditor *wk_editor,
+                                             const gchar *selector,
+                                             const gchar *attribute,
+                                             const gchar *value)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ElementSetAttributeBySelector",
+               g_variant_new (
+                       "(tsss)", current_page_id (wk_editor), selector, attribute, value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_remove_element_attribute (EWebKitContentEditor *wk_editor,
+                                                const gchar *selector,
+                                                const gchar *attribute)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ElementRemoveAttributeBySelector",
+               g_variant_new ("(tss)", current_page_id (wk_editor), selector, attribute),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_set_format_boolean (EWebKitContentEditor *wk_editor,
+                                          const gchar *format_dom_function,
+                                          gboolean format_value)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               format_dom_function,
+               g_variant_new ("(tb)", current_page_id (wk_editor), format_value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_set_format_int (EWebKitContentEditor *wk_editor,
+                                      const gchar *format_dom_function,
+                                      gint32 format_value)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               format_dom_function,
+               g_variant_new ("(ti)", current_page_id (wk_editor), format_value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static EContentEditorFindController *
+webkit_content_editor_get_find_controller (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->find_controller;
+}
+
+static void
+webkit_content_editor_set_format_string (EWebKitContentEditor *wk_editor,
+                                         const gchar *format_name,
+                                         const gchar *format_dom_function,
+                                         const gchar *format_value)
+{
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       webkit_content_editor_set_changed (E_CONTENT_EDITOR (wk_editor), TRUE);
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               format_dom_function,
+               g_variant_new ("(ts)", current_page_id (wk_editor), format_value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       g_object_notify (G_OBJECT (wk_editor), format_name);
+}
+
+static void
+webkit_content_editor_queue_post_reload_operation (EWebKitContentEditor *wk_editor,
+                                                   PostReloadOperationFunc func,
+                                                   gpointer data,
+                                                   GDestroyNotify data_free_func,
+                                                  EContentEditorInsertContentFlags flags)
+{
+       PostReloadOperation *op;
+
+       g_return_if_fail (func != NULL);
+
+       if (wk_editor->priv->post_reload_operations == NULL)
+               wk_editor->priv->post_reload_operations = g_queue_new ();
+
+       op = g_new0 (PostReloadOperation, 1);
+       op->func = func;
+       op->flags = flags;
+       op->data = data;
+       op->data_free_func = data_free_func;
+
+       g_queue_push_head (wk_editor->priv->post_reload_operations, op);
+}
+
+static void
+webkit_content_editor_update_fonts (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean mark_citations, use_custom_font;
+       gchar *font, *aa = NULL, *citation_color;
+       const gchar *styles[] = { "normal", "oblique", "italic" };
+       const gchar *smoothing = NULL;
+       GString *stylesheet;
+       PangoFontDescription *min_size, *ms, *vw;
+       WebKitSettings *settings;
+       WebKitUserContentManager *manager;
+       WebKitUserStyleSheet *style_sheet;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       use_custom_font = g_settings_get_boolean (
+               wk_editor->priv->mail_settings, "use-custom-font");
+
+       if (use_custom_font) {
+               font = g_settings_get_string (
+                       wk_editor->priv->mail_settings, "monospace-font");
+               ms = pango_font_description_from_string (font ? font : "monospace 10");
+               g_free (font);
+       } else {
+               font = g_settings_get_string (
+                       wk_editor->priv->font_settings, "monospace-font-name");
+               ms = pango_font_description_from_string (font ? font : "monospace 10");
+               g_free (font);
+       }
+
+       if (wk_editor->priv->html_mode) {
+               if (use_custom_font) {
+                       font = g_settings_get_string (
+                               wk_editor->priv->mail_settings, "variable-width-font");
+                       vw = pango_font_description_from_string (font ? font : "serif 10");
+                       g_free (font);
+               } else {
+                       font = g_settings_get_string (
+                               wk_editor->priv->font_settings, "font-name");
+                       vw = pango_font_description_from_string (font ? font : "serif 10");
+                       g_free (font);
+               }
+       } else {
+               /* When in plain text mode, force monospace font */
+               vw = pango_font_description_copy (ms);
+       }
+
+       stylesheet = g_string_new ("");
+       g_string_append_printf (
+               stylesheet,
+               "body {\n"
+               "  font-family: '%s';\n"
+               "  font-size: %dpt;\n"
+               "  font-weight: %d;\n"
+               "  font-style: %s;\n"
+               " -webkit-line-break: after-white-space;\n",
+               pango_font_description_get_family (vw),
+               pango_font_description_get_size (vw) / PANGO_SCALE,
+               pango_font_description_get_weight (vw),
+               styles[pango_font_description_get_style (vw)]);
+
+       if (wk_editor->priv->aliasing_settings != NULL)
+               aa = g_settings_get_string (
+                       wk_editor->priv->aliasing_settings, "antialiasing");
+
+       if (g_strcmp0 (aa, "none") == 0)
+               smoothing = "none";
+       else if (g_strcmp0 (aa, "grayscale") == 0)
+               smoothing = "antialiased";
+       else if (g_strcmp0 (aa, "rgba") == 0)
+               smoothing = "subpixel-antialiased";
+
+       if (smoothing != NULL)
+               g_string_append_printf (
+                       stylesheet,
+                       " -webkit-font-smoothing: %s;\n",
+                       smoothing);
+
+       g_free (aa);
+
+       g_string_append (stylesheet, "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               "pre,code,.pre {\n"
+               "  font-family: '%s';\n"
+               "  font-size: %dpt;\n"
+               "  font-weight: %d;\n"
+               "  font-style: %s;\n"
+               "}",
+               pango_font_description_get_family (ms),
+               pango_font_description_get_size (ms) / PANGO_SCALE,
+               pango_font_description_get_weight (ms),
+               styles[pango_font_description_get_style (ms)]);
+
+       /* See bug #689777 for details */
+       g_string_append (
+               stylesheet,
+               "p,pre,code,address {\n"
+               "  margin: 0;\n"
+               "}\n"
+               "h1,h2,h3,h4,h5,h6 {\n"
+               "  margin-top: 0.2em;\n"
+               "  margin-bottom: 0.2em;\n"
+               "}\n");
+
+       /* When inserting a table into contenteditable element the width of the
+        * cells is nearly zero and the td { min-height } doesn't work so put
+        * unicode zero width space before each cell. */
+       g_string_append (
+               stylesheet,
+               "td:before {\n"
+               " content: \"\xe2\x80\x8b\";"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "img "
+               "{\n"
+               "  height: inherit; \n"
+               "  width: inherit; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "span.-x-evo-resizable-wrapper:hover "
+               "{\n"
+               "  outline: 1px dashed red; \n"
+               "  resize: both; \n"
+               "  overflow: hidden; \n"
+               "  display: inline-block; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "td:hover "
+               "{\n"
+               "  outline: 1px dotted red;\n"
+               "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-plaintext-table "
+               "{\n"
+               "  border-collapse: collapse;\n"
+               "  width: %dch;\n"
+               "}\n",
+               g_settings_get_int (wk_editor->priv->mail_settings, "composer-word-wrap-length"));
+
+       g_string_append (
+               stylesheet,
+               ".-x-evo-plaintext-table td"
+               "{\n"
+               "  vertical-align: top;\n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "td > *"
+               "{\n"
+               "  display : inline-block;\n"
+               "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               "ul[data-evo-plain-text]"
+               "{\n"
+               "  list-style: outside none;\n"
+               "  -webkit-padding-start: %dch; \n"
+               "}\n", SPACES_PER_LIST_LEVEL);
+
+       g_string_append_printf (
+               stylesheet,
+               "ul[data-evo-plain-text] > li"
+               "{\n"
+               "  list-style-position: outside;\n"
+               "  text-indent: -%dch;\n"
+               "}\n", SPACES_PER_LIST_LEVEL - 1);
+
+       g_string_append (
+               stylesheet,
+               "ul[data-evo-plain-text] > li::before "
+               "{\n"
+               "  content: \"*"UNICODE_NBSP"\";\n"
+               "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               "ul[data-evo-plain-text].-x-evo-indented "
+               "{\n"
+               "  -webkit-padding-start: %dch; \n"
+               "}\n", SPACES_PER_LIST_LEVEL);
+
+       g_string_append (
+               stylesheet,
+               "ul:not([data-evo-plain-text]) > li.-x-evo-align-center,ol > li.-x-evo-align-center"
+               "{\n"
+               "  list-style-position: inside;\n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "ul:not([data-evo-plain-text]) > li.-x-evo-align-right, ol > li.-x-evo-align-right"
+               "{\n"
+               "  list-style-position: inside;\n"
+               "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               "ol"
+               "{\n"
+               "  -webkit-padding-start: %dch; \n"
+               "}\n", SPACES_ORDERED_LIST_FIRST_LEVEL);
+
+       g_string_append_printf (
+               stylesheet,
+               "ol.-x-evo-indented"
+               "{\n"
+               "  -webkit-padding-start: %dch; \n"
+               "}\n", SPACES_PER_LIST_LEVEL);
+
+       g_string_append (
+               stylesheet,
+               ".-x-evo-align-left "
+               "{\n"
+               "  text-align: left; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               ".-x-evo-align-center "
+               "{\n"
+               "  text-align: center; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               ".-x-evo-align-right "
+               "{\n"
+               "  text-align: right; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "ol,ul "
+               "{\n"
+               "  -webkit-margin-before: 0em; \n"
+               "  -webkit-margin-after: 0em; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "blockquote "
+               "{\n"
+               "  -webkit-margin-before: 0em; \n"
+               "  -webkit-margin-after: 0em; \n"
+               "}\n");
+
+       g_string_append (
+               stylesheet,
+               "a "
+               "{\n"
+               "  word-wrap: break-word; \n"
+               "  word-break: break-all; \n"
+               "}\n");
+
+       citation_color = g_settings_get_string (
+               wk_editor->priv->mail_settings, "citation-color");
+       mark_citations = g_settings_get_boolean (
+               wk_editor->priv->mail_settings, "mark-citations");
+
+       g_string_append (
+               stylesheet,
+               "blockquote[type=cite] "
+               "{\n"
+               "  padding: 0.0ex 0ex;\n"
+               "  margin: 0ex;\n"
+               "  -webkit-margin-start: 0em; \n"
+               "  -webkit-margin-end : 0em; \n");
+
+       if (mark_citations && citation_color)
+               g_string_append_printf (
+                       stylesheet,
+                       "  color: %s !important; \n",
+                       citation_color);
+
+       g_free (citation_color);
+       citation_color = NULL;
+
+       g_string_append (stylesheet, "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-quote-character "
+               "{\n"
+               "  color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (1));
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character"
+               "{\n"
+               "  color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (2));
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character"
+               "{\n"
+               "  color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (3));
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character"
+               "{\n"
+               "  color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (4));
+
+       g_string_append_printf (
+               stylesheet,
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character+"
+               ".-x-evo-quote-character"
+               "{\n"
+               "  color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (5));
+
+       g_string_append (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  padding: 0ch 1ch 0ch 1ch;\n"
+               "  margin: 0ch;\n"
+               "  border-width: 0px 2px 0px 2px;\n"
+               "  border-style: none solid none solid;\n"
+               "  border-radius: 2px;\n"
+               "}\n");
+
+       g_string_append_printf (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  border-color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (1));
+
+       g_string_append_printf (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  border-color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (2));
+
+       g_string_append_printf (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  border-color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (3));
+
+       g_string_append_printf (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  border-color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (4));
+
+       g_string_append_printf (
+               stylesheet,
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "blockquote[type=cite]:not(.-x-evo-plaintext-quoted) "
+               "{\n"
+               "  border-color: %s;\n"
+               "}\n",
+               e_web_view_get_citation_color_for_level (5));
+
+       if (pango_font_description_get_size (ms) < pango_font_description_get_size (vw) || 
!wk_editor->priv->html_mode)
+               min_size = ms;
+       else
+               min_size = vw;
+
+       settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (wk_editor));
+       g_object_set (
+               G_OBJECT (settings),
+               "default-font-size",
+               e_util_normalize_font_size (
+                       GTK_WIDGET (wk_editor), pango_font_description_get_size (vw) / PANGO_SCALE),
+               "default-font-family",
+               pango_font_description_get_family (vw),
+               "monospace-font-family",
+               pango_font_description_get_family (ms),
+               "default-monospace-font-size", pango_font_description_get_size (ms) / PANGO_SCALE,
+               "minimum-font-size", pango_font_description_get_size (min_size) / PANGO_SCALE,
+               NULL);
+
+       manager = webkit_web_view_get_user_content_manager (WEBKIT_WEB_VIEW (wk_editor));
+       webkit_user_content_manager_remove_all_style_sheets (manager);
+
+       style_sheet = webkit_user_style_sheet_new (
+               stylesheet->str,
+               WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
+               WEBKIT_USER_STYLE_LEVEL_USER,
+               NULL,
+               NULL);
+
+       webkit_user_content_manager_add_style_sheet (manager, style_sheet);
+
+       g_free (wk_editor->priv->current_user_stylesheet);
+       wk_editor->priv->current_user_stylesheet = g_string_free (stylesheet, FALSE);
+
+       webkit_user_style_sheet_unref (style_sheet);
+
+       pango_font_description_free (ms);
+       pango_font_description_free (vw);
+}
+
+static gboolean
+webkit_content_editor_get_html_mode (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->html_mode;
+}
+
+static gboolean
+show_lose_formatting_dialog (EWebKitContentEditor *wk_editor)
+{
+       gboolean lose;
+       GtkWidget *toplevel;
+       GtkWindow *parent = NULL;
+
+       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (wk_editor));
+
+       if (GTK_IS_WINDOW (toplevel))
+               parent = GTK_WINDOW (toplevel);
+
+       lose = e_util_prompt_user (
+               parent, "org.gnome.evolution.mail", "prompt-on-composer-mode-switch",
+               "mail-composer:prompt-composer-mode-switch", NULL);
+
+       if (!lose) {
+               /* Nothing has changed, but notify anyway */
+               g_object_notify (G_OBJECT (wk_editor), "html-mode");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void
+webkit_content_editor_set_html_mode (EContentEditor *editor,
+                                     gboolean html_mode)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean convert = FALSE;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (html_mode == wk_editor->priv->html_mode)
+               return;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMCheckIfConversionNeeded",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &convert);
+               g_variant_unref (result);
+       }
+
+       /* If toggling from HTML to the plain text mode, ask the user first if
+        * he wants to convert the content. */
+       if (convert && wk_editor->priv->html_mode && !html_mode)
+               if (!show_lose_formatting_dialog (wk_editor))
+                       return;
+
+       wk_editor->priv->html_mode = html_mode;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "SetEditorHTMLMode",
+               g_variant_new ("(tbb)", current_page_id (wk_editor), html_mode, convert),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       /* Update fonts - in plain text we only want monospaced */
+       webkit_content_editor_update_fonts (editor);
+
+       g_object_notify (G_OBJECT (wk_editor), "html-mode");
+}
+
+static void
+set_convert_in_situ (EWebKitContentEditor *wk_editor,
+                     gboolean value)
+{
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "SetConvertInSitu",
+               g_variant_new ("(tb)", current_page_id (wk_editor), value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+}
+
+static void
+webkit_content_editor_insert_content (EContentEditor *editor,
+                                      const gchar *content,
+                                      EContentEditorInsertContentFlags flags)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       /* It can happen that the view is not ready yet (it is in the middle of
+        * another load operation) so we have to queue the current operation and
+        * redo it again when the view is ready. This was happening when loading
+        * the stuff in EMailSignatureEditor. */
+       if (wk_editor->priv->webkit_load_event != WEBKIT_LOAD_FINISHED ||
+           wk_editor->priv->reload_in_progress) {
+               webkit_content_editor_queue_post_reload_operation (
+                       wk_editor,
+                       (PostReloadOperationFunc) webkit_content_editor_insert_content,
+                       g_strdup (content),
+                       g_free,
+                       flags);
+               return;
+       }
+
+       if (!wk_editor->priv->web_extension) {
+               /* If the operation needs a web extension and it is not ready yet
+                * we need to schedule the current operation again a dispatch it
+                * when the extension is ready */
+               if (!((flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
+                     (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML) &&
+                     (wk_editor->priv->content_flags & E_CONTENT_EDITOR_MESSAGE_DRAFT))) {
+                       webkit_content_editor_queue_post_reload_operation (
+                               wk_editor,
+                               (PostReloadOperationFunc) webkit_content_editor_insert_content,
+                               g_strdup (content),
+                               g_free,
+                               flags);
+                       return;
+               }
+       }
+
+       wk_editor->priv->reload_in_progress = TRUE;
+
+       /* FIXME TOTO JE ASI BLBE.. */
+       if ((flags & E_CONTENT_EDITOR_INSERT_CONVERT) &&
+           (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML) &&
+           !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {
+               // e_html_editor_view_convert_and_insert_plain_text
+               // e_html_editor_view_convert_and_insert_html_to_plain_text
+               // e_html_editor_view_insert_text
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMConvertAndInsertHTMLIntoSelection",
+                       g_variant_new (
+                               "(tsb)",
+                               current_page_id (wk_editor),
+                               content,
+                               (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML)),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       } else if ((flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
+                  (flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML)) {
+               if (wk_editor->priv->content_flags & E_CONTENT_EDITOR_MESSAGE_DRAFT) {
+                       webkit_web_view_load_html (WEBKIT_WEB_VIEW (wk_editor), content, "file://");
+                       return;
+               }
+
+               if ((wk_editor->priv->content_flags & E_CONTENT_EDITOR_MESSAGE_DRAFT) &&
+                   !(wk_editor->priv->html_mode)) {
+                       if (content && *content)
+                               set_convert_in_situ (wk_editor, TRUE);
+                       webkit_web_view_load_html (WEBKIT_WEB_VIEW (wk_editor), content, "file://");
+                       return;
+               }
+
+               /* Only convert messages that are in HTML */
+               if (!(wk_editor->priv->html_mode)) {
+                       if (strstr (content, "<!-- text/html -->")) {
+                               if (!show_lose_formatting_dialog (wk_editor)) {
+                                       webkit_content_editor_set_html_mode (editor, TRUE);
+                                       webkit_web_view_load_html (
+                                               WEBKIT_WEB_VIEW (wk_editor), content, "file://");
+                                       return;
+                               }
+                       }
+                       if (content && *content)
+                               set_convert_in_situ (wk_editor, TRUE);
+               }
+
+               webkit_web_view_load_html (WEBKIT_WEB_VIEW (wk_editor), content, "file://");
+       } else if ((flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
+                  (flags & E_CONTENT_EDITOR_INSERT_TEXT_PLAIN)) {
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMConvertContent",
+                       g_variant_new ("(ts)", current_page_id (wk_editor), content),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       } else if ((flags & E_CONTENT_EDITOR_INSERT_CONVERT) &&
+                   !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL) &&
+                   !(flags & E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT)) {
+               // e_html_editor_view_paste_as_text
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMConvertAndInsertHTMLIntoSelection",
+                       g_variant_new (
+                               "(tsb)", current_page_id (wk_editor), content, TRUE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       } else if ((flags & E_CONTENT_EDITOR_INSERT_QUOTE_CONTENT) &&
+                  !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {
+               // e_html_editor_view_paste_clipboard_quoted
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMQuoteAndInsertTextIntoSelection",
+                       g_variant_new (
+                               "(tsb)", current_page_id (wk_editor), content),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       } else if ((flags & E_CONTENT_EDITOR_INSERT_CONVERT) &&
+                   !(flags & E_CONTENT_EDITOR_INSERT_REPLACE_ALL)) {
+               // e_html_editor_view_insert_html
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMInsertHTML",
+                       g_variant_new (
+                               "(ts)", current_page_id (wk_editor), content),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       } else
+               g_warning ("Unsupported flags combination (%d) in (%s)", flags, G_STRFUNC);
+}
+
+static CamelMimePart *
+create_part_for_inline_image_from_element_data (const gchar *element_src,
+                                                const gchar *name,
+                                                const gchar *id)
+{
+       CamelStream *stream;
+       CamelDataWrapper *wrapper;
+       CamelMimePart *part = NULL;
+       gsize decoded_size;
+       gssize size;
+       gchar *mime_type = NULL;
+       const gchar *base64_encoded_data;
+       guchar *base64_decoded_data = NULL;
+
+       base64_encoded_data = strstr (element_src, ";base64,");
+       if (!base64_encoded_data)
+               goto out;
+
+       mime_type = g_strndup (
+               element_src + 5,
+               base64_encoded_data - (strstr (element_src, "data:") + 5));
+
+       /* Move to actual data */
+       base64_encoded_data += 8;
+
+       base64_decoded_data = g_base64_decode (base64_encoded_data, &decoded_size);
+
+       stream = camel_stream_mem_new ();
+       size = camel_stream_write (
+               stream, (gchar *) base64_decoded_data, decoded_size, NULL, NULL);
+
+       if (size == -1)
+               goto out;
+
+       wrapper = camel_data_wrapper_new ();
+       camel_data_wrapper_construct_from_stream_sync (
+               wrapper, stream, NULL, NULL);
+       g_object_unref (stream);
+
+       camel_data_wrapper_set_mime_type (wrapper, mime_type);
+
+       part = camel_mime_part_new ();
+       camel_medium_set_content (CAMEL_MEDIUM (part), wrapper);
+       g_object_unref (wrapper);
+
+       camel_mime_part_set_content_id (part, id);
+       camel_mime_part_set_filename (part, name);
+       camel_mime_part_set_disposition (part, "inline");
+       camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64);
+out:
+       g_free (mime_type);
+       g_free (base64_decoded_data);
+
+       return part;
+}
+
+static GList *
+webkit_content_editor_get_parts_for_inline_images (GVariant *images)
+{
+       const gchar *element_src, *name, *id;
+       GVariantIter *iter;
+       GList *parts = NULL;
+
+       g_variant_get (images, "asss", &iter);
+       while (g_variant_iter_loop (iter, "&s&s&s", &element_src, &name, &id)) {
+               CamelMimePart *part;
+
+               part = create_part_for_inline_image_from_element_data (
+                       element_src, name, id);
+               parts = g_list_append (parts, part);
+       }
+       g_variant_iter_free (iter);
+
+       return parts;
+}
+
+static gchar *
+webkit_content_editor_get_content (EContentEditor *editor,
+                                   EContentEditorGetContentFlags flags,
+                                   EContentEditorInlineImages **inline_images)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return g_strdup ("");
+
+       if ((flags & E_CONTENT_EDITOR_GET_TEXT_HTML) &&
+           !(flags & E_CONTENT_EDITOR_GET_PROCESSED) &&
+            !(flags & E_CONTENT_EDITOR_GET_BODY))
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "DOMEmbedStyleSheet",
+                       g_variant_new (
+                               "(ts)",
+                               current_page_id (wk_editor),
+                               wk_editor->priv->current_user_stylesheet),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMGetContent",
+               g_variant_new (
+                       "(tsi)",
+                       current_page_id (wk_editor),
+                       inline_images ?  (*inline_images)->from_domain : "",
+                       (gint32) flags),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if ((flags & E_CONTENT_EDITOR_GET_TEXT_HTML) &&
+           !(flags & E_CONTENT_EDITOR_GET_PROCESSED) &&
+            !(flags & E_CONTENT_EDITOR_GET_BODY))
+               webkit_content_editor_call_simple_extension_function (
+                       wk_editor, "DOMRemoveEmbeddedStyleSheet");
+
+       if (result) {
+               GVariant *images;
+               gchar *value;
+
+               g_variant_get (result, "(sv)", &value, &images);
+               if (inline_images)
+                       (*inline_images)->images = webkit_content_editor_get_parts_for_inline_images (images);
+               g_variant_unref (result);
+
+               return value;
+       }
+
+       return g_strdup ("");
+}
+
+static gboolean
+webkit_content_editor_can_undo (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->can_undo;
+}
+
+static void
+webkit_content_editor_undo (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (wk_editor, "DOMUndo");
+}
+
+static gboolean
+webkit_content_editor_can_redo (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->can_redo;
+}
+
+static void
+webkit_content_editor_redo (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (wk_editor, "DOMRedo");
+}
+
+static void
+webkit_content_editor_move_caret_on_coordinates (EContentEditor *editor,
+                                                 gint x,
+                                                 gint y,
+                                                 gboolean cancel_if_not_collapsed)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMMoveSelectionOnPoint",
+               g_variant_new (
+                       "(tiib)", current_page_id (wk_editor), x, y, cancel_if_not_collapsed),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_insert_emoticon (EContentEditor *editor,
+                                       EEmoticon *emoticon)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMInsertSmiley",
+               g_variant_new (
+                       "(ts)", current_page_id (wk_editor), e_emoticon_get_name (emoticon)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_insert_image_from_mime_part (EContentEditor *editor,
+                                                   CamelMimePart *part)
+{
+       CamelDataWrapper *dw;
+       CamelStream *stream;
+       EWebKitContentEditor *wk_editor;
+       GByteArray *byte_array;
+       gchar *src, *base64_encoded, *mime_type, *cid_uri;
+       const gchar *cid, *name;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       stream = camel_stream_mem_new ();
+       dw = camel_medium_get_content (CAMEL_MEDIUM (part));
+       g_return_if_fail (dw);
+
+       mime_type = camel_data_wrapper_get_mime_type (dw);
+       camel_data_wrapper_decode_to_stream_sync (dw, stream, NULL, NULL);
+       camel_stream_close (stream, NULL, NULL);
+
+       byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream));
+
+       if (!byte_array->data)
+               return;
+
+       base64_encoded = g_base64_encode ((const guchar *) byte_array->data, byte_array->len);
+
+       name = camel_mime_part_get_filename (part);
+       /* Insert file name before new src */
+       src = g_strconcat (name, ";data:", mime_type, ";base64,", base64_encoded, NULL);
+
+       cid = camel_mime_part_get_content_id (part);
+       if (!cid) {
+               camel_mime_part_set_content_id (part, NULL);
+               cid = camel_mime_part_get_content_id (part);
+       }
+       cid_uri = g_strdup_printf ("cid:%s", cid);
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMAddNewInlineImageIntoList",
+               g_variant_new ("(tss)", current_page_id (wk_editor), name, cid_uri, src),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       g_free (base64_encoded);
+       g_free (mime_type);
+       g_object_unref (stream);
+}
+
+static EContentEditorContentFlags
+webkit_content_editor_get_current_content_flags (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->content_flags;
+}
+
+static void
+webkit_content_editor_set_current_content_flags (EContentEditor *editor,
+                                                 EContentEditorContentFlags flags)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       wk_editor->priv->content_flags = flags;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "SetCurrentContentFlags",
+               g_variant_new ("(ti)", current_page_id (wk_editor), (gint32) flags),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_select_all (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_web_view_execute_editing_command (
+               WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_SELECT_ALL);
+}
+
+static void
+webkit_content_editor_show_inspector (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       WebKitWebInspector *inspector;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       inspector = webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (wk_editor));
+
+       webkit_web_inspector_show (inspector);
+}
+
+static void
+webkit_content_editor_selection_wrap (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (wk_editor, "DOMSelectionWrap");
+}
+
+static gboolean
+webkit_content_editor_selection_is_indented (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_indented;
+}
+
+static void
+webkit_content_editor_selection_indent (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "DOMSelectionIndent");
+}
+
+static void
+webkit_content_editor_selection_unindent (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "DOMSelectionUnindent");
+}
+
+static void
+webkit_content_editor_cut (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean handled = FALSE;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorActionsSaveHistoryForCut");
+
+       g_signal_emit_by_name (editor, "cut-clipboard", editor, &handled);
+
+       if (!handled)
+               webkit_web_view_execute_editing_command (
+                       WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_CUT);
+}
+
+static void
+webkit_content_editor_copy (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean handled = FALSE;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       g_signal_emit_by_name (editor, "copy-clipboard", editor, &handled);
+
+       if (!handled)
+               webkit_web_view_execute_editing_command (
+                       WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_COPY);
+}
+
+static void
+webkit_content_editor_paste (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean handled = FALSE;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       g_signal_emit_by_name (editor, "paste-clipboard", editor, &handled);
+
+       if (!handled)
+               webkit_web_view_execute_editing_command (
+                       WEBKIT_WEB_VIEW (wk_editor), WEBKIT_EDITING_COMMAND_PASTE);
+
+       /* FIXME
+       e_html_editor_view_force_spell_check (view) */
+}
+
+static gboolean
+webkit_content_editor_paste_prefer_text_html (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->pasting_primary_clipboard)
+               return wk_editor->priv->copy_paste_primary_in_view;
+       else
+               return wk_editor->priv->copy_paste_clipboard_in_view;
+}
+
+static ESpellChecker *
+webkit_content_editor_get_spell_checker (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->spell_checker;
+}
+
+static gchar *
+webkit_content_editor_get_caret_word (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *ret_val = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMGetCaretWord",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(s)", &ret_val);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static void
+webkit_content_editor_set_spell_checking_languages (EContentEditor *editor,
+                                                    const gchar **languages)
+{
+       EWebKitContentEditor *wk_editor;
+       WebKitWebContext *web_context;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       web_context = webkit_web_view_get_context (WEBKIT_WEB_VIEW (wk_editor));
+       webkit_web_context_set_spell_checking_languages (web_context, (const gchar * const *) languages);
+}
+
+static void
+webkit_content_editor_set_spell_check (EContentEditor *editor,
+                                       gboolean enable)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, enable ? "DOMForceSpellCheck" : "DOMTurnSpellCheckOff");
+}
+
+static gboolean
+webkit_content_editor_get_spell_check (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return g_settings_get_boolean (
+               wk_editor->priv->mail_settings, "composer-inline-spelling");
+}
+
+static gboolean
+webkit_content_editor_is_editable (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return webkit_web_view_is_editable (WEBKIT_WEB_VIEW (wk_editor));
+}
+
+static void
+webkit_content_editor_set_editable (EContentEditor *editor,
+                                    gboolean editable)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return webkit_web_view_set_editable (WEBKIT_WEB_VIEW (wk_editor), editable);
+}
+
+static gchar *
+webkit_content_editor_get_current_signature_uid (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *ret_val= NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMGetActiveSignatureUid",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(s)", &ret_val);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static gboolean
+webkit_content_editor_is_ready (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return !webkit_web_view_is_loading (WEBKIT_WEB_VIEW (wk_editor)) && wk_editor->priv->web_extension;
+}
+
+static char *
+webkit_content_editor_insert_signature (EContentEditor *editor,
+                                        const gchar *content,
+                                        gboolean is_html,
+                                        const gchar *signature_id,
+                                        gboolean *set_signature_from_message,
+                                        gboolean *check_if_signature_is_changed,
+                                        gboolean *ignore_next_signature_change)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *ret_val = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMInsertSignature",
+               g_variant_new (
+                       "(tsbsbbb)",
+                       current_page_id (wk_editor),
+                       content,
+                       is_html,
+                       signature_id,
+                       set_signature_from_message,
+                       check_if_signature_is_changed,
+                       ignore_next_signature_change),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (
+                       result,
+                       "(sbbb)",
+                       &ret_val,
+                       set_signature_from_message,
+                       check_if_signature_is_changed,
+                       ignore_next_signature_change);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static guint
+webkit_content_editor_get_caret_position (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       guint ret_val = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMGetCaretPosition",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               ret_val = g_variant_get_uint32 (result);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static guint
+webkit_content_editor_get_caret_offset (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       guint ret_val = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMGetCaretOffset",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               ret_val = g_variant_get_uint32 (result);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static void
+webkit_content_editor_clear_undo_redo_history (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMClearUndoRedoHistory",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gboolean
+webkit_content_editor_selection_has_text (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean ret_val;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "DOMSelectionHasText",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &ret_val);
+               g_variant_unref (result);
+       }
+
+       return ret_val;
+}
+
+static void
+webkit_content_editor_replace_caret_word (EContentEditor *editor,
+                                          const gchar *replacement)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMReplaceCaretWord",
+               g_variant_new ("(ts)", current_page_id (wk_editor), replacement),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_selection_replace (EContentEditor *editor,
+                                         const gchar *replacement)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMSelectionReplace",
+               g_variant_new ("(ts)", current_page_id (wk_editor), replacement),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_selection_save (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "DOMSelectionSave");
+}
+
+static void
+webkit_content_editor_selection_restore (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "DOMSelectionRestore");
+}
+
+static void
+webkit_content_editor_delete_cell_contents (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogDeleteCellContents");
+}
+
+static void
+webkit_content_editor_delete_column (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogDeleteColumn");
+}
+
+static void
+webkit_content_editor_delete_row (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogDeleteRow");
+}
+
+static void
+webkit_content_editor_delete_table (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogDeleteTable");
+}
+
+static void
+webkit_content_editor_insert_column_after (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogInsertColumnAfter");
+}
+
+static void
+webkit_content_editor_insert_column_before (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogInsertColumnBefore");
+}
+
+
+static void
+webkit_content_editor_insert_row_above (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogInsertRowAbove");
+}
+
+static void
+webkit_content_editor_insert_row_below (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorDialogInsertRowBelow");
+}
+
+static gboolean
+webkit_content_editor_on_h_rule_dialog_open (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean value = FALSE;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorHRuleDialogFindHRule",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_on_h_rule_dialog_close (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorHRuleDialogSaveHistoryOnExit");
+}
+
+static void
+webkit_content_editor_h_rule_set_align (EContentEditor *editor,
+                                        const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "align", value);
+}
+
+static gchar *
+webkit_content_editor_h_rule_get_align (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "align");
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_h_rule_set_size (EContentEditor *editor,
+                                       gint value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *size;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       size = g_strdup_printf ("%d", value);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "size", size);
+
+       g_free (size);
+}
+
+static gint
+webkit_content_editor_h_rule_get_size (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gint size = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "size");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (value && *value)
+                       size = atoi (value);
+
+               if (size == 0)
+                       size = 2;
+
+               g_variant_unref (result);
+       }
+
+       return size;
+}
+
+static void
+webkit_content_editor_h_rule_set_width (EContentEditor *editor,
+                                        gint value,
+                                        EContentEditorUnit unit)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *width;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       width = g_strdup_printf (
+               "%d%s",
+               value,
+               (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "width", width);
+
+       g_free (width);
+}
+
+static gint
+webkit_content_editor_h_rule_get_width (EContentEditor *editor,
+                                        EContentEditorUnit *unit)
+{
+       EWebKitContentEditor *wk_editor;
+       gint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-hr", "width");
+       if (result) {
+               const gchar *width;
+               g_variant_get (result, "(&s)", &width);
+               if (width && *width) {
+                       value = atoi (width);
+                       if (strstr (width, "%"))
+                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
+               }
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_h_rule_set_no_shade (EContentEditor *editor,
+                                           gboolean value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "HRElementSetNoShade",
+               g_variant_new (
+                       "(tsb)", current_page_id (wk_editor), "-x-evo-current-hr", value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gboolean
+webkit_content_editor_h_rule_get_no_shade (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean value = FALSE;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "HRElementGetNoShade",
+               g_variant_new (
+                       "(ts)", current_page_id (wk_editor), "-x-evo-current-hr"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_on_image_dialog_open (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorImageDialogMarkImage");
+}
+
+static void
+webkit_content_editor_on_image_dialog_close (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorImageDialogSaveHistoryOnExit");
+}
+
+static void
+webkit_content_editor_insert_image (EContentEditor *editor,
+                                    const gchar *image_uri)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMSelectionInsertImage",
+               g_variant_new ("(ts)", current_page_id (wk_editor), image_uri),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_replace_image_src (EWebKitContentEditor *wk_editor,
+                                         const gchar *selector,
+                                         const gchar *image_uri)
+{
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "DOMReplaceImageSrc",
+               g_variant_new ("(tss)", current_page_id (wk_editor), selector, image_uri),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_image_set_src (EContentEditor *editor,
+                                     const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_replace_image_src (
+               wk_editor, "img#-x-evo-current-img", value);
+}
+
+static gchar *
+webkit_content_editor_image_get_src (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-img", "data-uri");
+
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_alt (EContentEditor *editor,
+                                     const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-img", "alt", value);
+}
+
+static gchar *
+webkit_content_editor_image_get_alt (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-img", "alt");
+
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_url (EContentEditor *editor,
+                                     const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorImageDialogSetElementUrl",
+               g_variant_new ("(ts)", current_page_id (wk_editor), value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gchar *
+webkit_content_editor_image_get_url (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gchar *value = NULL;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorImageDialogGetElementUrl",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_vspace (EContentEditor *editor,
+                                        gint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ImageElementSetVSpace",
+               g_variant_new (
+                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gint
+webkit_content_editor_image_get_vspace (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetVSpace",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_hspace (EContentEditor *editor,
+                                        gint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ImageElementSetHSpace",
+               g_variant_new (
+                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gint
+webkit_content_editor_image_get_hspace (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetHSpace",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_border (EContentEditor *editor,
+                                        gint value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *border;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       border = g_strdup_printf ("%d", value);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-img", "border", border);
+
+       g_free (border);
+}
+
+static gint
+webkit_content_editor_image_get_border (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-img", "border");
+
+       if (result) {
+               const gchar *border;
+               g_variant_get (result, "(&s)", &border);
+               if (border && *border)
+                       value = atoi (border);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_align (EContentEditor *editor,
+                                       const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-img", "align", value);
+}
+
+static gchar *
+webkit_content_editor_image_get_align (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-img", "align");
+
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gint32
+webkit_content_editor_image_get_natural_width (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint32 value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetNaturalWidth",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gint32
+webkit_content_editor_image_get_natural_height (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint32 value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetNaturalHeight",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_image_set_height (EContentEditor *editor,
+                                        gint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ImageElementSetHeight",
+               g_variant_new (
+                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_image_set_width (EContentEditor *editor,
+                                       gint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "ImageElementSetWidth",
+               g_variant_new (
+                       "(tsi)", current_page_id (wk_editor), "-x-evo-current-img", value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_image_set_height_follow (EContentEditor *editor,
+                                              gboolean value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (value)
+               webkit_content_editor_set_element_attribute (
+                       wk_editor, "#-x-evo-current-img", "style", "height: auto;");
+       else
+               webkit_content_editor_remove_element_attribute (
+                       wk_editor, "#-x-evo-current-img", "style");
+}
+
+static void
+webkit_content_editor_image_set_width_follow (EContentEditor *editor,
+                                             gboolean value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (value)
+               webkit_content_editor_set_element_attribute (
+                       wk_editor, "#-x-evo-current-img", "style", "width: auto;");
+       else
+               webkit_content_editor_remove_element_attribute (
+                       wk_editor, "#-x-evo-current-img", "style");
+}
+
+static gint32
+webkit_content_editor_image_get_width (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint32 value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetWidth",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gint32
+webkit_content_editor_image_get_height (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint32 value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ImageElementGetHeight",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-img"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_selection_unlink (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorSelectionUnlink");
+}
+
+static void
+webkit_content_editor_link_set_values (EContentEditor *editor,
+                                       const gchar *href,
+                                       const gchar *text)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorLinkDialogOk",
+               g_variant_new ("(tss)", current_page_id (wk_editor), href, text),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_link_get_values (EContentEditor *editor,
+                                       gchar **href,
+                                       gchar **text)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       printf ("%s:%d\n", __FUNCTION__, __LINE__);
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorLinkDialogShow",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(ss)", href, text);
+               g_variant_unref (result);
+       } else {
+               printf ("%s:%d\n", __FUNCTION__, __LINE__);
+               *href = NULL;
+               *text = NULL;
+       }
+}
+
+static void
+webkit_content_editor_set_alignment (EContentEditor *editor,
+                                     EContentEditorAlignment value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_set_format_int (
+               wk_editor, "DOMSelectionSetAlignment", (gint32) value);
+}
+
+static EContentEditorAlignment
+webkit_content_editor_get_alignment (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->alignment;
+}
+
+static void
+webkit_content_editor_set_block_format (EContentEditor *editor,
+                                        EContentEditorBlockFormat value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_set_format_int (
+               wk_editor, "DOMSelectionSetBlockFormat", (gint32) value);
+}
+
+static EContentEditorBlockFormat
+webkit_content_editor_get_block_format (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->block_format;
+}
+
+static void
+webkit_content_editor_set_background_color (EContentEditor *editor,
+                                            const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (gdk_rgba_equal (value, wk_editor->priv->background_color))
+               return;
+
+       color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+
+       if (wk_editor->priv->background_color)
+               gdk_rgba_free (wk_editor->priv->background_color);
+
+       wk_editor->priv->background_color = gdk_rgba_copy (value);
+
+       webkit_content_editor_set_format_string (
+               wk_editor,
+               "background-color",
+               "DOMSelectionSetBackgroundColor",
+               color);
+
+       g_free (color);
+}
+
+static const GdkRGBA *
+webkit_content_editor_get_background_color (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       if (!wk_editor->priv->html_mode || !wk_editor->priv->background_color)
+               return &white;
+
+       return wk_editor->priv->background_color;
+}
+
+static void
+webkit_content_editor_set_font_name (EContentEditor *editor,
+                                     const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       wk_editor->priv->font_name = g_strdup (value);
+
+       webkit_content_editor_set_format_string (
+               wk_editor, "font-name", "DOMSelectionSetFontName", value);
+}
+
+static const gchar *
+webkit_content_editor_get_font_name (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->font_name;
+}
+
+static void
+webkit_content_editor_set_font_color (EContentEditor *editor,
+                                      const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (gdk_rgba_equal (value, wk_editor->priv->font_color))
+               return;
+
+       color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+
+       if (wk_editor->priv->font_color)
+               gdk_rgba_free (wk_editor->priv->font_color);
+
+       wk_editor->priv->font_color = gdk_rgba_copy (value);
+
+       webkit_content_editor_set_format_string (
+               wk_editor,
+               "font-color",
+               "DOMSelectionSetFontColor",
+               color);
+
+       g_free (color);
+}
+
+static const GdkRGBA *
+webkit_content_editor_get_font_color (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       if (!wk_editor->priv->html_mode || !wk_editor->priv->font_color)
+               return &black;
+
+       return wk_editor->priv->font_color;
+}
+
+static void
+webkit_content_editor_set_font_size (EContentEditor *editor,
+                                     guint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->font_size == value)
+               return;
+
+       wk_editor->priv->font_size = value;
+
+       webkit_content_editor_set_format_int (
+               wk_editor, "DOMSelectionSetFontSize", (gint32) value);
+}
+
+static guint
+webkit_content_editor_get_font_size (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->font_size;
+}
+
+static void
+webkit_content_editor_set_bold (EContentEditor *editor,
+                                gboolean bold)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_bold == bold)
+               return;
+
+       wk_editor->priv->is_bold = bold;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetBold", bold);
+}
+
+static gboolean
+webkit_content_editor_is_bold (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_bold;
+}
+
+static void
+webkit_content_editor_set_italic (EContentEditor *editor,
+                                  gboolean italic)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_italic == italic)
+               return;
+
+       wk_editor->priv->is_italic = italic;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetItalic", italic);
+}
+
+static gboolean
+webkit_content_editor_is_italic (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_italic;
+}
+
+static void
+webkit_content_editor_set_monospaced (EContentEditor *editor,
+                                      gboolean monospaced)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_monospaced == monospaced)
+               return;
+
+       wk_editor->priv->is_monospaced = monospaced;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetMonospaced", monospaced);
+}
+
+static gboolean
+webkit_content_editor_is_monospaced (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_monospaced;
+}
+
+static void
+webkit_content_editor_set_strikethrough (EContentEditor *editor,
+                                         gboolean strikethrough)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_strikethrough == strikethrough)
+               return;
+
+       wk_editor->priv->is_strikethrough = strikethrough;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetStrikethrough", strikethrough);
+}
+
+static gboolean
+webkit_content_editor_is_strikethrough (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_strikethrough;
+}
+
+static void
+webkit_content_editor_set_subscript (EContentEditor *editor,
+                                     gboolean subscript)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_subscript == subscript)
+               return;
+
+       wk_editor->priv->is_subscript = subscript;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetSubscript", subscript);
+}
+
+static gboolean
+webkit_content_editor_is_subscript (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_subscript;
+}
+
+static void
+webkit_content_editor_set_superscript (EContentEditor *editor,
+                                       gboolean superscript)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_superscript == superscript)
+               return;
+
+       wk_editor->priv->is_superscript = superscript;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetSuperscript", superscript);
+}
+
+static gboolean
+webkit_content_editor_is_superscript (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_superscript;
+}
+
+static void
+webkit_content_editor_set_underline (EContentEditor *editor,
+                                     gboolean underline)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (wk_editor->priv->is_underline == underline)
+               return;
+
+       wk_editor->priv->is_underline = underline;
+
+       webkit_content_editor_set_format_boolean (
+               wk_editor, "DOMSelectionSetUnderline", underline);
+}
+
+static gboolean
+webkit_content_editor_is_underline (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       return wk_editor->priv->is_underline;
+}
+
+static void
+webkit_content_editor_page_set_text_color (EContentEditor *editor,
+                                           const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+
+       webkit_content_editor_set_element_attribute (wk_editor, "body", "text", color);
+
+       g_free (color);
+}
+
+static void
+webkit_content_editor_page_get_text_color (EContentEditor *editor,
+                                           GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto theme;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "body", "text");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto theme;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ theme:
+       e_utils_get_theme_color (
+               GTK_WIDGET (wk_editor),
+               "theme_text_color",
+               E_UTILS_DEFAULT_THEME_TEXT_COLOR,
+               color);
+}
+
+static void
+webkit_content_editor_page_set_background_color (EContentEditor *editor,
+                                                 const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (value->alpha != 0.0)
+               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+       else
+               color = g_strdup ("");
+
+       webkit_content_editor_set_element_attribute (wk_editor, "body", "bgcolor", color);
+
+       g_free (color);
+}
+
+static void
+webkit_content_editor_page_get_background_color (EContentEditor *editor,
+                                                 GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto theme;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "body", "bgcolor");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto theme;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ theme:
+       e_utils_get_theme_color (
+               GTK_WIDGET (wk_editor),
+               "theme_base_color",
+               E_UTILS_DEFAULT_THEME_BASE_COLOR,
+               color);
+}
+
+static void
+webkit_content_editor_page_set_link_color (EContentEditor *editor,
+                                           const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+
+       webkit_content_editor_set_element_attribute (wk_editor, "body", "link", color);
+
+       g_free (color);
+}
+
+static void
+webkit_content_editor_page_get_link_color (EContentEditor *editor,
+                                           GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto theme;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "body", "link");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto theme;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ theme:
+       color->alpha = 1;
+       color->red = 0;
+       color->green = 0;
+       color->blue = 1;
+}
+
+static void
+webkit_content_editor_page_set_visited_link_color (EContentEditor *editor,
+                                                   const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+
+       webkit_content_editor_set_element_attribute (wk_editor, "body", "vlink", color);
+
+       g_free (color);
+}
+
+static void
+webkit_content_editor_page_get_visited_link_color (EContentEditor *editor,
+                                                   GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto theme;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "body", "vlink");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto theme;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ theme:
+       color->alpha = 1;
+       color->red = 1;
+       color->green = 0;
+       color->blue = 0;
+}
+
+static void
+webkit_content_editor_on_page_dialog_open (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorPageDialogSaveHistory");
+}
+
+static void
+webkit_content_editor_on_page_dialog_close (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorPageDialogSaveHistoryOnExit");
+}
+
+static gchar *
+webkit_content_editor_page_get_background_image_uri (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "body", "data-uri");
+       if (result) {
+               gchar *value;
+
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return NULL;
+}
+
+static void
+webkit_content_editor_page_set_background_image_uri (EContentEditor *editor,
+                                                     const gchar *uri)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (uri && *uri)
+               webkit_content_editor_replace_image_src (wk_editor, "body", uri);
+       else {
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "RemoveImageAttributesFromElementBySelector",
+                       g_variant_new ("(ts)", current_page_id (wk_editor), "body"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       }
+}
+
+static void
+webkit_content_editor_on_cell_dialog_open (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogMarkCurrentCellElement",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-table-cell"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_on_cell_dialog_close (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorCellDialogSaveHistoryOnExit");
+}
+
+static void
+webkit_content_editor_cell_set_v_align (EContentEditor *editor,
+                                        const gchar *value,
+                                        EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementVAlign",
+               g_variant_new ("(tsi)", current_page_id (wk_editor), value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gchar *
+webkit_content_editor_cell_get_v_align (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-cell", "valign");
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_cell_set_align (EContentEditor *editor,
+                                      const gchar *value,
+                                      EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementAlign",
+               g_variant_new ("(tsi)", current_page_id (wk_editor), value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gchar *
+webkit_content_editor_cell_get_align (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-cell", "align");
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_cell_set_wrap (EContentEditor *editor,
+                                     gboolean value,
+                                     EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementNoWrap",
+               g_variant_new ("(tbi)", current_page_id (wk_editor), !value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gboolean
+webkit_content_editor_cell_get_wrap (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean value = FALSE;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return FALSE;
+
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "TableCellElementGetNoWrap",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &value);
+               value = !value;
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_cell_set_header_style (EContentEditor *editor,
+                                             gboolean value,
+                                             EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementHeaderStyle",
+               g_variant_new ("(tbi)", current_page_id (wk_editor), value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static gboolean
+webkit_content_editor_cell_is_header (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean value = FALSE;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return FALSE;
+
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "ElementGetTagName",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               const gchar *tag_name;
+
+               g_variant_get (result, "(&s)", &tag_name);
+               value = g_ascii_strncasecmp (tag_name, "TH", 2) == 0;
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gint
+webkit_content_editor_cell_get_width (EContentEditor *editor,
+                                      EContentEditorUnit *unit)
+{
+       EWebKitContentEditor *wk_editor;
+       gint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       *unit = E_CONTENT_EDITOR_UNIT_AUTO;
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-cell", "width");
+
+       if (result) {
+               const gchar *width;
+
+               g_variant_get (result, "(&s)", &width);
+               if (width && *width) {
+                       value = atoi (width);
+                       if (strstr (width, "%"))
+                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
+                       else if (g_ascii_strncasecmp (width, "auto", 4) != 0)
+                               *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+               }
+               g_object_unref (result);
+       }
+
+       return value;
+}
+
+static gint
+webkit_content_editor_cell_get_row_span (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "TableCellElementGetRowSpan",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gint
+webkit_content_editor_cell_get_col_span (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "TableCellElementGetColSpan",
+               g_variant_new ("(ts)", current_page_id (wk_editor), "-x-evo-current-cell"),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(i)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static gchar *
+webkit_content_editor_cell_get_background_image_uri (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-cell", "data-uri");
+       if (result) {
+               gchar *value;
+
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return NULL;
+}
+
+static void
+webkit_content_editor_cell_get_background_color (EContentEditor *editor,
+                                                 GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto exit;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-cell", "bgcolor");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto exit;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ exit:
+       *color = transparent;
+}
+
+static void
+webkit_content_editor_cell_set_row_span (EContentEditor *editor,
+                                         gint value,
+                                         EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementRowSpan",
+               g_variant_new ("(tii)", current_page_id (wk_editor), value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_cell_set_col_span (EContentEditor *editor,
+                                         gint value,
+                                         EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementColSpan",
+               g_variant_new ("(tii)", current_page_id (wk_editor), value, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_cell_set_width (EContentEditor *editor,
+                                      gint value,
+                                      EContentEditorUnit unit,
+                                      EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *width;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (unit == E_CONTENT_EDITOR_UNIT_AUTO)
+               width = g_strdup ("auto");
+       else
+               width = g_strdup_printf (
+                       "%d%s",
+                       value,
+                       (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementWidth",
+               g_variant_new ("(tsi)", current_page_id (wk_editor), width, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       g_free (width);
+}
+
+static void
+webkit_content_editor_cell_set_background_color (EContentEditor *editor,
+                                                 const GdkRGBA *value,
+                                                 EContentEditorScope scope)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (value->alpha != 0.0)
+               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+       else
+               color = g_strdup ("");
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorCellDialogSetElementBgColor",
+               g_variant_new ("(tsi)", current_page_id (wk_editor), color, (gint32) scope),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       g_free (color);
+}
+
+static void
+webkit_content_editor_cell_set_background_image_uri (EContentEditor *editor,
+                                                     const gchar *uri)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (uri && *uri)
+               webkit_content_editor_replace_image_src (wk_editor, "#-x-evo-current-cell", uri);
+       else {
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "RemoveImageAttributesFromElementBySelector",
+                       g_variant_new ("(ts)", current_page_id (wk_editor), "#-x-evo-current-cell"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       }
+}
+
+static void
+webkit_content_editor_table_set_row_count (EContentEditor *editor,
+                                           guint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorTableDialogSetRowCount",
+               g_variant_new ("(tu)", current_page_id (wk_editor), value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static guint
+webkit_content_editor_table_get_row_count (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       guint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorTableDialogGetRowCount",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(u)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_column_count (EContentEditor *editor,
+                                              guint value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorTableDialogSetColumnCount",
+               g_variant_new ("(tu)", current_page_id (wk_editor), value),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static guint
+webkit_content_editor_table_get_column_count (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       guint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       if (!wk_editor->priv->web_extension)
+               return 0;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorTableDialogGetColumnCount",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(u)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_width (EContentEditor *editor,
+                                       gint value,
+                                       EContentEditorUnit unit)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *width;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (unit == E_CONTENT_EDITOR_UNIT_AUTO)
+               width = g_strdup ("auto");
+       else
+               width = g_strdup_printf (
+                       "%d%s",
+                       value,
+                       (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "px" : "%");
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "width", width);
+
+       g_free (width);
+}
+
+static guint
+webkit_content_editor_table_get_width (EContentEditor *editor,
+                                       EContentEditorUnit *unit)
+{
+       EWebKitContentEditor *wk_editor;
+       guint value = 0;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+
+       if (!wk_editor->priv->html_mode)
+               return 0;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "width");
+
+       if (result) {
+               const gchar *width;
+
+               g_variant_get (result, "(&s)", &width);
+               if (width && *width) {
+                       value = atoi (width);
+                       if (strstr (width, "%"))
+                               *unit = E_CONTENT_EDITOR_UNIT_PERCENTAGE;
+                       else if (g_ascii_strncasecmp (width, "auto", 4) != 0)
+                               *unit = E_CONTENT_EDITOR_UNIT_PIXEL;
+               }
+               g_object_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_align (EContentEditor *editor,
+                                       const gchar *value)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "align", value);
+}
+
+static gchar *
+webkit_content_editor_table_get_align (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *value = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "align");
+       if (result) {
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_padding (EContentEditor *editor,
+                                         gint value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *padding;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       padding = g_strdup_printf ("%d", value);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "cellpadding", padding);
+
+       g_free (padding);
+}
+
+static gint
+webkit_content_editor_table_get_padding (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "cellpadding");
+
+       if (result) {
+               const gchar *padding;
+
+               g_variant_get (result, "(&s)", &padding);
+               if (padding && *padding)
+                       value = atoi (padding);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_spacing (EContentEditor *editor,
+                                         gint value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *spacing;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       spacing = g_strdup_printf ("%d", value);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "cellspacing", spacing);
+
+       g_free (spacing);
+}
+
+static gint
+webkit_content_editor_table_get_spacing (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "cellspacing");
+
+       if (result) {
+               const gchar *spacing;
+
+               g_variant_get (result, "(&s)", &spacing);
+               if (spacing && *spacing)
+                       value = atoi (spacing);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_set_border (EContentEditor *editor,
+                                        gint value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *border;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       border = g_strdup_printf ("%d", value);
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "border", border);
+
+       g_free (border);
+}
+
+static gint
+webkit_content_editor_table_get_border (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gint value = 0;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "border");
+
+       if (result) {
+               const gchar *border;
+
+               g_variant_get (result, "(&s)", &border);
+               if (border && *border)
+                       value = atoi (border);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_table_get_background_color (EContentEditor *editor,
+                                                 GdkRGBA *color)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               goto exit;
+
+       result = webkit_content_editor_get_element_attribute (
+               wk_editor, "#-x-evo-current-table", "bgcolor");
+       if (result) {
+               const gchar *value;
+
+               g_variant_get (result, "(&s)", &value);
+               if (!value || !*value || !gdk_rgba_parse (color, value)) {
+                       g_variant_unref (result);
+                       goto exit;
+               }
+               g_variant_unref (result);
+               return;
+       }
+
+ exit:
+       *color = transparent;
+}
+
+static void
+webkit_content_editor_table_set_background_color (EContentEditor *editor,
+                                                  const GdkRGBA *value)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar *color;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (value->alpha != 0.0)
+               color = g_strdup_printf ("#%06x", e_rgba_to_value (value));
+       else
+               color = g_strdup ("");
+
+       webkit_content_editor_set_element_attribute (
+               wk_editor, "#-x-evo-current-table", "bgcolor", color);
+
+       g_free (color);
+}
+
+static gchar *
+webkit_content_editor_table_get_background_image_uri (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->html_mode)
+               return NULL;
+
+       result = webkit_content_editor_get_element_attribute (wk_editor, "#-x-evo-current-table", "data-uri");
+       if (result) {
+               gchar *value;
+
+               g_variant_get (result, "(s)", &value);
+               g_variant_unref (result);
+       }
+
+       return NULL;
+}
+
+static void
+webkit_content_editor_table_set_background_image_uri (EContentEditor *editor,
+                                                     const gchar *uri)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return;
+
+       if (!wk_editor->priv->html_mode)
+               return;
+
+       if (uri && *uri)
+               webkit_content_editor_replace_image_src (wk_editor, "#-x-evo-current-table", uri);
+       else {
+               g_dbus_proxy_call (
+                       wk_editor->priv->web_extension,
+                       "RemoveImageAttributesFromElementBySelector",
+                       g_variant_new ("(ts)", current_page_id (wk_editor), "#-x-evo-current-table"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL,
+                       NULL);
+       }
+}
+
+static gboolean
+webkit_content_editor_on_table_dialog_open (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+       GVariant *result;
+       gboolean value = FALSE;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return FALSE;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               "EHTMLEditorTableDialogShow",
+               g_variant_new ("(t)", current_page_id (wk_editor)),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       if (result) {
+               g_variant_get (result, "(b)", &value);
+               g_variant_unref (result);
+       }
+
+       return value;
+}
+
+static void
+webkit_content_editor_on_table_dialog_close (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       webkit_content_editor_call_simple_extension_function (
+               wk_editor, "EHTMLEditorTableDialogSaveHistoryOnExit");
+}
+
+static void
+webkit_content_editor_on_spell_check_dialog_open (EContentEditor *editor)
+{
+}
+
+static void
+webkit_content_editor_on_spell_check_dialog_close (EContentEditor *editor)
+{
+}
+
+static gchar *
+move_to_another_word (EContentEditor *editor,
+                      const gchar *word,
+                      const gchar *dom_function)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar **active_languages;
+       gchar *another_word = NULL;
+       GVariant *result;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       if (!wk_editor->priv->web_extension)
+               return NULL;
+
+       active_languages = e_spell_checker_list_active_languages (
+               wk_editor->priv->spell_checker, NULL);
+       if (!active_languages)
+               return NULL;
+
+       result = g_dbus_proxy_call_sync (
+               wk_editor->priv->web_extension,
+               dom_function,
+               g_variant_new (
+                       "(ts^as)", current_page_id (wk_editor), word ? word : "", active_languages),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL);
+
+       g_strfreev (active_languages);
+
+       if (result) {
+               g_variant_get (result, "(s)", &another_word);
+               g_variant_unref (result);
+       }
+
+       return another_word;
+}
+
+static gchar *
+webkit_content_editor_spell_check_next_word (EContentEditor *editor,
+                                             const gchar *word)
+{
+       return move_to_another_word (editor, word, "EHTMLEditorSpellCheckDialogNext");
+}
+
+static gchar *
+webkit_content_editor_spell_check_prev_word (EContentEditor *editor,
+                                             const gchar *word)
+{
+       return move_to_another_word (editor, word, "EHTMLEditorSpellCheckDialogPrev");
+}
+
+static void
+webkit_content_editor_on_replace_dialog_open (EContentEditor *editor)
+{
+}
+
+static void
+webkit_content_editor_on_replace_dialog_close (EContentEditor *editor)
+{
+}
+
+static void
+webkit_content_editor_on_find_dialog_open (EContentEditor *editor)
+{
+}
+
+static void
+webkit_content_editor_on_find_dialog_close (EContentEditor *editor)
+{
+}
+
+static void
+webkit_content_editor_constructed (GObject *object)
+{
+       EWebKitContentEditor *wk_editor;
+       gchar **languages;
+       WebKitWebContext *web_context;
+       WebKitSettings *web_settings;
+       WebKitWebView *web_view;
+
+       G_OBJECT_CLASS (e_webkit_content_editor_parent_class)->constructed (object);
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (object);
+       web_view = WEBKIT_WEB_VIEW (wk_editor);
+
+       wk_editor->priv->find_controller = g_object_new (
+               E_TYPE_WEBKIT_CONTENT_EDITOR_FIND_CONTROLLER,
+               "webkit-content-editor", wk_editor,
+               NULL);
+
+       /* Give spell check languages to WebKit */
+       languages = e_spell_checker_list_active_languages (wk_editor->priv->spell_checker, NULL);
+
+       web_context = webkit_web_view_get_context (web_view);
+       webkit_web_context_set_spell_checking_enabled (web_context, TRUE);
+       webkit_web_context_set_spell_checking_languages (web_context, (const gchar * const *) languages);
+       g_strfreev (languages);
+
+       webkit_web_view_set_editable (web_view, TRUE);
+
+       web_settings = webkit_web_view_get_settings (web_view);
+       webkit_settings_set_allow_file_access_from_file_urls (web_settings, TRUE);
+
+       /* Make WebKit think we are displaying a local file, so that it
+        * does not block loading resources from file:// protocol */
+       webkit_web_view_load_html (WEBKIT_WEB_VIEW (object), "", "file://");
+}
+
+static GObjectConstructParam*
+find_property (guint n_properties,
+               GObjectConstructParam* properties,
+               GParamSpec* param_spec)
+{
+       while (n_properties--) {
+               if (properties->pspec == param_spec)
+                       return properties;
+               properties++;
+       }
+
+       return NULL;
+}
+
+static GObject *
+webkit_content_editor_constructor (GType type,
+                                   guint n_construct_properties,
+                                   GObjectConstructParam *construct_properties)
+{
+       GObjectClass* object_class;
+       GParamSpec* param_spec;
+       GObjectConstructParam *param = NULL;
+
+       object_class = G_OBJECT_CLASS (g_type_class_ref (type));
+       g_return_val_if_fail (object_class != NULL, NULL);
+
+       if (construct_properties && n_construct_properties != 0) {
+               param_spec = g_object_class_find_property (object_class, "settings");
+               if ((param = find_property (n_construct_properties, construct_properties, param_spec)))
+                       g_value_take_object (param->value, e_web_view_get_default_webkit_settings ());
+               param_spec = g_object_class_find_property (object_class, "user-content-manager");
+               if ((param = find_property (n_construct_properties, construct_properties, param_spec)))
+                       g_value_take_object (param->value, webkit_user_content_manager_new ());
+               param_spec = g_object_class_find_property (object_class, "web-context");
+               if ((param = find_property (n_construct_properties, construct_properties, param_spec))) {
+                       WebKitWebContext *web_context;
+
+                       web_context = webkit_web_context_new ();
+
+                       webkit_web_context_set_cache_model (
+                               web_context, WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
+
+                       webkit_web_context_set_web_extensions_directory (
+                               web_context, EVOLUTION_WEB_EXTENSIONS_COMPOSER_DIR);
+
+                       g_value_take_object (param->value, web_context);
+               }
+       }
+
+       g_type_class_unref (object_class);
+
+       return G_OBJECT_CLASS (e_webkit_content_editor_parent_class)->constructor (type, 
n_construct_properties, construct_properties);
+}
+
+static void
+webkit_content_editor_dispose (GObject *object)
+{
+       EWebKitContentEditorPrivate *priv;
+
+       priv = E_WEBKIT_CONTENT_EDITOR_GET_PRIVATE (object);
+
+       if (priv->aliasing_settings != NULL) {
+               g_signal_handlers_disconnect_by_data (priv->aliasing_settings, object);
+               g_object_unref (priv->aliasing_settings);
+               priv->aliasing_settings = NULL;
+       }
+
+       if (priv->current_user_stylesheet != NULL) {
+               g_free (priv->current_user_stylesheet);
+               priv->current_user_stylesheet = NULL;
+       }
+
+       if (priv->font_settings != NULL) {
+               g_signal_handlers_disconnect_by_data (priv->font_settings, object);
+               g_object_unref (priv->font_settings);
+               priv->font_settings = NULL;
+       }
+
+       if (priv->mail_settings != NULL) {
+               g_signal_handlers_disconnect_by_data (priv->mail_settings, object);
+               g_object_unref (priv->mail_settings);
+               priv->mail_settings = NULL;
+       }
+
+       if (priv->web_extension_content_changed_cb_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_content_changed_cb_id);
+               priv->web_extension_content_changed_cb_id = 0;
+       }
+
+       if (priv->web_extension_selection_changed_cb_id > 0) {
+               g_dbus_connection_signal_unsubscribe (
+                       g_dbus_proxy_get_connection (priv->web_extension),
+                       priv->web_extension_selection_changed_cb_id);
+               priv->web_extension_selection_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;
+       }
+
+       if (priv->owner_change_clipboard_cb_id > 0) {
+               g_signal_handler_disconnect (
+                       gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
+                       priv->owner_change_clipboard_cb_id);
+               priv->owner_change_clipboard_cb_id = 0;
+       }
+
+       if (priv->owner_change_primary_clipboard_cb_id > 0) {
+               g_signal_handler_disconnect (
+                       gtk_clipboard_get (GDK_SELECTION_PRIMARY),
+                       priv->owner_change_primary_clipboard_cb_id);
+               priv->owner_change_primary_clipboard_cb_id = 0;
+       }
+
+       g_clear_object (&priv->web_extension);
+       g_clear_object (&priv->find_controller);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (e_webkit_content_editor_parent_class)->dispose (object);
+}
+
+static void
+webkit_content_editor_finalize (GObject *object)
+{
+       EWebKitContentEditorPrivate *priv;
+
+       priv = E_WEBKIT_CONTENT_EDITOR_GET_PRIVATE (object);
+
+       if (priv->old_settings) {
+               g_hash_table_destroy (priv->old_settings);
+               priv->old_settings = NULL;
+       }
+
+       if (priv->post_reload_operations) {
+               g_warn_if_fail (g_queue_is_empty (priv->post_reload_operations));
+
+               g_queue_free (priv->post_reload_operations);
+               priv->post_reload_operations = NULL;
+       }
+
+       if (priv->background_color != NULL) {
+               gdk_rgba_free (priv->background_color);
+               priv->background_color = NULL;
+       }
+
+       if (priv->font_color != NULL) {
+               gdk_rgba_free (priv->font_color);
+               priv->font_color = NULL;
+       }
+
+       g_clear_object (&priv->spell_checker);
+
+       g_free (priv->font_name);
+
+       /* Chain up to parent's finalize() method. */
+       G_OBJECT_CLASS (e_webkit_content_editor_parent_class)->finalize (object);
+}
+
+static void
+webkit_content_editor_set_property (GObject *object,
+                                    guint property_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_CHANGED:
+                       webkit_content_editor_set_changed (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_EDITABLE:
+                       webkit_content_editor_set_editable (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_HTML_MODE:
+                       webkit_content_editor_set_html_mode (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_ALIGNMENT:
+                       webkit_content_editor_set_alignment (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_int (value));
+                       return;
+
+               case PROP_BACKGROUND_COLOR:
+                       webkit_content_editor_set_background_color (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boxed (value));
+                       return;
+
+               case PROP_BOLD:
+                       webkit_content_editor_set_bold (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_FONT_COLOR:
+                       webkit_content_editor_set_font_color (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boxed (value));
+                       return;
+
+               case PROP_BLOCK_FORMAT:
+                       webkit_content_editor_set_block_format (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_int (value));
+                       return;
+
+               case PROP_FONT_NAME:
+                       webkit_content_editor_set_font_name (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_string (value));
+                       return;
+
+               case PROP_FONT_SIZE:
+                       webkit_content_editor_set_font_size (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_int (value));
+                       return;
+
+               case PROP_ITALIC:
+                       webkit_content_editor_set_italic (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_MONOSPACED:
+                       webkit_content_editor_set_monospaced (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_STRIKETHROUGH:
+                       webkit_content_editor_set_strikethrough (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_SUBSCRIPT:
+                       webkit_content_editor_set_subscript (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_SUPERSCRIPT:
+                       webkit_content_editor_set_superscript (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_UNDERLINE:
+                       webkit_content_editor_set_underline (
+                               E_CONTENT_EDITOR (object),
+                               g_value_get_boolean (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+webkit_content_editor_get_property (GObject *object,
+                                    guint property_id,
+                                    GValue *value,
+                                    GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_CAN_COPY:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_can_copy (
+                               E_WEBKIT_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_CAN_CUT:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_can_cut (
+                               E_WEBKIT_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_CAN_PASTE:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_can_paste (
+                               E_WEBKIT_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_CAN_REDO:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_can_redo (
+                               E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_CAN_UNDO:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_can_undo (
+                               E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_CHANGED:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_get_changed (
+                               E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_HTML_MODE:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_get_html_mode (
+                               E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_EDITABLE:
+                       g_value_set_boolean (
+                               value, webkit_content_editor_is_editable (
+                               E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_ALIGNMENT:
+                       g_value_set_int (
+                               value,
+                               webkit_content_editor_get_alignment (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_BACKGROUND_COLOR:
+                       g_value_set_boxed (
+                               value,
+                               webkit_content_editor_get_background_color (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_BLOCK_FORMAT:
+                       g_value_set_int (
+                               value,
+                               webkit_content_editor_get_block_format (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_BOLD:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_bold (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_FONT_COLOR:
+                       g_value_set_boxed (
+                               value,
+                               webkit_content_editor_get_font_color (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_FONT_NAME:
+                       g_value_set_string (
+                               value,
+                               webkit_content_editor_get_font_name (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_FONT_SIZE:
+                       g_value_set_int (
+                               value,
+                               webkit_content_editor_get_font_size (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_INDENTED:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_selection_is_indented (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_ITALIC:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_italic (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_MONOSPACED:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_monospaced (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_STRIKETHROUGH:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_strikethrough (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_SUBSCRIPT:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_subscript (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_SUPERSCRIPT:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_superscript (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_UNDERLINE:
+                       g_value_set_boolean (
+                               value,
+                               webkit_content_editor_is_underline (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+
+               case PROP_SPELL_CHECKER:
+                       g_value_set_object (
+                               value,
+                               webkit_content_editor_get_spell_checker (
+                                       E_CONTENT_EDITOR (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+webkit_content_editor_move_caret_on_current_coordinates (GtkWidget *widget)
+{
+       gint x, y;
+       GdkDeviceManager *device_manager;
+       GdkDevice *pointer;
+
+       device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
+       pointer = gdk_device_manager_get_client_pointer (device_manager);
+       gdk_window_get_device_position (
+               gtk_widget_get_window (widget), pointer, &x, &y, NULL);
+       webkit_content_editor_move_caret_on_coordinates
+               (E_CONTENT_EDITOR (widget), x, y, TRUE);
+}
+
+static void
+webkit_content_editor_settings_changed_cb (GSettings *settings,
+                                           const gchar *key,
+                                           EWebKitContentEditor *wk_editor)
+{
+       GVariant *new_value, *old_value;
+
+       new_value = g_settings_get_value (settings, key);
+       old_value = g_hash_table_lookup (wk_editor->priv->old_settings, key);
+
+       if (!new_value || !old_value || !g_variant_equal (new_value, old_value)) {
+               if (new_value)
+                       g_hash_table_insert (wk_editor->priv->old_settings, g_strdup (key), new_value);
+               else
+                       g_hash_table_remove (wk_editor->priv->old_settings, key);
+
+               webkit_content_editor_update_fonts (E_CONTENT_EDITOR (wk_editor));
+       } else if (new_value) {
+               g_variant_unref (new_value);
+       }
+}
+
+static void
+webkit_content_editor_load_changed_cb (EWebKitContentEditor *wk_editor,
+                                       WebKitLoadEvent load_event)
+{
+       wk_editor->priv->webkit_load_event = load_event;
+
+       if (load_event != WEBKIT_LOAD_FINISHED)
+               return;
+
+       if (wk_editor->priv->web_extension)
+               g_signal_emit_by_name (E_CONTENT_EDITOR (wk_editor), "load-finished", 0);
+       else
+               wk_editor->priv->emit_load_finished_when_extension_is_ready = TRUE;
+
+       dispatch_pending_operations (wk_editor);
+
+       wk_editor->priv->reload_in_progress = FALSE;
+}
+
+static void
+webkit_content_editor_clipboard_owner_change_cb (GtkClipboard *clipboard,
+                                                 GdkEventOwnerChange *event,
+                                                 EWebKitContentEditor *wk_editor)
+{
+       if (!E_IS_WEBKIT_CONTENT_EDITOR (wk_editor))
+               return;
+
+       if (wk_editor->priv->copy_action_triggered && event->owner)
+               wk_editor->priv->copy_paste_clipboard_in_view = TRUE;
+       else
+               wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "SetPastingContentFromItself",
+               g_variant_new (
+                       "(tb)",
+                       current_page_id (wk_editor),
+                       wk_editor->priv->copy_paste_clipboard_in_view),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+
+       wk_editor->priv->copy_action_triggered = FALSE;
+}
+
+static void
+webkit_content_editor_primary_clipboard_owner_change_cb (GtkClipboard *clipboard,
+                                                         GdkEventOwnerChange *event,
+                                                         EWebKitContentEditor *wk_editor)
+{
+       if (!E_IS_WEBKIT_CONTENT_EDITOR (wk_editor))
+               return;
+
+       if (!event->owner || !wk_editor->priv->can_copy)
+               wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
+
+       g_dbus_proxy_call (
+               wk_editor->priv->web_extension,
+               "SetPastingContentFromItself",
+               g_variant_new (
+                       "(tb)",
+                       current_page_id (wk_editor),
+                       wk_editor->priv->copy_paste_clipboard_in_view),
+               G_DBUS_CALL_FLAGS_NONE,
+               -1,
+               NULL,
+               NULL,
+               NULL);
+}
+
+static void
+webkit_content_editor_copy_cut_clipboard_cb (EWebKitContentEditor *wk_editor)
+{
+       wk_editor->priv->copy_action_triggered = TRUE;
+}
+
+static void
+webkit_content_editor_paste_clipboard_targets_cb (GtkClipboard *clipboard,
+                                                  GdkAtom *targets,
+                                                  gint n_targets,
+                                                  EWebKitContentEditor *wk_editor)
+{
+       if (targets == NULL || n_targets < 0)
+               return;
+
+       /* If view doesn't have focus, focus it */
+       if (!gtk_widget_has_focus (GTK_WIDGET (wk_editor)))
+               gtk_widget_grab_focus (GTK_WIDGET (wk_editor));
+
+       /* Order is important here to ensure common use cases are
+        * handled correctly.  See GNOME bug #603715 for details. */
+       /* Prefer plain text over HTML when in the plain text mode, but only
+        * when pasting content from outside the editor view. */
+       if (wk_editor->priv->html_mode ||
+           webkit_content_editor_paste_prefer_text_html (E_CONTENT_EDITOR (wk_editor))) {
+               gchar *content = NULL;
+
+               if (e_targets_include_html (targets, n_targets)) {
+                       if (!(content = e_clipboard_wait_for_html (clipboard)))
+                               return;
+
+                       webkit_content_editor_insert_content (
+                               E_CONTENT_EDITOR (wk_editor),
+                               content,
+                               E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+                       g_free (content);
+                       return;
+               }
+
+               if (gtk_targets_include_text (targets, n_targets)) {
+                       if (!(content = gtk_clipboard_wait_for_text (clipboard)))
+                               return;
+
+                       webkit_content_editor_insert_content (
+                               E_CONTENT_EDITOR (wk_editor),
+                               content,
+                               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
+
+                       g_free (content);
+                       return;
+               }
+       } else {
+               gchar *content = NULL;
+
+               if (gtk_targets_include_text (targets, n_targets)) {
+                       if (!(content = gtk_clipboard_wait_for_text (clipboard)))
+                               return;
+
+                       webkit_content_editor_insert_content (
+                               E_CONTENT_EDITOR (wk_editor),
+                               content,
+                               E_CONTENT_EDITOR_INSERT_TEXT_PLAIN);
+
+                       g_free (content);
+                       return;
+               }
+
+               if (e_targets_include_html (targets, n_targets)) {
+                       if (!(content = e_clipboard_wait_for_html (clipboard)))
+                               return;
+
+                       webkit_content_editor_insert_content (
+                               E_CONTENT_EDITOR (wk_editor),
+                               content,
+                               E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+                       g_free (content);
+                       return;
+               }
+       }
+
+       if (gtk_targets_include_image (targets, n_targets, TRUE)) {
+               gchar *uri;
+
+               if (!(uri = e_util_save_image_from_clipboard (clipboard)))
+                       return;
+
+               webkit_content_editor_insert_image (E_CONTENT_EDITOR (wk_editor), uri);
+
+               g_free (uri);
+
+               return;
+       }
+}
+
+static void
+webkit_content_editor_paste_primary_clipboard_cb (EWebKitContentEditor *wk_editor)
+{
+       GtkClipboard *clipboard;
+
+       clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+
+       gtk_clipboard_request_targets (
+               clipboard, (GtkClipboardTargetsReceivedFunc)
+               webkit_content_editor_paste_clipboard_targets_cb, wk_editor);
+
+       g_signal_stop_emission_by_name (wk_editor, "paste-primary-clipboard");
+}
+
+static void
+webkit_content_editor_paste_clipboard_cb (EWebKitContentEditor *wk_editor)
+{
+       GtkClipboard *clipboard;
+
+       clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+       gtk_clipboard_request_targets (
+               clipboard, (GtkClipboardTargetsReceivedFunc)
+               webkit_content_editor_paste_clipboard_targets_cb, wk_editor);
+
+       g_signal_stop_emission_by_name (wk_editor, "paste-clipboard");
+}
+
+static void
+webkit_content_editor_reconnect_paste_clipboard_signals (EContentEditor *editor)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (editor);
+
+       g_signal_handlers_disconnect_by_func (
+               wk_editor, webkit_content_editor_paste_clipboard_cb, NULL);
+       g_signal_handlers_disconnect_by_func (
+               wk_editor, webkit_content_editor_paste_primary_clipboard_cb, NULL);
+
+       g_signal_connect (
+               wk_editor, "paste-clipboard",
+               G_CALLBACK (webkit_content_editor_paste_clipboard_cb), NULL);
+       g_signal_connect (
+               wk_editor, "paste-primary-clipboard",
+               G_CALLBACK (webkit_content_editor_paste_primary_clipboard_cb), NULL);
+}
+
+static void
+webkit_content_editor_mouse_target_changed_cb (EWebKitContentEditor *wk_editor,
+                                               WebKitHitTestResult *hit_test_result,
+                                               guint modifiers,
+                                               gpointer user_data)
+{
+       /* Ctrl + Left Click on link opens it. */
+       if (webkit_hit_test_result_context_is_link (hit_test_result) &&
+           (modifiers & GDK_CONTROL_MASK)) {
+               GdkScreen *screen;
+               const gchar *uri;
+               GtkWidget *toplevel;
+
+               toplevel = gtk_widget_get_toplevel (GTK_WIDGET (wk_editor));
+               screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
+
+               uri = webkit_hit_test_result_get_link_uri (hit_test_result);
+
+               gtk_show_uri (screen, uri, GDK_CURRENT_TIME, NULL);
+       }
+}
+
+static gboolean
+webkit_content_editor_context_menu_cb (EWebKitContentEditor *wk_editor,
+                                       WebKitContextMenu *context_menu,
+                                       GdkEvent *event,
+                                       WebKitHitTestResult *hit_test_result)
+{
+       GVariant *result;
+       EContentEditorNodeFlags flags = 0;
+       gboolean handled = FALSE;
+
+       webkit_context_menu_remove_all (context_menu);
+
+       if ((result = webkit_context_menu_get_user_data (context_menu)))
+               flags = g_variant_get_int32 (result);
+
+       g_signal_emit_by_name (
+               E_CONTENT_EDITOR (wk_editor),
+               "context-menu-requested",
+               flags,
+               event,
+               &handled);
+
+       return handled;
+}
+
+static void
+webkit_content_editor_drag_end_cb (EWebKitContentEditor *editor,
+                                   GdkDragContext *context)
+{
+       webkit_content_editor_call_simple_extension_function (editor, "DOMDragAndDropEnd");
+}
+
+static gboolean
+webkit_content_editor_button_press_event (GtkWidget *widget,
+                                          GdkEventButton *event)
+{
+       EWebKitContentEditor *wk_editor;
+       gboolean event_handled;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (widget);
+
+       if (event->button == 2) {
+               /* Middle click paste */
+               webkit_content_editor_move_caret_on_current_coordinates (widget);
+               /* Remember, that we are pasting primary clipboard to return
+                * correct value in e_html_editor_view_is_pasting_content_from_itself. */
+               wk_editor->priv->pasting_primary_clipboard = TRUE;
+               g_signal_emit_by_name (E_CONTENT_EDITOR (widget), "paste-primary-clipboard", 0);
+               event_handled = TRUE;
+       } else {
+               event_handled = FALSE;
+       }
+
+       if (event_handled)
+               return TRUE;
+
+       /* Chain up to parent's button_press_event() method. */
+       return GTK_WIDGET_CLASS (e_webkit_content_editor_parent_class)->button_press_event (widget, event);
+}
+
+static gboolean
+webkit_content_editor_key_press_event (GtkWidget *widget,
+                                       GdkEventKey *event)
+{
+       EWebKitContentEditor *wk_editor;
+
+       wk_editor = E_WEBKIT_CONTENT_EDITOR (widget);
+
+       if ((((event)->state & GDK_SHIFT_MASK) &&
+           ((event)->keyval == GDK_KEY_Insert)) ||
+           (((event)->state & GDK_CONTROL_MASK) &&
+           ((event)->keyval == GDK_KEY_v))) {
+               webkit_content_editor_paste (E_CONTENT_EDITOR (wk_editor));
+               return TRUE;
+       }
+
+       if (((event)->state & GDK_CONTROL_MASK) &&
+           ((event)->keyval == GDK_KEY_Insert)) {
+               webkit_content_editor_copy (E_CONTENT_EDITOR (wk_editor));
+               return TRUE;
+       }
+
+       if (((event)->state & GDK_CONTROL_MASK) &&
+           ((event)->keyval == GDK_KEY_z)) {
+               webkit_content_editor_undo (E_CONTENT_EDITOR (wk_editor));
+               return TRUE;
+       }
+
+       if (((event)->state & (GDK_CONTROL_MASK)) &&
+           ((event)->keyval == GDK_KEY_Z)) {
+               webkit_content_editor_redo (E_CONTENT_EDITOR (wk_editor));
+               return TRUE;
+       }
+
+       if (((event)->state & GDK_SHIFT_MASK) &&
+           ((event)->keyval == GDK_KEY_Delete)) {
+               webkit_content_editor_cut (E_CONTENT_EDITOR (wk_editor));
+               return TRUE;
+       }
+
+       /* Chain up to parent's key_press_event() method. */
+       return GTK_WIDGET_CLASS (e_webkit_content_editor_parent_class)->key_press_event (widget, event);
+}
+
+static void
+e_webkit_content_editor_class_init (EWebKitContentEditorClass *class)
+{
+       GObjectClass *object_class;
+       GtkWidgetClass *widget_class;
+
+       g_type_class_add_private (class, sizeof (EWebKitContentEditorPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->constructed = webkit_content_editor_constructed;
+       object_class->constructor = webkit_content_editor_constructor;
+       object_class->get_property = webkit_content_editor_get_property;
+       object_class->set_property = webkit_content_editor_set_property;
+       object_class->dispose = webkit_content_editor_dispose;
+       object_class->finalize = webkit_content_editor_finalize;
+
+       widget_class = GTK_WIDGET_CLASS (class);
+       widget_class->button_press_event = webkit_content_editor_button_press_event;
+       widget_class->key_press_event = webkit_content_editor_key_press_event;
+
+       g_object_class_override_property (
+               object_class, PROP_CAN_COPY, "can-copy");
+       g_object_class_override_property (
+               object_class, PROP_CAN_CUT, "can-cut");
+       g_object_class_override_property (
+               object_class, PROP_CAN_PASTE, "can-paste");
+       g_object_class_override_property (
+               object_class, PROP_CAN_REDO, "can-redo");
+       g_object_class_override_property (
+               object_class, PROP_CAN_UNDO, "can-undo");
+       g_object_class_override_property (
+               object_class, PROP_CHANGED, "changed");
+       g_object_class_override_property (
+               object_class, PROP_HTML_MODE, "html-mode");
+       g_object_class_override_property (
+               object_class, PROP_EDITABLE, "editable");
+       g_object_class_override_property (
+               object_class, PROP_ALIGNMENT, "alignment");
+       g_object_class_override_property (
+               object_class, PROP_BACKGROUND_COLOR, "background-color");
+       g_object_class_override_property (
+               object_class, PROP_BLOCK_FORMAT, "block-format");
+       g_object_class_override_property (
+               object_class, PROP_BOLD, "bold");
+       g_object_class_override_property (
+               object_class, PROP_FONT_COLOR, "font-color");
+       g_object_class_override_property (
+               object_class, PROP_FONT_NAME, "font-name");
+       g_object_class_override_property (
+               object_class, PROP_FONT_SIZE, "font-size");
+       g_object_class_override_property (
+               object_class, PROP_INDENTED, "indented");
+       g_object_class_override_property (
+               object_class, PROP_ITALIC, "italic");
+       g_object_class_override_property (
+               object_class, PROP_MONOSPACED, "monospaced");
+       g_object_class_override_property (
+               object_class, PROP_STRIKETHROUGH, "strikethrough");
+       g_object_class_override_property (
+               object_class, PROP_SUBSCRIPT, "subscript");
+       g_object_class_override_property (
+               object_class, PROP_SUPERSCRIPT, "superscript");
+       g_object_class_override_property (
+               object_class, PROP_UNDERLINE, "underline");
+       g_object_class_override_property (
+               object_class, PROP_SPELL_CHECKER, "spell-checker");
+
+       /**
+        * EWebkitContentEditor:popup-event
+        *
+        * Emitted whenever a context menu is requested.
+        */
+       signals[POPUP_EVENT] = g_signal_new (
+               "popup-event",
+               G_TYPE_FROM_CLASS (class),
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (EWebKitContentEditorClass, popup_event),
+               g_signal_accumulator_true_handled, NULL,
+               e_marshal_BOOLEAN__BOXED,
+               G_TYPE_BOOLEAN, 1,
+               GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void
+e_webkit_content_editor_init (EWebKitContentEditor *wk_editor)
+{
+       GSettings *g_settings;
+       GSettingsSchema *settings_schema;
+
+       wk_editor->priv = E_WEBKIT_CONTENT_EDITOR_GET_PRIVATE (wk_editor);
+
+       wk_editor->priv->spell_checker = e_spell_checker_new ();
+       wk_editor->priv->old_settings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, 
(GDestroyNotify) g_variant_unref);
+
+       webkit_content_editor_watch_web_extension (wk_editor);
+
+       g_signal_connect (
+               wk_editor, "load-changed",
+               G_CALLBACK (webkit_content_editor_load_changed_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "copy-clipboard",
+               G_CALLBACK (webkit_content_editor_copy_cut_clipboard_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "cut-clipboard",
+               G_CALLBACK (webkit_content_editor_copy_cut_clipboard_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "paste-clipboard",
+               G_CALLBACK (webkit_content_editor_paste_clipboard_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "paste-primary-clipboard",
+               G_CALLBACK (webkit_content_editor_paste_primary_clipboard_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "context-menu",
+               G_CALLBACK (webkit_content_editor_context_menu_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "mouse-target-changed",
+               G_CALLBACK (webkit_content_editor_mouse_target_changed_cb), NULL);
+
+       g_signal_connect (
+               wk_editor, "drag-end",
+               G_CALLBACK (webkit_content_editor_drag_end_cb), NULL);
+
+       wk_editor->priv->owner_change_primary_clipboard_cb_id = g_signal_connect (
+               gtk_clipboard_get (GDK_SELECTION_PRIMARY), "owner-change",
+               G_CALLBACK (webkit_content_editor_primary_clipboard_owner_change_cb), wk_editor);
+
+       wk_editor->priv->owner_change_clipboard_cb_id = g_signal_connect (
+               gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), "owner-change",
+               G_CALLBACK (webkit_content_editor_clipboard_owner_change_cb), wk_editor);
+
+       g_settings = e_util_ref_settings ("org.gnome.desktop.interface");
+       g_signal_connect (
+               g_settings, "changed::font-name",
+               G_CALLBACK (webkit_content_editor_settings_changed_cb), wk_editor);
+       g_signal_connect (
+               g_settings, "changed::monospace-font-name",
+               G_CALLBACK (webkit_content_editor_settings_changed_cb), wk_editor);
+       wk_editor->priv->font_settings = g_settings;
+
+       g_settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       wk_editor->priv->mail_settings = g_settings;
+
+       /* This schema is optional.  Use if available. */
+       settings_schema = g_settings_schema_source_lookup (
+               g_settings_schema_source_get_default (),
+               "org.gnome.settings-daemon.plugins.xsettings", FALSE);
+       if (settings_schema != NULL) {
+               g_settings = e_util_ref_settings ("org.gnome.settings-daemon.plugins.xsettings");
+               g_signal_connect (
+                       g_settings, "changed::antialiasing",
+                       G_CALLBACK (webkit_content_editor_settings_changed_cb), wk_editor);
+               wk_editor->priv->aliasing_settings = g_settings;
+       }
+
+       wk_editor->priv->html_mode = FALSE;
+       wk_editor->priv->changed = FALSE;
+       wk_editor->priv->can_copy = FALSE;
+       wk_editor->priv->can_cut = FALSE;
+       wk_editor->priv->can_paste = FALSE;
+       wk_editor->priv->can_undo = FALSE;
+       wk_editor->priv->can_redo = FALSE;
+       wk_editor->priv->copy_paste_clipboard_in_view = FALSE;
+       wk_editor->priv->copy_paste_primary_in_view = FALSE;
+       wk_editor->priv->copy_action_triggered = FALSE;
+       wk_editor->priv->pasting_primary_clipboard = FALSE;
+       wk_editor->priv->content_flags = 0;
+       wk_editor->priv->current_user_stylesheet = NULL;
+       wk_editor->priv->emit_load_finished_when_extension_is_ready = FALSE;
+
+       wk_editor->priv->font_color = gdk_rgba_copy (&black);
+       wk_editor->priv->font_color = gdk_rgba_copy (&white);
+       wk_editor->priv->font_name = NULL;
+       wk_editor->priv->font_size = E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
+       wk_editor->priv->block_format = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
+       wk_editor->priv->alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
+
+       wk_editor->priv->web_extension_selection_changed_cb_id = 0;
+       wk_editor->priv->web_extension_content_changed_cb_id = 0;
+}
+
+static void
+e_webkit_content_editor_content_editor_init (EContentEditorInterface *iface)
+{
+       iface->get_find_controller = webkit_content_editor_get_find_controller;
+       iface->insert_content = webkit_content_editor_insert_content;
+       iface->get_content = webkit_content_editor_get_content;
+       iface->insert_image = webkit_content_editor_insert_image;
+       iface->insert_image_from_mime_part = webkit_content_editor_insert_image_from_mime_part;
+       iface->insert_emoticon = webkit_content_editor_insert_emoticon;
+       iface->set_current_content_flags = webkit_content_editor_set_current_content_flags;
+       iface->get_current_content_flags = webkit_content_editor_get_current_content_flags;
+       iface->move_caret_on_coordinates = webkit_content_editor_move_caret_on_coordinates;
+       iface->set_changed = webkit_content_editor_set_changed;
+       iface->get_changed = webkit_content_editor_get_changed;
+       iface->cut = webkit_content_editor_cut;
+       iface->copy = webkit_content_editor_copy;
+       iface->paste = webkit_content_editor_paste;
+       iface->paste_prefer_text_html = webkit_content_editor_paste_prefer_text_html;
+       iface->reconnect_paste_clipboard_signals = webkit_content_editor_reconnect_paste_clipboard_signals;
+       iface->can_undo = webkit_content_editor_can_undo;
+       iface->undo = webkit_content_editor_undo;
+       iface->can_redo = webkit_content_editor_can_redo;
+       iface->redo = webkit_content_editor_redo;
+       iface->clear_undo_redo_history = webkit_content_editor_clear_undo_redo_history;
+       iface->set_html_mode = webkit_content_editor_set_html_mode;
+       iface->get_html_mode = webkit_content_editor_get_html_mode;
+       iface->get_spell_checker = webkit_content_editor_get_spell_checker;
+       iface->set_spell_checking_languages = webkit_content_editor_set_spell_checking_languages;
+       iface->set_spell_check = webkit_content_editor_set_spell_check;
+       iface->get_spell_check = webkit_content_editor_get_spell_check;
+       iface->selection_has_text = webkit_content_editor_selection_has_text;
+//     iface->selection_get_text = webkit_content_editor_selection_get_text;
+       iface->get_caret_word = webkit_content_editor_get_caret_word;
+       iface->replace_caret_word = webkit_content_editor_replace_caret_word;
+       iface->select_all = webkit_content_editor_select_all;
+       iface->selection_is_indented = webkit_content_editor_selection_is_indented;
+       iface->selection_indent = webkit_content_editor_selection_indent;
+       iface->selection_unindent = webkit_content_editor_selection_unindent;
+//     iface->create_link = webkit_content_editor_create_link;
+       iface->selection_unlink = webkit_content_editor_selection_unlink;
+       iface->selection_replace = webkit_content_editor_selection_replace;
+       iface->selection_save = webkit_content_editor_selection_save;
+       iface->selection_restore = webkit_content_editor_selection_restore;
+       iface->selection_wrap = webkit_content_editor_selection_wrap;
+       iface->show_inspector = webkit_content_editor_show_inspector;
+       iface->get_caret_position = webkit_content_editor_get_caret_position;
+       iface->get_caret_offset = webkit_content_editor_get_caret_offset;
+       iface->update_fonts = webkit_content_editor_update_fonts;
+       iface->is_editable = webkit_content_editor_is_editable;
+       iface->set_editable = webkit_content_editor_set_editable;
+       iface->get_current_signature_uid =  webkit_content_editor_get_current_signature_uid;
+       iface->is_ready = webkit_content_editor_is_ready;
+       iface->insert_signature = webkit_content_editor_insert_signature;
+       iface->set_alignment = webkit_content_editor_set_alignment;
+       iface->get_alignment = webkit_content_editor_get_alignment;
+       iface->set_block_format = webkit_content_editor_set_block_format;
+       iface->get_block_format = webkit_content_editor_get_block_format;
+       iface->set_background_color = webkit_content_editor_set_background_color;
+       iface->get_background_color = webkit_content_editor_get_background_color;
+       iface->set_font_name = webkit_content_editor_set_font_name;
+       iface->get_font_name = webkit_content_editor_get_font_name;
+       iface->set_font_color = webkit_content_editor_set_font_color;
+       iface->get_font_color = webkit_content_editor_get_font_color;
+       iface->set_font_size = webkit_content_editor_set_font_size;
+       iface->get_font_size = webkit_content_editor_get_font_size;
+       iface->set_bold = webkit_content_editor_set_bold;
+       iface->is_bold = webkit_content_editor_is_bold;
+       iface->set_italic = webkit_content_editor_set_italic;
+       iface->is_italic = webkit_content_editor_is_italic;
+       iface->set_monospaced = webkit_content_editor_set_monospaced;
+       iface->is_monospaced = webkit_content_editor_is_monospaced;
+       iface->set_strikethrough = webkit_content_editor_set_strikethrough;
+       iface->is_strikethrough = webkit_content_editor_is_strikethrough;
+       iface->set_subscript = webkit_content_editor_set_subscript;
+       iface->is_subscript = webkit_content_editor_is_subscript;
+       iface->set_superscript = webkit_content_editor_set_superscript;
+       iface->is_superscript = webkit_content_editor_is_superscript;
+       iface->set_underline = webkit_content_editor_set_underline;
+       iface->is_underline = webkit_content_editor_is_underline;
+       iface->delete_cell_contents = webkit_content_editor_delete_cell_contents;
+       iface->delete_column = webkit_content_editor_delete_column;
+       iface->delete_row = webkit_content_editor_delete_row;
+       iface->delete_table = webkit_content_editor_delete_table;
+       iface->insert_column_after = webkit_content_editor_insert_column_after;
+       iface->insert_column_before = webkit_content_editor_insert_column_before;
+       iface->insert_row_above = webkit_content_editor_insert_row_above;
+       iface->insert_row_below = webkit_content_editor_insert_row_below;
+       iface->on_h_rule_dialog_open = webkit_content_editor_on_h_rule_dialog_open;
+       iface->on_h_rule_dialog_close = webkit_content_editor_on_h_rule_dialog_close;
+       iface->h_rule_set_align = webkit_content_editor_h_rule_set_align;
+       iface->h_rule_get_align = webkit_content_editor_h_rule_get_align;
+       iface->h_rule_set_size = webkit_content_editor_h_rule_set_size;
+       iface->h_rule_get_size = webkit_content_editor_h_rule_get_size;
+       iface->h_rule_set_width = webkit_content_editor_h_rule_set_width;
+       iface->h_rule_get_width = webkit_content_editor_h_rule_get_width;
+       iface->h_rule_set_no_shade = webkit_content_editor_h_rule_set_no_shade;
+       iface->h_rule_get_no_shade = webkit_content_editor_h_rule_get_no_shade;
+       iface->on_image_dialog_open = webkit_content_editor_on_image_dialog_open;
+       iface->on_image_dialog_close = webkit_content_editor_on_image_dialog_close;
+       iface->image_set_src = webkit_content_editor_image_set_src;
+       iface->image_get_src = webkit_content_editor_image_get_src;
+       iface->image_set_alt = webkit_content_editor_image_set_alt;
+       iface->image_get_alt = webkit_content_editor_image_get_alt;
+       iface->image_set_url = webkit_content_editor_image_set_url;
+       iface->image_get_url = webkit_content_editor_image_get_url;
+       iface->image_set_vspace = webkit_content_editor_image_set_vspace;
+       iface->image_get_vspace = webkit_content_editor_image_get_vspace;
+       iface->image_set_hspace = webkit_content_editor_image_set_hspace;
+       iface->image_get_hspace = webkit_content_editor_image_get_hspace;
+       iface->image_set_border = webkit_content_editor_image_set_border;
+       iface->image_get_border = webkit_content_editor_image_get_border;
+       iface->image_set_align = webkit_content_editor_image_set_align;
+       iface->image_get_align = webkit_content_editor_image_get_align;
+       iface->image_get_natural_width = webkit_content_editor_image_get_natural_width;
+       iface->image_get_natural_height = webkit_content_editor_image_get_natural_height;
+       iface->image_set_height = webkit_content_editor_image_set_height;
+       iface->image_set_width = webkit_content_editor_image_set_width;
+       iface->image_set_height_follow = webkit_content_editor_image_set_height_follow;
+       iface->image_set_width_follow = webkit_content_editor_image_set_width_follow;
+       iface->image_get_width = webkit_content_editor_image_get_width;
+       iface->image_get_height = webkit_content_editor_image_get_height;
+       iface->link_set_values = webkit_content_editor_link_set_values;
+       iface->link_get_values = webkit_content_editor_link_get_values;
+       iface->page_set_text_color = webkit_content_editor_page_set_text_color;
+       iface->page_get_text_color = webkit_content_editor_page_get_text_color;
+       iface->page_set_background_color = webkit_content_editor_page_set_background_color;
+       iface->page_get_background_color = webkit_content_editor_page_get_background_color;
+       iface->page_set_link_color = webkit_content_editor_page_set_link_color;
+       iface->page_get_link_color = webkit_content_editor_page_get_link_color;
+       iface->page_set_visited_link_color = webkit_content_editor_page_set_visited_link_color;
+       iface->page_get_visited_link_color = webkit_content_editor_page_get_visited_link_color;
+       iface->page_set_background_image_uri = webkit_content_editor_page_set_background_image_uri;
+       iface->page_get_background_image_uri = webkit_content_editor_page_get_background_image_uri;
+       iface->on_page_dialog_open = webkit_content_editor_on_page_dialog_open;
+       iface->on_page_dialog_close = webkit_content_editor_on_page_dialog_close;
+       iface->on_cell_dialog_open = webkit_content_editor_on_cell_dialog_open;
+       iface->on_cell_dialog_close = webkit_content_editor_on_cell_dialog_close;
+       iface->cell_set_v_align = webkit_content_editor_cell_set_v_align;
+       iface->cell_get_v_align = webkit_content_editor_cell_get_v_align;
+       iface->cell_set_align = webkit_content_editor_cell_set_align;
+       iface->cell_get_align = webkit_content_editor_cell_get_align;
+       iface->cell_set_wrap = webkit_content_editor_cell_set_wrap;
+       iface->cell_get_wrap = webkit_content_editor_cell_get_wrap;
+       iface->cell_set_header_style = webkit_content_editor_cell_set_header_style;
+       iface->cell_is_header = webkit_content_editor_cell_is_header;
+       iface->cell_get_width = webkit_content_editor_cell_get_width;
+       iface->cell_set_width = webkit_content_editor_cell_set_width;
+       iface->cell_get_row_span = webkit_content_editor_cell_get_row_span;
+       iface->cell_set_row_span = webkit_content_editor_cell_set_row_span;
+       iface->cell_get_col_span = webkit_content_editor_cell_get_col_span;
+       iface->cell_set_col_span = webkit_content_editor_cell_set_col_span;
+       iface->cell_get_background_image_uri = webkit_content_editor_cell_get_background_image_uri;
+       iface->cell_set_background_image_uri = webkit_content_editor_cell_set_background_image_uri;
+       iface->cell_get_background_color = webkit_content_editor_cell_get_background_color;
+       iface->cell_set_background_color = webkit_content_editor_cell_set_background_color;
+       iface->table_set_row_count = webkit_content_editor_table_set_row_count;
+       iface->table_get_row_count = webkit_content_editor_table_get_row_count;
+       iface->table_set_column_count = webkit_content_editor_table_set_column_count;
+       iface->table_get_column_count = webkit_content_editor_table_get_column_count;
+       iface->table_set_width = webkit_content_editor_table_set_width;
+       iface->table_get_width = webkit_content_editor_table_get_width;
+       iface->table_set_align = webkit_content_editor_table_set_align;
+       iface->table_get_align = webkit_content_editor_table_get_align;
+       iface->table_set_padding = webkit_content_editor_table_set_padding;
+       iface->table_get_padding = webkit_content_editor_table_get_padding;
+       iface->table_set_spacing = webkit_content_editor_table_set_spacing;
+       iface->table_get_spacing = webkit_content_editor_table_get_spacing;
+       iface->table_set_border = webkit_content_editor_table_set_border;
+       iface->table_get_border = webkit_content_editor_table_get_border;
+       iface->table_get_background_image_uri = webkit_content_editor_table_get_background_image_uri;
+       iface->table_set_background_image_uri = webkit_content_editor_table_set_background_image_uri;
+       iface->table_get_background_color = webkit_content_editor_table_get_background_color;
+       iface->table_set_background_color = webkit_content_editor_table_set_background_color;
+       iface->on_table_dialog_open = webkit_content_editor_on_table_dialog_open;
+       iface->on_table_dialog_close = webkit_content_editor_on_table_dialog_close;
+       iface->on_spell_check_dialog_open = webkit_content_editor_on_spell_check_dialog_open;
+       iface->on_spell_check_dialog_close = webkit_content_editor_on_spell_check_dialog_close;
+       iface->spell_check_next_word = webkit_content_editor_spell_check_next_word;
+       iface->spell_check_prev_word = webkit_content_editor_spell_check_prev_word;
+       iface->on_replace_dialog_open = webkit_content_editor_on_replace_dialog_open;
+       iface->on_replace_dialog_close = webkit_content_editor_on_replace_dialog_close;
+       iface->on_find_dialog_open = webkit_content_editor_on_find_dialog_open;
+       iface->on_find_dialog_close = webkit_content_editor_on_find_dialog_close;
+}
diff --git a/modules/webkit-content-editor/e-webkit-content-editor.h 
b/modules/webkit-content-editor/e-webkit-content-editor.h
new file mode 100644
index 0000000..aa2e305
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-content-editor.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef E_WEBKIT_CONTENT_EDITOR_H
+#define E_WEBKIT_CONTENT_EDITOR_H
+
+#include <webkit2/webkit2.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEBKIT_CONTENT_EDITOR \
+       (e_webkit_content_editor_get_type ())
+#define E_WEBKIT_CONTENT_EDITOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR, EWebKitContentEditor))
+#define E_WEBKIT_CONTENT_EDITOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_WEBKIT_CONTENT_EDITOR, EWebKitContentEditorClass))
+#define E_IS_WEBKIT_CONTENT_EDITOR(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR))
+#define E_IS_WEBKIT_CONTENT_EDITOR_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_WEBKIT_CONTENT_EDITOR))
+#define E_WEBKIT_CONTENT_EDITOR_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_WEBKIT_CONTENT_EDITOR, EWebKitContentEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWebKitContentEditor EWebKitContentEditor;
+typedef struct _EWebKitContentEditorClass EWebKitContentEditorClass;
+typedef struct _EWebKitContentEditorPrivate EWebKitContentEditorPrivate;
+
+struct _EWebKitContentEditor {
+       WebKitWebView parent;
+       EWebKitContentEditorPrivate *priv;
+};
+
+struct _EWebKitContentEditorClass {
+       WebKitWebViewClass parent_class;
+
+       gboolean        (*popup_event)          (EWebKitContentEditor *wk_editor,
+                                                GdkEventButton *event);
+       void            (*paste_primary_clipboard)
+                                               (EWebKitContentEditor *wk_editor);
+};
+
+GType          e_webkit_content_editor_get_type        (void) G_GNUC_CONST;
+
+EWebKitContentEditor *
+               e_webkit_content_editor_new             (void);
+
+G_END_DECLS
+
+#endif /* E_WEBKIT_CONTENT_EDITOR_H */
diff --git a/modules/webkit-content-editor/e-webkit-editor-extension.c 
b/modules/webkit-content-editor/e-webkit-editor-extension.c
new file mode 100644
index 0000000..6ef7059
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-editor-extension.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-webkit-editor-extension.h"
+#include "e-webkit-content-editor.h"
+
+#include <e-util/e-util.h>
+
+#define E_WEBKIT_EDITOR_EXTENSION_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_WEBKIT_EDITOR_EXTENSION, EWebKitEditorExtensionPrivate))
+
+struct _EWebKitEditorExtensionPrivate {
+       EWebKitContentEditor *wk_editor;
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+       EWebKitEditorExtension,
+       e_webkit_editor_extension,
+       E_TYPE_EXTENSION)
+
+static void
+e_webkit_editor_extension_init (EWebKitEditorExtension *editor_extension)
+{
+       editor_extension->priv = E_WEBKIT_EDITOR_EXTENSION_GET_PRIVATE (editor_extension);
+
+       editor_extension->priv->wk_editor = g_object_ref_sink (e_webkit_content_editor_new ());
+}
+
+static void
+webkit_editor_extension_constructed (GObject *object)
+{
+       EWebKitEditorExtensionPrivate *priv;
+       EExtensible *extensible;
+
+       /* Chain up to parent's constructed() method. */
+       G_OBJECT_CLASS (e_webkit_editor_extension_parent_class)->constructed (object);
+
+       priv = E_WEBKIT_EDITOR_EXTENSION_GET_PRIVATE (object);
+       extensible = e_extension_get_extensible (E_EXTENSION (object));
+
+       e_html_editor_register_content_editor (
+               E_HTML_EDITOR (extensible), E_CONTENT_EDITOR (priv->wk_editor));
+}
+
+static void
+webkit_editor_extension_dispose (GObject *object)
+{
+       EWebKitEditorExtensionPrivate *priv;
+
+       priv = E_WEBKIT_EDITOR_EXTENSION_GET_PRIVATE (object);
+
+       g_clear_object (&priv->wk_editor);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (e_webkit_editor_extension_parent_class)->dispose (object);
+}
+
+static void
+e_webkit_editor_extension_class_init (EWebKitEditorExtensionClass *class)
+{
+       EExtensionClass *extension_class;
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (EWebKitEditorExtensionPrivate));
+
+       extension_class = E_EXTENSION_CLASS (class);
+       extension_class->extensible_type = E_TYPE_HTML_EDITOR;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->dispose = webkit_editor_extension_dispose;
+       object_class->constructed = webkit_editor_extension_constructed;
+}
+
+static void
+e_webkit_editor_extension_class_finalize (EWebKitEditorExtensionClass *class)
+{
+}
+
+void
+e_webkit_editor_extension_type_register (GTypeModule *type_module)
+{
+       e_webkit_editor_extension_register_type (type_module);
+}
diff --git a/modules/webkit-content-editor/e-webkit-editor-extension.h 
b/modules/webkit-content-editor/e-webkit-editor-extension.h
new file mode 100644
index 0000000..ff5d781
--- /dev/null
+++ b/modules/webkit-content-editor/e-webkit-editor-extension.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef E_WEBKIT_EDITOR_EXTENSION_H
+#define E_WEBKIT_EDITOR_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEBKIT_EDITOR_EXTENSION \
+       (e_webkit_editor_extension_get_type ())
+#define E_WEBKIT_EDITOR_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_WEBKIT_EDITOR_EXTENSION, EWebKitEditorExtension))
+#define E_WEBKIT_EDITOR_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_WEBKIT_EDITOR_EXTENSION, EWebKitEditorExtensionClass))
+#define E_IS_WEBKIT_EDITOR_EXTENSION(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_WEBKIT_EDITOR_EXTENSION))
+#define E_IS_WEBKIT_EDITOR_EXTENSION_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_WEBKIT_EDITOR_EXTENSION))
+#define E_WEBKIT_EDITOR_EXTENSION_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_WEBKIT_EDITOR_EXTENSION, EWebKitEditorExtensionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWebKitEditorExtension EWebKitEditorExtension;
+typedef struct _EWebKitEditorExtensionClass EWebKitEditorExtensionClass;
+typedef struct _EWebKitEditorExtensionPrivate EWebKitEditorExtensionPrivate;
+
+struct _EWebKitEditorExtension {
+       EExtension parent;
+
+       EWebKitEditorExtensionPrivate *priv;
+};
+
+struct _EWebKitEditorExtensionClass {
+       EExtensionClass parent_class;
+};
+
+GType          e_webkit_editor_extension_get_type      (void) G_GNUC_CONST;
+void           e_webkit_editor_extension_type_register (GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_WEBKIT_EDITOR_EXTENSION_H */
diff --git a/modules/webkit-content-editor/evolution-module-webkit-content-editor.c 
b/modules/webkit-content-editor/evolution-module-webkit-content-editor.c
new file mode 100644
index 0000000..116903f
--- /dev/null
+++ b/modules/webkit-content-editor/evolution-module-webkit-content-editor.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-webkit-editor-extension.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+       e_webkit_editor_extension_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c
index 1e8a109..6515fe2 100644
--- a/plugins/external-editor/external-editor.c
+++ b/plugins/external-editor/external-editor.c
@@ -150,16 +150,16 @@ enable_disable_composer (EMsgComposer *composer,
                          gboolean enable)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        GtkAction *action;
        GtkActionGroup *action_group;
 
        g_return_if_fail (E_IS_MSG_COMPOSER (composer));
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), enable);
+       e_content_editor_set_editable (cnt_editor, enable);
 
        action = E_HTML_EDITOR_ACTION_EDIT_MENU (editor);
        gtk_action_set_sensitive (action, enable);
@@ -192,20 +192,20 @@ update_composer_text (GArray *array)
 {
        EMsgComposer *composer;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
        gchar *text;
 
        composer = g_array_index (array, gpointer, 0);
        text = g_array_index (array, gpointer, 1);
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        e_msg_composer_set_body_text (composer, text, FALSE);
 
        enable_composer (composer);
 
-       e_html_editor_view_set_changed (view, TRUE);
+       e_content_editor_set_changed (cnt_editor, TRUE);
 
        g_free (text);
 
@@ -254,91 +254,6 @@ numlines (const gchar *text,
        return lineno;
 }
 
-static gint32
-get_caret_offset (EHTMLEditorView *view)
-{
-       GDBusProxy *web_extension;
-       gint position = 0;
-       GVariant *result;
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return 0;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMGetCaretOffset",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               position = g_variant_get_int32 (result);
-               g_variant_unref (result);
-       }
-
-       return position;
-}
-
-static gint32
-get_caret_position (EHTMLEditorView *view)
-{
-       GDBusProxy *web_extension;
-       gint position = 0;
-       GVariant *result;
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return 0;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMGetCaretPosition",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result) {
-               position = g_variant_get_int32 (result);
-               g_variant_unref (result);
-       }
-
-       return position;
-}
-
-static void
-clear_undo_redo_history (EHTMLEditorView *view)
-{
-       GDBusProxy *web_extension;
-       GVariant *result;
-
-       web_extension = e_html_editor_view_get_web_extension_proxy (view);
-       if (!web_extension)
-               return;
-
-       result = g_dbus_proxy_call_sync (
-               web_extension,
-               "DOMClearUndoRedoHistory",
-               g_variant_new (
-                       "(t)",
-                       webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
-               G_DBUS_CALL_FLAGS_NONE,
-               -1,
-               NULL,
-               NULL);
-
-       if (result)
-               g_variant_unref (result);
-}
-
 static gboolean external_editor_running = FALSE;
 static GMutex external_editor_running_lock;
 
@@ -352,10 +267,10 @@ external_editor_thread (gpointer user_data)
        gchar *editor_cmd_line = NULL, *editor_cmd = NULL, *content;
        gint fd, position = -1, offset = -1;
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* prefix temp files with evo so .*vimrc can be setup to recognize them */
        fd = g_file_open_tmp ("evoXXXXXX", &filename, NULL);
@@ -364,7 +279,11 @@ external_editor_thread (gpointer user_data)
                d (printf ("\n\aTemporary-file Name is : [%s] \n\a", filename));
 
                /* Push the text (if there is one) from the composer to the file */
-               content = e_html_editor_view_get_text_plain (view);
+               content = e_content_editor_get_content (
+                       cnt_editor,
+                       E_CONTENT_EDITOR_GET_TEXT_PLAIN |
+                       E_CONTENT_EDITOR_GET_PROCESSED,
+                       NULL);
                if (content && *content)
                        g_file_set_contents (filename, content, strlen (content), NULL);
        } else {
@@ -394,14 +313,14 @@ external_editor_thread (gpointer user_data)
        g_object_unref (settings);
 
        if (g_strrstr (editor_cmd, "vim") != NULL &&
-           ((position = get_caret_position (view)) > 0)) {
+           ((position = e_content_editor_get_caret_position (cnt_editor)) > 0)) {
                gchar *tmp = editor_cmd;
                gint lineno;
                gboolean set_nofork;
 
                set_nofork = g_strrstr (editor_cmd, "gvim") != NULL;
 
-               offset = get_caret_offset (view);
+               offset = e_content_editor_get_caret_offset (cnt_editor);
                /* Increment by 1 so that entering vim insert mode places you
                 * in the same entry position you were at in the html. */
                offset++;
@@ -488,7 +407,7 @@ finished:
 static void launch_editor (GtkAction *action, EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        d (printf ("\n\nexternal_editor plugin is launched \n\n"));
 
@@ -498,9 +417,9 @@ static void launch_editor (GtkAction *action, EMsgComposer *composer)
        }
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
-       clear_undo_redo_history (view);
+       e_content_editor_clear_undo_redo_history (cnt_editor);
        disable_composer (composer);
 
        g_mutex_lock (&external_editor_running_lock);
@@ -584,10 +503,10 @@ e_plugin_ui_init (GtkUIManager *manager,
                   EMsgComposer *composer)
 {
        EHTMLEditor *editor;
-       EHTMLEditorView *view;
+       EContentEditor *cnt_editor;
 
        editor = e_msg_composer_get_editor (composer);
-       view = e_html_editor_get_view (editor);
+       cnt_editor = e_html_editor_get_content_editor (editor);
 
        /* Add actions to the "composer" action group. */
        gtk_action_group_add_actions (
@@ -595,11 +514,11 @@ e_plugin_ui_init (GtkUIManager *manager,
                entries, G_N_ELEMENTS (entries), composer);
 
        g_signal_connect (
-               view, "key_press_event",
+               cnt_editor, "key_press_event",
                G_CALLBACK (key_press_cb), composer);
 
        g_signal_connect (
-               view, "delete-event",
+               cnt_editor, "delete-event",
                G_CALLBACK (delete_cb), composer);
 
        return TRUE;
diff --git a/web-extensions/composer/e-composer-private-dom-functions.c 
b/web-extensions/composer/e-composer-private-dom-functions.c
index c83f7f2..4b1bc78 100644
--- a/web-extensions/composer/e-composer-private-dom-functions.c
+++ b/web-extensions/composer/e-composer-private-dom-functions.c
@@ -22,17 +22,20 @@
 
 #include <string.h>
 
+#include "e-composer-private-dom-functions.h"
+
+#include "e-html-editor-web-extension.h"
+#include "e-html-editor-selection-dom-functions.h"
+#include "e-html-editor-view-dom-functions.h"
+
 #define WEBKIT_DOM_USE_UNSTABLE_API
 #include <webkitdom/WebKitDOMDOMSelection.h>
 #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
+#include <webkitdom/WebKitDOMHTMLElementUnstable.h>
 
 #include <web-extensions/e-dom-utils.h>
 
-#include "e-html-editor-web-extension.h"
-#include "e-html-editor-selection-dom-functions.h"
-#include "e-html-editor-view-dom-functions.h"
-
-#include "e-composer-private-dom-functions.h"
+#include <camel/camel.h>
 
 gchar *
 dom_remove_signatures (WebKitDOMDocument *document,
@@ -104,24 +107,72 @@ prepare_top_signature_spacer (WebKitDOMDocument *document,
        return element;
 }
 
+static gboolean
+add_signature_delimiter (void)
+{
+       gboolean ret_val;
+       GSettings *settings;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       ret_val = !g_settings_get_boolean (settings, "composer-no-signature-delim");
+       g_object_unref (settings);
+
+       return ret_val;
+}
+
+static gboolean
+use_top_signature (void)
+{
+       gboolean ret_val;
+       GSettings *settings;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       ret_val = g_settings_get_boolean (settings, "composer-top-signature");
+       g_object_unref (settings);
+
+       return ret_val;
+}
+
+static gboolean
+start_typing_at_bottom (void)
+{
+       gboolean ret_val;
+       GSettings *settings;
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       ret_val = g_settings_get_boolean (settings, "composer-reply-start-bottom");
+       g_object_unref (settings);
+
+       return ret_val;
+}
+
 static void
-composer_move_caret (WebKitDOMDocument *document,
-                     EHTMLEditorWebExtension *extension,
-                     gboolean top_signature,
-                    gboolean start_bottom)
+move_caret_after_signature_inserted (WebKitDOMDocument *document,
+                                     EHTMLEditorWebExtension *extension)
 {
+       EContentEditorContentFlags flags;
        gboolean is_message_from_draft;
        gboolean is_message_from_edit_as_new;
        gboolean is_from_new_message;
+       gboolean top_signature;
+       gboolean start_bottom;
        gboolean has_paragraphs_in_body = TRUE;
        WebKitDOMElement *element, *signature;
        WebKitDOMHTMLElement *body;
        WebKitDOMNodeList *paragraphs;
 
-       is_message_from_draft = e_html_editor_web_extension_is_message_from_draft (extension);
-       is_message_from_edit_as_new =
-               e_html_editor_web_extension_is_message_from_edit_as_new (extension);
-       is_from_new_message = e_html_editor_web_extension_is_from_new_message (extension);
+       flags = e_html_editor_web_extension_get_current_content_flags (extension);
+
+       is_message_from_draft = (flags & E_CONTENT_EDITOR_MESSAGE_DRAFT);
+       is_message_from_edit_as_new = (flags & E_CONTENT_EDITOR_MESSAGE_EDIT_AS_NEW);
+       is_from_new_message = (flags & E_CONTENT_EDITOR_MESSAGE_NEW);
+
+       top_signature =
+               use_top_signature () &&
+               !is_message_from_edit_as_new &&
+               !is_from_new_message;
+
+       start_bottom = start_typing_at_bottom ();
 
        body = webkit_dom_document_get_body (document);
        webkit_dom_element_set_attribute (
@@ -280,43 +331,230 @@ composer_move_caret (WebKitDOMDocument *document,
                g_clear_object (&dom_selection);
                g_clear_object (&dom_window);
                g_clear_object (&range);
-
-               if (start_bottom)
-                       dom_scroll_to_caret (document);
        }
 
+       if (start_bottom)
+               dom_scroll_to_caret (document);
+
        dom_force_spell_check_in_viewport (document, extension);
        e_html_editor_web_extension_unblock_selection_changed_callback (extension);
 }
 
-void
+gchar *
 dom_insert_signature (WebKitDOMDocument *document,
                       EHTMLEditorWebExtension *extension,
-                      const gchar *signature_html,
-                      gboolean top_signature,
-                     gboolean start_bottom)
+                      const gchar *content,
+                     gboolean is_html,
+                     const gchar *id,
+                     gboolean *set_signature_from_message,
+                     gboolean *check_if_signature_is_changed,
+                     gboolean *ignore_next_signature_change)
 {
-       WebKitDOMElement *element;
+       EContentEditorContentFlags flags;
+       gchar *new_signature_id = NULL;
+       gchar *signature_text = NULL;
+       gboolean top_signature, html_mode, is_message_from_edit_as_new;
+       gboolean is_message_from_draft, is_from_new_message;
+       gulong list_length, ii;
+       WebKitDOMElement *signature_to_insert;
+       WebKitDOMElement *insert_signature_in = NULL;
+       WebKitDOMElement *signature_wrapper;
+       WebKitDOMElement *element, *converted_signature = NULL;
        WebKitDOMHTMLElement *body;
+       WebKitDOMHTMLCollection *signatures;
 
-       g_return_if_fail (WEBKIT_DOM_IS_HTML_DOCUMENT (document));
-       g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
-       g_return_if_fail (signature_html && *signature_html);
+       g_return_val_if_fail (WEBKIT_DOM_IS_HTML_DOCUMENT (document), NULL);
+       g_return_val_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension), NULL);
+       g_return_val_if_fail (set_signature_from_message != NULL, NULL);
+       g_return_val_if_fail (check_if_signature_is_changed != NULL, NULL);
+       g_return_val_if_fail (ignore_next_signature_change != NULL, NULL);
+
+       flags = e_html_editor_web_extension_get_current_content_flags (extension);
+
+       is_message_from_draft = (flags & E_CONTENT_EDITOR_MESSAGE_DRAFT);
+       is_message_from_edit_as_new = (flags & E_CONTENT_EDITOR_MESSAGE_EDIT_AS_NEW);
+       is_from_new_message = (flags & E_CONTENT_EDITOR_MESSAGE_NEW);
+
+       /* "Edit as New Message" sets is_message_from_edit_as_new.
+        * Always put the signature at the bottom for that case. */
+       top_signature =
+               use_top_signature () &&
+               !is_message_from_edit_as_new &&
+               !is_from_new_message;
+
+       html_mode = e_html_editor_web_extension_get_html_mode (extension);
+
+       /* Create the DOM signature that is the same across all types of signatures. */
+       signature_to_insert = webkit_dom_document_create_element (document, "span", NULL);
+       webkit_dom_element_set_class_name (signature_to_insert, "-x-evo-signature");
+       /* The combo box active ID is the signature's ESource UID. */
+       webkit_dom_element_set_id (signature_to_insert, id);
+       insert_signature_in = signature_to_insert;
+
+       /* The signature has no content usually it means it is set to None. */
+       if (!content)
+               goto insert;
+
+       if (!is_html) {
+               gchar *html;
+
+               html = camel_text_to_html (content, 0, 0);
+               if (html) {
+                       signature_text = html;
+               } else
+                       signature_text = g_strdup (content);
 
-       body = webkit_dom_document_get_body (document);
-       element = webkit_dom_document_create_element (document, "DIV", NULL);
-       webkit_dom_element_set_class_name (element, "-x-evo-signature-wrapper");
+               insert_signature_in = webkit_dom_document_create_element (document, "pre", NULL);
+               webkit_dom_node_append_child (
+                       WEBKIT_DOM_NODE (signature_to_insert),
+                       WEBKIT_DOM_NODE (insert_signature_in),
+                       NULL);
+       } else
+               signature_text = g_strdup (content);
+
+
+       /* If inserting HTML signature in the plain text composer we have to convert it. */
+       if (is_html && !html_mode && !strstr (signature_text, "data-evo-signature-plain-text-mode")) {
+               gchar *inner_text;
 
-       webkit_dom_element_set_inner_html (element, signature_html, NULL);
+               /* Save the converted signature to avoid parsing it later again
+                * while inserting it into the view. */
+               converted_signature = webkit_dom_document_create_element (document, "pre", NULL);
+               webkit_dom_element_set_inner_html (converted_signature, signature_text, NULL);
+               dom_convert_element_from_html_to_plain_text (document, extension, converted_signature);
+               inner_text = webkit_dom_html_element_get_inner_text (WEBKIT_DOM_HTML_ELEMENT 
(converted_signature));
+
+               g_free (signature_text);
+               signature_text = inner_text ? g_strstrip (inner_text) : g_strdup ("");
+               /* because of the -- \n check */
+               is_html = FALSE;
+       }
+
+       /* The signature dash convention ("-- \n") is specified
+        * in the "Son of RFC 1036", section 4.3.2.
+        * http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html
+        */
+       if (add_signature_delimiter ()) {
+               const gchar *delim;
+               const gchar *delim_nl;
+
+               if (is_html) {
+                       delim = "-- <BR>";
+                       delim_nl = "\n-- <BR>";
+               } else {
+                       delim = "-- \n";
+                       delim_nl = "\n-- \n";
+               }
+
+               /* Skip the delimiter if the signature already has one. */
+               if (g_ascii_strncasecmp (signature_text, delim, strlen (delim)) == 0)
+                       ;  /* skip */
+               else if (e_util_strstrcase (signature_text, delim_nl) != NULL)
+                       ;  /* skip */
+               else
+                       webkit_dom_element_set_inner_html (insert_signature_in, delim, NULL);
+       }
+
+       if (converted_signature) {
+               WebKitDOMNode *node;
+
+               while ((node = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (converted_signature))))
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (insert_signature_in), node, NULL);
+               remove_node (WEBKIT_DOM_NODE (converted_signature));
+       } else
+               webkit_dom_html_element_insert_adjacent_html (
+                       WEBKIT_DOM_HTML_ELEMENT (insert_signature_in),
+                       "beforeend",
+                       signature_text,
+                       NULL);
+
+       element = webkit_dom_element_query_selector (
+               insert_signature_in, "[data-evo-signature-plain-text-mode]", NULL);
+       if (element)
+               webkit_dom_element_remove_attribute (
+                       element, "data-evo-signature-plain-text-mode");
+       g_free (signature_text);
+
+insert:
+       /* Remove the old signature and insert the new one. */
+       signatures = webkit_dom_document_get_elements_by_class_name_as_html_collection (
+               document, "-x-evo-signature-wrapper");
+       list_length = webkit_dom_html_collection_get_length (signatures);
+       for (ii = 0; ii < list_length; ii++) {
+               WebKitDOMNode *wrapper, *signature;
+
+               wrapper = webkit_dom_html_collection_item (signatures, ii);
+               signature = webkit_dom_node_get_first_child (wrapper);
+
+               /* Old messages will have the signature id in the name attribute, correct it. */
+               element_rename_attribute (WEBKIT_DOM_ELEMENT (signature), "name", "id");
+
+               /* When we are editing a message with signature, we need to unset the
+                * active signature id as if the signature in the message was edited
+                * by the user we would discard these changes. */
+               if (*set_signature_from_message &&
+                   (is_message_from_edit_as_new || is_message_from_draft)) {
+                       if (*check_if_signature_is_changed) {
+                               /* Normalize the signature that we want to insert as the one in the
+                                * message already is normalized. */
+                               webkit_dom_node_normalize (WEBKIT_DOM_NODE (signature_to_insert));
+                               if (!webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (signature_to_insert), 
signature)) {
+                                       /* Signature in the body is different than the one with the
+                                        * same id, so set the active signature to None and leave
+                                        * the signature that is in the body. */
+                                       new_signature_id = g_strdup ("none");
+                                       *ignore_next_signature_change = TRUE;
+                               }
+
+                               *check_if_signature_is_changed = FALSE;
+                               *set_signature_from_message = FALSE;
+                       } else {
+                               /* Load the signature and check if is it the same
+                                * as the signature in body or the user previously
+                                * changed it. */
+                               new_signature_id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (signature));
+                               *check_if_signature_is_changed = TRUE;
+                       }
+                       g_object_unref (wrapper);
+                       g_object_unref (signatures);
+
+                       return new_signature_id;
+               }
+
+               /* If the top signature was set we have to remove the newline
+                * that was inserted after it */
+               if (top_signature) {
+                       WebKitDOMElement *spacer;
+
+                       spacer = webkit_dom_document_query_selector (
+                               document, ".-x-evo-top-signature-spacer", NULL);
+                       if (spacer)
+                               remove_node_if_empty (WEBKIT_DOM_NODE (spacer));
+               }
+               /* We have to remove the div containing the span with signature */
+               remove_node (wrapper);
+               g_object_unref (wrapper);
+       }
+       g_object_unref (signatures);
+
+       body = webkit_dom_document_get_body (document);
+       signature_wrapper = webkit_dom_document_create_element (document, "div", NULL);
+       webkit_dom_node_append_child (
+               WEBKIT_DOM_NODE (signature_wrapper),
+               WEBKIT_DOM_NODE (signature_to_insert),
+               NULL);
+       webkit_dom_element_set_class_name (signature_wrapper, "-x-evo-signature-wrapper");
 
        if (top_signature) {
-               WebKitDOMNode *child =
-                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+               WebKitDOMNode *child;
 
-               if (start_bottom) {
+               child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+
+               if (start_typing_at_bottom ()) {
                        webkit_dom_node_insert_before (
                                WEBKIT_DOM_NODE (body),
-                               WEBKIT_DOM_NODE (element),
+                               WEBKIT_DOM_NODE (signature_wrapper),
                                child,
                                NULL);
                } else {
@@ -324,18 +562,27 @@ dom_insert_signature (WebKitDOMDocument *document,
                         * should be before the signature */
                        webkit_dom_node_insert_before (
                                WEBKIT_DOM_NODE (body),
-                               WEBKIT_DOM_NODE (element),
+                               WEBKIT_DOM_NODE (signature_wrapper),
                                child,
                                NULL);
                }
        } else {
                webkit_dom_node_append_child (
                        WEBKIT_DOM_NODE (body),
-                       WEBKIT_DOM_NODE (element),
+                       WEBKIT_DOM_NODE (signature_wrapper),
                        NULL);
        }
 
-       composer_move_caret (document, extension, top_signature, start_bottom);
+/* FIXME WK2 - dom_fix_file_uri_images
+       if (is_html && html_mode) {
+               e_html_editor_view_fix_file_uri_images (view);*/
+
+       move_caret_after_signature_inserted (document, extension);
+
+       /* Make sure the flag will be unset and won't influence user's choice */
+       *set_signature_from_message = FALSE;
+
+       return NULL;
 }
 
 static void
diff --git a/web-extensions/composer/e-composer-private-dom-functions.h 
b/web-extensions/composer/e-composer-private-dom-functions.h
index 30c9337..0c44130 100644
--- a/web-extensions/composer/e-composer-private-dom-functions.h
+++ b/web-extensions/composer/e-composer-private-dom-functions.h
@@ -28,12 +28,14 @@ G_BEGIN_DECLS
 gchar *                dom_remove_signatures           (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
                                                 gboolean top_signature);
-
-void           dom_insert_signature            (WebKitDOMDocument *document,
+gchar *                dom_insert_signature            (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
-                                                const gchar *signature_html,
-                                                gboolean top_signature,
-                                                gboolean start_bottom);
+                                                const gchar *content,
+                                                gboolean is_html,
+                                                const gchar *id,
+                                                gboolean *set_signature_from_message,
+                                                gboolean *check_if_signature_is_changed,
+                                                gboolean *ignore_next_signature_change);
 void           dom_save_drag_and_drop_history  (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 void           dom_clean_after_drag_and_drop   (WebKitDOMDocument *document,
diff --git a/web-extensions/composer/e-html-editor-cell-dialog-dom-functions.c 
b/web-extensions/composer/e-html-editor-cell-dialog-dom-functions.c
index 269eb4f..5928469 100644
--- a/web-extensions/composer/e-html-editor-cell-dialog-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-cell-dialog-dom-functions.c
@@ -27,13 +27,6 @@
 
 #include "e-html-editor-cell-dialog-dom-functions.h"
 
-enum {
-       SCOPE_CELL,
-       SCOPE_ROW,
-       SCOPE_COLUMN,
-       SCOPE_TABLE
-};
-
 typedef void (*DOMStrFunc) (WebKitDOMHTMLTableCellElement *cell, const gchar *val, gpointer user_data);
 typedef void (*DOMUlongFunc) (WebKitDOMHTMLTableCellElement *cell, gulong val, gpointer user_data);
 typedef void (*DOMBoolFunc) (WebKitDOMHTMLTableCellElement *cell, gboolean val, gpointer user_data);
@@ -89,20 +82,20 @@ for_each_cell_do (WebKitDOMElement *row,
 
 static void
 html_editor_cell_dialog_set_attribute (WebKitDOMDocument *document,
-                                       guint scope,
+                                       EContentEditorScope scope,
                                        gpointer func,
                                        GValue *value,
                                        gpointer user_data)
 {
        WebKitDOMElement *cell = get_current_cell_element (document);
 
-       if (scope == SCOPE_CELL) {
+       if (scope == E_CONTENT_EDITOR_SCOPE_CELL) {
 
                call_cell_dom_func (
                        WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell),
                        func, value, user_data);
 
-       } else if (scope == SCOPE_COLUMN) {
+       } else if (scope == E_CONTENT_EDITOR_SCOPE_COLUMN) {
                gulong index, ii, length;
                WebKitDOMElement *table;
                WebKitDOMHTMLCollection *rows;
@@ -140,7 +133,7 @@ html_editor_cell_dialog_set_attribute (WebKitDOMDocument *document,
                }
                g_object_unref (rows);
 
-       } else if (scope == SCOPE_ROW) {
+       } else if (scope == E_CONTENT_EDITOR_SCOPE_ROW) {
                WebKitDOMElement *row;
 
                row = dom_node_find_parent_element (WEBKIT_DOM_NODE (cell), "TR");
@@ -150,7 +143,7 @@ html_editor_cell_dialog_set_attribute (WebKitDOMDocument *document,
 
                for_each_cell_do (row, func, value, user_data);
 
-       } else if (scope == SCOPE_TABLE) {
+       } else if (scope == E_CONTENT_EDITOR_SCOPE_TABLE) {
                gulong ii, length;
                WebKitDOMElement *table;
                WebKitDOMHTMLCollection *rows;
@@ -312,7 +305,7 @@ e_html_editor_cell_dialog_save_history_on_exit (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_v_align (WebKitDOMDocument *document,
                                                const gchar *v_align,
-                                               guint scope)
+                                               EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -328,7 +321,7 @@ e_html_editor_cell_dialog_set_element_v_align (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_align (WebKitDOMDocument *document,
                                              const gchar *align,
-                                             guint scope)
+                                             EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -344,7 +337,7 @@ e_html_editor_cell_dialog_set_element_align (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_no_wrap (WebKitDOMDocument *document,
                                                gboolean wrap_text,
-                                               guint scope)
+                                               EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -358,7 +351,7 @@ e_html_editor_cell_dialog_set_element_no_wrap (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_header_style (WebKitDOMDocument *document,
                                                     gboolean header_style,
-                                                    guint scope)
+                                                    EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -372,7 +365,7 @@ e_html_editor_cell_dialog_set_element_header_style (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_width (WebKitDOMDocument *document,
                                              const gchar *width,
-                                             guint scope)
+                                             EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -388,7 +381,7 @@ e_html_editor_cell_dialog_set_element_width (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_col_span (WebKitDOMDocument *document,
                                                 glong span,
-                                                guint scope)
+                                                EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -402,7 +395,7 @@ e_html_editor_cell_dialog_set_element_col_span (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_row_span (WebKitDOMDocument *document,
                                                 glong span,
-                                                guint scope)
+                                                EContentEditorScope scope)
 {
        GValue val = { 0 };
 
@@ -416,7 +409,7 @@ e_html_editor_cell_dialog_set_element_row_span (WebKitDOMDocument *document,
 void
 e_html_editor_cell_dialog_set_element_bg_color (WebKitDOMDocument *document,
                                                 const gchar *color,
-                                                guint scope)
+                                                EContentEditorScope scope)
 {
        GValue val = { 0 };
 
diff --git a/web-extensions/composer/e-html-editor-link-dialog-dom-functions.c 
b/web-extensions/composer/e-html-editor-link-dialog-dom-functions.c
index 53626d3..b534d27 100644
--- a/web-extensions/composer/e-html-editor-link-dialog-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-link-dialog-dom-functions.c
@@ -38,62 +38,33 @@ e_html_editor_link_dialog_ok (WebKitDOMDocument *document,
                               const gchar *url,
                               const gchar *inner_text)
 {
-       WebKitDOMDOMWindow *dom_window;
-       WebKitDOMDOMSelection *dom_selection;
-       WebKitDOMRange *range;
        WebKitDOMElement *link;
 
-       dom_window = webkit_dom_document_get_default_view (document);
-       dom_selection = webkit_dom_dom_window_get_selection (dom_window);
-       g_object_unref (dom_window);
-
-       if (!dom_selection ||
-           (webkit_dom_dom_selection_get_range_count (dom_selection) == 0)) {
-               g_object_unref (dom_selection);
-               return;
-       }
-
-       range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-       link = dom_node_find_parent_element (
-               webkit_dom_range_get_start_container (range, NULL), "A");
-       if (!link) {
-               if ((webkit_dom_range_get_start_container (range, NULL) !=
-                       webkit_dom_range_get_end_container (range, NULL)) ||
-                   (webkit_dom_range_get_start_offset (range, NULL) !=
-                       webkit_dom_range_get_end_offset (range, NULL))) {
-
-                       WebKitDOMDocumentFragment *fragment;
-                       fragment = webkit_dom_range_extract_contents (range, NULL);
-                       link = dom_node_find_child_element (WEBKIT_DOM_NODE (fragment), "A");
-                       webkit_dom_range_insert_node (
-                               range, WEBKIT_DOM_NODE (fragment), NULL);
-
-                       webkit_dom_dom_selection_set_base_and_extent (
-                               dom_selection,
-                               webkit_dom_range_get_start_container (range, NULL),
-                               webkit_dom_range_get_start_offset (range, NULL),
-                               webkit_dom_range_get_end_container (range, NULL),
-                               webkit_dom_range_get_end_offset (range, NULL),
-                               NULL);
-               } else {
-                       WebKitDOMNode *node;
-                       /* get element that was clicked on */
-                       node = webkit_dom_range_get_common_ancestor_container (range, NULL);
-                       if (node && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
-                               link = dom_node_find_parent_element (node, "A");
-                               if (link && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (link))
-                                       link = NULL;
-                       } else
-                               link = WEBKIT_DOM_ELEMENT (node);
-               }
-       }
+       link = webkit_dom_document_get_element_by_id (document, "-x-evo-current-anchor");
 
        if (link) {
                webkit_dom_html_anchor_element_set_href (
                        WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link), url);
-               webkit_dom_element_set_inner_html (link, inner_text, NULL);
+               webkit_dom_html_element_set_inner_text (
+                       WEBKIT_DOM_HTML_ELEMENT (link), inner_text, NULL);
+               webkit_dom_element_remove_attribute (link, "id");
        } else {
                gchar *text;
+               WebKitDOMDOMWindow *dom_window;
+               WebKitDOMDOMSelection *dom_selection;
+               WebKitDOMRange *range;
+
+               dom_window = webkit_dom_document_get_default_view (document);
+               dom_selection = webkit_dom_dom_window_get_selection (dom_window);
+               g_object_unref (dom_window);
+
+               if (!dom_selection ||
+                   (webkit_dom_dom_selection_get_range_count (dom_selection) == 0)) {
+                       g_object_unref (dom_selection);
+                       return;
+               }
+
+               range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
 
                /* Check whether a text is selected or not */
                text = webkit_dom_range_get_text (range);
@@ -104,16 +75,15 @@ e_html_editor_link_dialog_ok (WebKitDOMDocument *document,
                                "<a href=\"%s\">%s</a>", url, inner_text);
 
                        dom_exec_command (
-                               document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html);
+                               document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_HTML, html);
                        g_free (html);
-
                }
 
                g_free (text);
-       }
 
-       g_object_unref (range);
-       g_object_unref (dom_selection);
+               g_object_unref (range);
+               g_object_unref (dom_selection);
+       }
 }
 
 GVariant *
@@ -170,6 +140,9 @@ e_html_editor_link_dialog_show (WebKitDOMDocument *document)
                text = webkit_dom_html_element_get_inner_text (
                                WEBKIT_DOM_HTML_ELEMENT (link));
 
+               webkit_dom_element_set_id (
+                       WEBKIT_DOM_ELEMENT (link), "-x-evo-current-anchor");
+
                result = g_variant_new ("(ss)", href, text);
 
                g_free (text);
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 aec8fb4..20d86b5 100644
--- a/web-extensions/composer/e-html-editor-selection-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-selection-dom-functions.c
@@ -190,7 +190,7 @@ dom_insert_base64_image (WebKitDOMDocument *document,
                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_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
        }
 
        dom_selection_save (document);
@@ -275,6 +275,317 @@ dom_insert_base64_image (WebKitDOMDocument *document,
 
        dom_selection_restore (document);
        dom_force_spell_check_for_current_paragraph (document, extension);
+       dom_scroll_to_caret (document);
+}
+
+/************************* image_load_and_insert_async() *************************/
+
+typedef struct _LoadContext LoadContext;
+
+struct _LoadContext {
+       WebKitDOMDocument *document;
+       EHTMLEditorWebExtension *extension;
+       GInputStream *input_stream;
+       GOutputStream *output_stream;
+       GFile *file;
+       GFileInfo *file_info;
+       goffset total_num_bytes;
+       gssize bytes_read;
+       const gchar *content_type;
+       const gchar *filename;
+       const gchar *selector;
+       gchar buffer[4096];
+};
+
+/* Forward Declaration */
+static void
+image_load_stream_read_cb (GInputStream *input_stream,
+                           GAsyncResult *result,
+                           LoadContext *load_context);
+
+static LoadContext *
+image_load_context_new (WebKitDOMDocument *document,
+                        EHTMLEditorWebExtension *extension)
+{
+       LoadContext *load_context;
+
+       load_context = g_slice_new0 (LoadContext);
+       load_context->document = document;
+       load_context->extension = extension;
+
+       return load_context;
+}
+
+static void
+image_load_context_free (LoadContext *load_context)
+{
+       if (load_context->input_stream != NULL)
+               g_object_unref (load_context->input_stream);
+
+       if (load_context->output_stream != NULL)
+               g_object_unref (load_context->output_stream);
+
+       if (load_context->file_info != NULL)
+               g_object_unref (load_context->file_info);
+
+       if (load_context->file != NULL)
+               g_object_unref (load_context->file);
+
+       g_slice_free (LoadContext, load_context);
+}
+
+static void
+image_load_finish (LoadContext *load_context)
+{
+       WebKitDOMDocument *document;
+       EHTMLEditorWebExtension *extension;
+       GMemoryOutputStream *output_stream;
+       const gchar *selector;
+       gchar *base64_encoded, *mime_type, *output, *uri;
+       gsize size;
+       gpointer data;
+
+       output_stream = G_MEMORY_OUTPUT_STREAM (load_context->output_stream);
+
+       document = load_context->document;
+       extension = load_context->extension;
+
+       mime_type = g_content_type_get_mime_type (load_context->content_type);
+
+       data = g_memory_output_stream_get_data (output_stream);
+       size = g_memory_output_stream_get_data_size (output_stream);
+       uri = g_file_get_uri (load_context->file);
+
+       base64_encoded = g_base64_encode ((const guchar *) data, size);
+       output = g_strconcat ("data:", mime_type, ";base64,", base64_encoded, NULL);
+       selector = load_context->selector;
+       if (selector && *selector)
+               dom_replace_base64_image_src (document, selector, output, load_context->filename, uri);
+       else
+               dom_insert_base64_image (document, extension, output, load_context->filename, uri);
+
+       g_free (base64_encoded);
+       g_free (output);
+       g_free (mime_type);
+       g_free (uri);
+
+       image_load_context_free (load_context);
+}
+
+static void
+image_load_write_cb (GOutputStream *output_stream,
+                     GAsyncResult *result,
+                     LoadContext *load_context)
+{
+       GInputStream *input_stream;
+       gssize bytes_written;
+       GError *error = NULL;
+
+       bytes_written = g_output_stream_write_finish (
+               output_stream, result, &error);
+
+       if (error) {
+               image_load_context_free (load_context);
+               return;
+       }
+
+       input_stream = load_context->input_stream;
+
+       if (bytes_written < load_context->bytes_read) {
+               g_memmove (
+                       load_context->buffer,
+                       load_context->buffer + bytes_written,
+                       load_context->bytes_read - bytes_written);
+               load_context->bytes_read -= bytes_written;
+
+               g_output_stream_write_async (
+                       output_stream,
+                       load_context->buffer,
+                       load_context->bytes_read,
+                       G_PRIORITY_DEFAULT, NULL,
+                       (GAsyncReadyCallback) image_load_write_cb,
+                       load_context);
+       } else
+               g_input_stream_read_async (
+                       input_stream,
+                       load_context->buffer,
+                       sizeof (load_context->buffer),
+                       G_PRIORITY_DEFAULT, NULL,
+                       (GAsyncReadyCallback) image_load_stream_read_cb,
+                       load_context);
+}
+
+static void
+image_load_stream_read_cb (GInputStream *input_stream,
+                           GAsyncResult *result,
+                           LoadContext *load_context)
+{
+       GOutputStream *output_stream;
+       gssize bytes_read;
+       GError *error = NULL;
+
+       bytes_read = g_input_stream_read_finish (
+               input_stream, result, &error);
+
+       if (error) {
+               image_load_context_free (load_context);
+               return;
+       }
+
+       if (bytes_read == 0) {
+               image_load_finish (load_context);
+               return;
+       }
+
+       output_stream = load_context->output_stream;
+       load_context->bytes_read = bytes_read;
+
+       g_output_stream_write_async (
+               output_stream,
+               load_context->buffer,
+               load_context->bytes_read,
+               G_PRIORITY_DEFAULT, NULL,
+               (GAsyncReadyCallback) image_load_write_cb,
+               load_context);
+}
+
+static void
+image_load_file_read_cb (GFile *file,
+                         GAsyncResult *result,
+                         LoadContext *load_context)
+{
+       GFileInputStream *input_stream;
+       GOutputStream *output_stream;
+       GError *error = NULL;
+
+       /* Input stream might be NULL, so don't use cast macro. */
+       input_stream = g_file_read_finish (file, result, &error);
+       load_context->input_stream = (GInputStream *) input_stream;
+
+       if (error) {
+               image_load_context_free (load_context);
+               return;
+       }
+
+       /* Load the contents into a GMemoryOutputStream. */
+       output_stream = g_memory_output_stream_new (
+               NULL, 0, g_realloc, g_free);
+
+       load_context->output_stream = output_stream;
+
+       g_input_stream_read_async (
+               load_context->input_stream,
+               load_context->buffer,
+               sizeof (load_context->buffer),
+               G_PRIORITY_DEFAULT, NULL,
+               (GAsyncReadyCallback) image_load_stream_read_cb,
+               load_context);
+}
+
+static void
+image_load_query_info_cb (GFile *file,
+                          GAsyncResult *result,
+                          LoadContext *load_context)
+{
+       GFileInfo *file_info;
+       GError *error = NULL;
+
+       file_info = g_file_query_info_finish (file, result, &error);
+       if (error) {
+               image_load_context_free (load_context);
+               return;
+       }
+
+       load_context->content_type = g_file_info_get_content_type (file_info);
+       load_context->total_num_bytes = g_file_info_get_size (file_info);
+       load_context->filename = g_file_info_get_name (file_info);
+
+       g_file_read_async (
+               file, G_PRIORITY_DEFAULT,
+               NULL, (GAsyncReadyCallback)
+               image_load_file_read_cb, load_context);
+}
+
+static void
+image_load_and_insert_async (WebKitDOMDocument *document,
+                             EHTMLEditorWebExtension *extension,
+                             const gchar *selector,
+                             const gchar *uri)
+{
+       LoadContext *load_context;
+       GFile *file;
+
+       g_return_if_fail (uri && *uri);
+
+       file = g_file_new_for_uri (uri);
+       g_return_if_fail (file != NULL);
+
+       load_context = image_load_context_new (document, extension);
+       load_context->file = file;
+       if (selector && *selector)
+               load_context->selector = g_strdup (selector);
+
+       g_file_query_info_async (
+               file, "standard::*",
+               G_FILE_QUERY_INFO_NONE,G_PRIORITY_DEFAULT,
+               NULL, (GAsyncReadyCallback)
+               image_load_query_info_cb, load_context);
+}
+
+void
+dom_insert_image (WebKitDOMDocument *document,
+                  EHTMLEditorWebExtension *extension,
+                  const gchar *uri)
+{
+       if (!e_html_editor_web_extension_get_html_mode (extension))
+               return;
+
+       if (strstr (uri, ";base64,")) {
+               if (g_str_has_prefix (uri, "data:"))
+                       dom_insert_base64_image (document, extension, uri, "", "");
+               if (strstr (uri, ";data")) {
+                       const gchar *base64_data = strstr (uri, ";") + 1;
+                       gchar *filename;
+                       glong filename_length;
+
+                       filename_length =
+                               g_utf8_strlen (uri, -1) -
+                               g_utf8_strlen (base64_data, -1) - 1;
+                       filename = g_strndup (uri, filename_length);
+
+                       dom_insert_base64_image (document, extension, base64_data, filename, "");
+                       g_free (filename);
+               }
+       } else
+               image_load_and_insert_async (document, extension, NULL, uri);
+}
+
+void
+dom_replace_image_src (WebKitDOMDocument *document,
+                       EHTMLEditorWebExtension *extension,
+                       const gchar *selector,
+                       const gchar *uri)
+{
+       if (strstr (uri, ";base64,")) {
+               if (g_str_has_prefix (uri, "data:"))
+                       dom_replace_base64_image_src (
+                               document, selector, uri, "", "");
+               if (strstr (uri, ";data")) {
+                       const gchar *base64_data = strstr (uri, ";") + 1;
+                       gchar *filename;
+                       glong filename_length;
+
+                       filename_length =
+                               g_utf8_strlen (uri, -1) -
+                               g_utf8_strlen (base64_data, -1) - 1;
+                       filename = g_strndup (uri, filename_length);
+
+                       dom_replace_base64_image_src (
+                               document, selector, base64_data, filename, "");
+                       g_free (filename);
+               }
+       } else
+               image_load_and_insert_async (document, extension, selector, uri);
 }
 
 /**
@@ -319,7 +630,7 @@ dom_selection_unlink (WebKitDOMDocument *document,
                                link = WEBKIT_DOM_ELEMENT (node);
                }
        } else {
-               dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_UNLINK, NULL);
+               dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_UNLINK, NULL);
        }
 
        g_object_unref (range);
@@ -372,7 +683,7 @@ dom_create_link (WebKitDOMDocument *document,
 {
        g_return_if_fail (uri != NULL && *uri != '\0');
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_CREATE_LINK, uri);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_CREATE_LINK, uri);
 }
 
 static gint
@@ -391,26 +702,26 @@ get_list_level (WebKitDOMNode *node)
 
 static void
 set_ordered_list_type_to_element (WebKitDOMElement *list,
-                                  EHTMLEditorSelectionBlockFormat format)
+                                  EContentEditorBlockFormat format)
 {
-       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST)
+       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST)
                webkit_dom_element_remove_attribute (list, "type");
-       else if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
+       else if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
                webkit_dom_element_set_attribute (list, "type", "A", NULL);
-       else if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN)
+       else if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN)
                webkit_dom_element_set_attribute (list, "type", "I", NULL);
 }
 
 static const gchar *
-get_css_alignment_value_class (EHTMLEditorSelectionAlignment alignment)
+get_css_alignment_value_class (EContentEditorAlignment alignment)
 {
-       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
+       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_LEFT)
                return ""; /* Left is by default on ltr */
 
-       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER)
+       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_CENTER)
                return "-x-evo-align-center";
 
-       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT)
+       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_RIGHT)
                return "-x-evo-align-right";
 
        return "";
@@ -422,12 +733,12 @@ get_css_alignment_value_class (EHTMLEditorSelectionAlignment alignment)
  *
  * Returns alignment of current paragraph
  *
- * Returns: #EHTMLEditorSelectionAlignment
+ * Returns: #EContentEditorAlignment
  */
-static EHTMLEditorSelectionAlignment
+static EContentEditorAlignment
 dom_get_alignment (WebKitDOMDocument *document)
 {
-       EHTMLEditorSelectionAlignment alignment;
+       EContentEditorAlignment alignment;
        gchar *value;
        WebKitDOMCSSStyleDeclaration *style;
        WebKitDOMDOMWindow *dom_window;
@@ -437,12 +748,12 @@ dom_get_alignment (WebKitDOMDocument *document)
 
        range = dom_get_current_range (document);
        if (!range)
-               return E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               return E_CONTENT_EDITOR_ALIGNMENT_LEFT;
 
        node = webkit_dom_range_get_start_container (range, NULL);
        g_object_unref (range);
        if (!node)
-               return E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               return E_CONTENT_EDITOR_ALIGNMENT_LEFT;
 
        if (WEBKIT_DOM_IS_ELEMENT (node))
                element = WEBKIT_DOM_ELEMENT (node);
@@ -451,11 +762,11 @@ dom_get_alignment (WebKitDOMDocument *document)
 
        if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (element)) {
                if (element_has_class (element, "-x-evo-align-right"))
-                       alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+                       alignment = E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
                else if (element_has_class (element, "-x-evo-align-center"))
-                       alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+                       alignment = E_CONTENT_EDITOR_ALIGNMENT_CENTER;
                else
-                       alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+                       alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
 
                return alignment;
        }
@@ -466,13 +777,13 @@ dom_get_alignment (WebKitDOMDocument *document)
 
        if (!value || !*value ||
            (g_ascii_strncasecmp (value, "left", 4) == 0)) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        } else if (g_ascii_strncasecmp (value, "center", 6) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_CENTER;
        } else if (g_ascii_strncasecmp (value, "right", 5) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
        } else {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        }
 
        g_object_unref (dom_window);
@@ -509,7 +820,7 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
 
        /* Don't set the alignment for nodes as they are handled separately. */
        if (!node_is_list (WEBKIT_DOM_NODE (element))) {
-               EHTMLEditorSelectionAlignment alignment;
+               EContentEditorAlignment alignment;
 
                alignment = dom_get_alignment (document);
                element_add_class (element, get_css_alignment_value_class (alignment));
@@ -538,14 +849,14 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
 static WebKitDOMElement *
 create_list_element (WebKitDOMDocument *document,
                      EHTMLEditorWebExtension *extension,
-                     EHTMLEditorSelectionBlockFormat format,
+                     EContentEditorBlockFormat format,
                     gint level,
                      gboolean html_mode)
 {
        gboolean inserting_unordered_list;
        WebKitDOMElement *list;
 
-       inserting_unordered_list = format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
+       inserting_unordered_list = format == E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST;
 
        list = webkit_dom_document_create_element (
                document, inserting_unordered_list  ? "UL" : "OL", NULL);
@@ -591,7 +902,7 @@ indent_list (WebKitDOMDocument *document,
                gboolean html_mode = e_html_editor_web_extension_get_html_mode (extension);
                WebKitDOMElement *list;
                WebKitDOMNode *source_list = webkit_dom_node_get_parent_node (item);
-               EHTMLEditorSelectionBlockFormat format;
+               EContentEditorBlockFormat format;
 
                format = dom_get_list_format_from_node (source_list);
 
@@ -787,8 +1098,8 @@ get_indentation_level (WebKitDOMElement *element)
 
 static gboolean
 do_format_change_list_to_block (WebKitDOMDocument *document,
-                               EHTMLEditorWebExtension *extension,
-                                EHTMLEditorSelectionBlockFormat format,
+                                EHTMLEditorWebExtension *extension,
+                                EContentEditorBlockFormat format,
                                 WebKitDOMNode *item,
                                 const gchar *value)
 {
@@ -855,7 +1166,7 @@ do_format_change_list_to_block (WebKitDOMDocument *document,
 
                        level = get_indentation_level (WEBKIT_DOM_ELEMENT (item));
 
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH) {
+                       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH) {
                                element = dom_get_paragraph_element (document, extension, -1, 0);
                        } else
                                element = webkit_dom_document_create_element (
@@ -899,7 +1210,7 @@ do_format_change_list_to_block (WebKitDOMDocument *document,
 static void
 format_change_list_to_block (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
-                             EHTMLEditorSelectionBlockFormat format,
+                             EContentEditorBlockFormat format,
                              const gchar *value)
 {
        WebKitDOMElement *selection_start;
@@ -944,10 +1255,10 @@ get_element_for_inspection (WebKitDOMRange *range)
        return WEBKIT_DOM_ELEMENT (get_parent_indented_block (node));
 }
 
-static EHTMLEditorSelectionAlignment
+static EContentEditorAlignment
 dom_get_alignment_from_node (WebKitDOMNode *node)
 {
-       EHTMLEditorSelectionAlignment alignment;
+       EContentEditorAlignment alignment;
        gchar *value;
        WebKitDOMCSSStyleDeclaration *style;
 
@@ -956,13 +1267,13 @@ dom_get_alignment_from_node (WebKitDOMNode *node)
 
        if (!value || !*value ||
            (g_ascii_strncasecmp (value, "left", 4) == 0)) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        } else if (g_ascii_strncasecmp (value, "center", 6) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_CENTER;
        } else if (g_ascii_strncasecmp (value, "right", 5) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
        } else {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        }
 
        g_object_unref (style);
@@ -1135,8 +1446,6 @@ dom_selection_indent (WebKitDOMDocument *document,
 
        dom_selection_restore (document);
        dom_force_spell_check_for_current_paragraph (document, extension);
-
-       set_dbus_property_boolean (extension, "Indented", TRUE);
 }
 
 static void
@@ -1215,7 +1524,7 @@ unindent_block (WebKitDOMDocument *document,
 {
        gboolean before_node = TRUE;
        gint word_wrap_length, level, width;
-       EHTMLEditorSelectionAlignment alignment;
+       EContentEditorAlignment alignment;
        WebKitDOMElement *element;
        WebKitDOMElement *prev_blockquote = NULL, *next_blockquote = NULL;
        WebKitDOMNode *block_to_process, *node_clone = NULL, *child;
@@ -1445,9 +1754,6 @@ dom_selection_unindent (WebKitDOMDocument *document,
        dom_selection_restore (document);
 
        dom_force_spell_check_for_current_paragraph (document, extension);
-
-       /* FIXME XXX - Check if the block is still indented */
-       set_dbus_property_boolean (extension, "Indented", TRUE);
 }
 
 static WebKitDOMNode *
@@ -2961,7 +3267,7 @@ WebKitDOMElement *
 dom_put_node_into_paragraph (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
                              WebKitDOMNode *node,
-                            gboolean with_input)
+                             gboolean with_input)
 {
        WebKitDOMRange *range;
        WebKitDOMElement *container;
@@ -3203,7 +3509,7 @@ static void
 html_editor_selection_modify (WebKitDOMDocument *document,
                               const gchar *alter,
                               gboolean forward,
-                              EHTMLEditorSelectionGranularity granularity)
+                              EContentEditorGranularity granularity)
 {
        WebKitDOMDOMWindow *dom_window;
        WebKitDOMDOMSelection *dom_selection;
@@ -3213,10 +3519,10 @@ html_editor_selection_modify (WebKitDOMDocument *document,
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
 
        switch (granularity) {
-               case E_HTML_EDITOR_SELECTION_GRANULARITY_CHARACTER:
+               case E_CONTENT_EDITOR_GRANULARITY_CHARACTER:
                        granularity_str = "character";
                        break;
-               case E_HTML_EDITOR_SELECTION_GRANULARITY_WORD:
+               case E_CONTENT_EDITOR_GRANULARITY_WORD:
                        granularity_str = "word";
                        break;
        }
@@ -3303,9 +3609,9 @@ typedef gboolean (*IsRightFormatNodeFunc) (WebKitDOMElement *element);
 
 static gboolean
 dom_selection_is_font_format (WebKitDOMDocument *document,
-                             EHTMLEditorWebExtension *extension,
-                             IsRightFormatNodeFunc func,
-                             gboolean *previous_value)
+                              EHTMLEditorWebExtension *extension,
+                              IsRightFormatNodeFunc func,
+                              gboolean *previous_value)
 {
        gboolean ret_val = FALSE;
        WebKitDOMDOMWindow *dom_window = NULL;
@@ -3592,7 +3898,7 @@ set_font_style (WebKitDOMDocument *document,
 static void
 selection_set_font_style (WebKitDOMDocument *document,
                           EHTMLEditorWebExtension *extension,
-                          EHTMLEditorViewCommand command,
+                          EContentEditorCommand command,
                           gboolean value)
 {
        EHTMLEditorHistoryEvent *ev = NULL;
@@ -3603,13 +3909,13 @@ selection_set_font_style (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)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
-               if (command == E_HTML_EDITOR_VIEW_COMMAND_BOLD)
+               if (command == E_CONTENT_EDITOR_COMMAND_BOLD)
                        ev->type = HISTORY_BOLD;
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_ITALIC)
+               else if (command == E_CONTENT_EDITOR_COMMAND_ITALIC)
                        ev->type = HISTORY_ITALIC;
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE)
+               else if (command == E_CONTENT_EDITOR_COMMAND_UNDERLINE)
                        ev->type = HISTORY_UNDERLINE;
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH)
+               else if (command == E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH)
                        ev->type = HISTORY_STRIKETHROUGH;
 
                dom_selection_get_coordinates (
@@ -3626,13 +3932,13 @@ selection_set_font_style (WebKitDOMDocument *document,
        if (dom_selection_is_collapsed (document)) {
                const gchar *element_name = NULL;
 
-               if (command == E_HTML_EDITOR_VIEW_COMMAND_BOLD)
+               if (command == E_CONTENT_EDITOR_COMMAND_BOLD)
                        element_name = "b";
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_ITALIC)
+               else if (command == E_CONTENT_EDITOR_COMMAND_ITALIC)
                        element_name = "i";
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE)
+               else if (command == E_CONTENT_EDITOR_COMMAND_UNDERLINE)
                        element_name = "u";
-               else if (command == E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH)
+               else if (command == E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH)
                        element_name = "strike";
 
                if (element_name)
@@ -3675,9 +3981,7 @@ dom_selection_set_underline (WebKitDOMDocument *document,
                return;
 
        selection_set_font_style (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE, underline);
-
-       set_dbus_property_boolean (extension, "Underline", underline);
+               document, extension, E_CONTENT_EDITOR_COMMAND_UNDERLINE, underline);
 }
 
 static gboolean
@@ -3722,9 +4026,7 @@ dom_selection_set_subscript (WebKitDOMDocument *document,
        if (dom_selection_is_subscript (document, extension) == subscript)
                return;
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT, NULL);
-
-       set_dbus_property_boolean (extension, "Subscript", subscript);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_SUBSCRIPT, NULL);
 }
 
 static gboolean
@@ -3769,9 +4071,7 @@ dom_selection_set_superscript (WebKitDOMDocument *document,
        if (dom_selection_is_superscript (document, extension) == superscript)
                return;
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT, NULL);
-
-       set_dbus_property_boolean (extension, "Superscript", superscript);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_SUPERSCRIPT, NULL);
 }
 
 static gboolean
@@ -3822,9 +4122,7 @@ dom_selection_set_strikethrough (WebKitDOMDocument *document,
                return;
 
        selection_set_font_style (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH, strikethrough);
-
-       set_dbus_property_boolean (extension, "Strikethrough", strikethrough);
+               document, extension, E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH, strikethrough);
 }
 
 static gboolean
@@ -4282,7 +4580,7 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
 
        font_size = e_html_editor_web_extension_get_font_size (extension);
        if (font_size == 0)
-               font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+               font_size = E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
 
        dom_window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
@@ -4382,8 +4680,6 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
        g_object_unref (range);
        g_object_unref (dom_selection);
        g_object_unref (dom_window);
-
-       set_dbus_property_boolean (extension, "Monospaced", monospaced);
 }
 
 static gboolean
@@ -4439,11 +4735,9 @@ dom_selection_set_bold (WebKitDOMDocument *document,
                return;
 
        selection_set_font_style (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_BOLD, bold);
+               document, extension, E_CONTENT_EDITOR_COMMAND_BOLD, bold);
 
        dom_force_spell_check_for_current_paragraph (document, extension);
-
-       set_dbus_property_boolean (extension, "Bold", bold);
 }
 
 static gboolean
@@ -4494,9 +4788,7 @@ dom_selection_set_italic (WebKitDOMDocument *document,
                return;
 
        selection_set_font_style (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_ITALIC, italic);
-
-       set_dbus_property_boolean (extension, "Italic", italic);
+               document, extension, E_CONTENT_EDITOR_COMMAND_ITALIC, italic);
 }
 
 /**
@@ -4647,7 +4939,7 @@ dom_selection_get_font_size (WebKitDOMDocument *document,
        size = get_font_property (document, "size");
        if (!(size && *size)) {
                g_free (size);
-               return E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+               return E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
        }
 
        /* We don't support increments, but when going through a content that
@@ -4659,7 +4951,7 @@ dom_selection_get_font_size (WebKitDOMDocument *document,
        g_free (size);
 
        if (increment || size_int == 0)
-               return E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+               return E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
 
        return size_int;
 }
@@ -4675,7 +4967,7 @@ dom_selection_get_font_size (WebKitDOMDocument *document,
 void
 dom_selection_set_font_size (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
-                             guint font_size)
+                             EContentEditorFontSize font_size)
 {
        EHTMLEditorUndoRedoManager *manager;
        EHTMLEditorHistoryEvent *ev = NULL;
@@ -4718,11 +5010,11 @@ dom_selection_set_font_size (WebKitDOMDocument *document,
 
        dom_selection_restore (document);
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE, size_str);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_FONT_SIZE, size_str);
 
        /* Text in <font size="3"></font> (size 3 is our default size) is a little
         * bit smaller than font outsize it. So move it outside of it. */
-       if (font_size == E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL) {
+       if (font_size == E_CONTENT_EDITOR_FONT_SIZE_NORMAL) {
                WebKitDOMElement *element;
 
                element = webkit_dom_document_query_selector (document, "font[size=\"3\"]", NULL);
@@ -4753,8 +5045,6 @@ dom_selection_set_font_size (WebKitDOMDocument *document,
 
                e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
        }
-
-       set_dbus_property_unsigned (extension, "FontSize", font_size);
 }
 
 /**
@@ -4770,9 +5060,7 @@ dom_selection_set_font_name (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
                              const gchar *font_name)
 {
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME, font_name);
-/* FIXME WK2
-       set_dbus_property_string (extension, "FontName", font_name); */
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_FONT_NAME, font_name);
 }
 
 /**
@@ -4836,7 +5124,7 @@ dom_selection_set_font_color (WebKitDOMDocument *document,
                ev->data.string.to = g_strdup (color);
        }
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_FORE_COLOR, color);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_FORE_COLOR, color);
 
        if (ev) {
                ev->after.start.x = ev->before.start.x;
@@ -4846,8 +5134,6 @@ dom_selection_set_font_color (WebKitDOMDocument *document,
 
                e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
        }
-
-       set_dbus_property_string (extension, "FontColor", color);
 }
 
 /**
@@ -4897,20 +5183,20 @@ get_block_node (WebKitDOMRange *range)
  *
  * Returns block format of current paragraph.
  *
- * Returns: #EHTMLEditorSelectionBlockFormat
+ * Returns: #EContentEditorBlockFormat
  */
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
 dom_selection_get_block_format (WebKitDOMDocument *document,
                                 EHTMLEditorWebExtension *extension)
 {
        WebKitDOMNode *node;
        WebKitDOMRange *range;
        WebKitDOMElement *element;
-       EHTMLEditorSelectionBlockFormat result;
+       EContentEditorBlockFormat result;
 
        range = dom_get_current_range (document);
        if (!range)
-               return E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+               return E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
 
        node = webkit_dom_range_get_start_container (range, NULL);
 
@@ -4924,7 +5210,7 @@ dom_selection_get_block_format (WebKitDOMDocument *document,
                        else
                                result = dom_get_list_format_from_node (WEBKIT_DOM_NODE (tmp_element));
                } else
-                       result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
+                       result = E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST;
        } else if ((element = dom_node_find_parent_element (node, "OL")) != NULL) {
                WebKitDOMElement *tmp_element;
 
@@ -4937,42 +5223,42 @@ dom_selection_get_block_format (WebKitDOMDocument *document,
                } else
                        result = dom_get_list_format_from_node (WEBKIT_DOM_NODE (element));
        } else if (dom_node_find_parent_element (node, "PRE")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_PRE;
        } else if (dom_node_find_parent_element (node, "ADDRESS")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_ADDRESS;
        } else if (dom_node_find_parent_element (node, "H1")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H1;
        } else if (dom_node_find_parent_element (node, "H2")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H2;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H2;
        } else if (dom_node_find_parent_element (node, "H3")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H3;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H3;
        } else if (dom_node_find_parent_element (node, "H4")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H4;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H4;
        } else if (dom_node_find_parent_element (node, "H5")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H5;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H5;
        } else if (dom_node_find_parent_element (node, "H6")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_H6;
        } else if ((element = dom_node_find_parent_element (node, "BLOCKQUOTE")) != NULL) {
                if (element_has_class (element, "-x-evo-indented"))
-                       result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+                       result = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
                else {
                        WebKitDOMNode *block = get_block_node (range);
 
                        if (WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (block) ||
                            webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (block), 
"data-evo-paragraph"))
-                               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+                               result = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
                        else {
                                /* Paragraphs inside quote */
                                if ((element = dom_node_find_parent_element (node, "P")) != NULL)
-                                       result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+                                       result = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
                                else
-                                       result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE;
+                                       result = E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE;
                        }
                }
        } else if (dom_node_find_parent_element (node, "P")) {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
        } else {
-               result = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+               result = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
        }
 
        g_object_unref (range);
@@ -5060,7 +5346,7 @@ change_space_before_selection_to_nbsp (WebKitDOMNode *node)
 static gboolean
 process_block_to_block (WebKitDOMDocument *document,
                         EHTMLEditorWebExtension *extension,
-                        EHTMLEditorSelectionBlockFormat format,
+                        EContentEditorBlockFormat format,
                         const gchar *value,
                         WebKitDOMNode *block,
                         WebKitDOMNode *end_block,
@@ -5127,8 +5413,8 @@ process_block_to_block (WebKitDOMDocument *document,
                        continue;
                }
 
-               if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH ||
-                   format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE)
+               if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH ||
+                   format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE)
                        element = dom_get_paragraph_element (document, extension, -1, 0);
                else
                        element = webkit_dom_document_create_element (
@@ -5181,11 +5467,11 @@ process_block_to_block (WebKitDOMDocument *document,
                block = next_block;
 
                if (!html_mode &&
-                   (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH ||
-                    format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE)) {
+                   (format == E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH ||
+                    format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE)) {
                        gint citation_level;
 
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE)
+                       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE)
                                citation_level = 1;
                        else
                                citation_level = selection_get_citation_level (WEBKIT_DOM_NODE (element));
@@ -5203,7 +5489,7 @@ process_block_to_block (WebKitDOMDocument *document,
                        }
                }
 
-               if (blockquote && format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE) {
+               if (blockquote && format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE) {
                        webkit_dom_node_append_child (
                                blockquote, WEBKIT_DOM_NODE (element), NULL);
                        if (!html_mode)
@@ -5218,7 +5504,7 @@ process_block_to_block (WebKitDOMDocument *document,
 static void
 format_change_block_to_block (WebKitDOMDocument *document,
                               EHTMLEditorWebExtension *extension,
-                              EHTMLEditorSelectionBlockFormat format,
+                              EContentEditorBlockFormat format,
                               const gchar *value)
 {
        gboolean html_mode = FALSE;
@@ -5250,7 +5536,7 @@ format_change_block_to_block (WebKitDOMDocument *document,
 
        html_mode = e_html_editor_web_extension_get_html_mode (extension);
 
-       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE) {
+       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE) {
                blockquote = WEBKIT_DOM_NODE (
                        webkit_dom_document_create_element (document, "BLOCKQUOTE", NULL));
 
@@ -5276,7 +5562,7 @@ format_change_block_to_block (WebKitDOMDocument *document,
 static void
 format_change_block_to_list (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
-                             EHTMLEditorSelectionBlockFormat format)
+                             EContentEditorBlockFormat format)
 {
        gboolean after_selection_end = FALSE, in_quote = FALSE;
        gboolean html_mode = e_html_editor_web_extension_get_html_mode (extension);
@@ -5334,7 +5620,7 @@ format_change_block_to_list (WebKitDOMDocument *document,
                e_html_editor_web_extension_block_selection_changed_callback (extension);
 
                dom_exec_command (
-                       document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
NULL);
+                       document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
NULL);
 
                dom_register_input_event_listener_on_body (document, extension);
                e_html_editor_web_extension_unblock_selection_changed_callback (extension);
@@ -5430,17 +5716,17 @@ format_change_block_to_list (WebKitDOMDocument *document,
 static WebKitDOMElement *
 do_format_change_list_to_list (WebKitDOMElement *list_to_process,
                                WebKitDOMElement *new_list_template,
-                               EHTMLEditorSelectionBlockFormat to)
+                               EContentEditorBlockFormat to)
 {
-       EHTMLEditorSelectionBlockFormat current_format;
+       EContentEditorBlockFormat current_format;
 
        current_format = dom_get_list_format_from_node (
                WEBKIT_DOM_NODE (list_to_process));
        if (to == current_format) {
                /* Same format, skip it. */
                return list_to_process;
-       } else if (current_format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST &&
-                  to >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+       } else if (current_format >= E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST &&
+                  to >= E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST) {
                /* Changing from ordered list type to another ordered list type. */
                set_ordered_list_type_to_element (list_to_process, to);
                return list_to_process;
@@ -5474,7 +5760,7 @@ do_format_change_list_to_list (WebKitDOMElement *list_to_process,
 static void
 format_change_list_from_list (WebKitDOMDocument *document,
                               EHTMLEditorWebExtension *extension,
-                              EHTMLEditorSelectionBlockFormat to,
+                              EContentEditorBlockFormat to,
                               gboolean html_mode)
 {
        gboolean after_selection_end = FALSE;
@@ -5670,10 +5956,10 @@ format_change_list_from_list (WebKitDOMDocument *document,
 static void
 format_change_list_to_list (WebKitDOMDocument *document,
                             EHTMLEditorWebExtension *extension,
-                            EHTMLEditorSelectionBlockFormat format,
+                            EContentEditorBlockFormat format,
                             gboolean html_mode)
 {
-       EHTMLEditorSelectionBlockFormat prev = 0, next = 0;
+       EContentEditorBlockFormat prev = 0, next = 0;
        gboolean done = FALSE, indented = FALSE;
        gboolean selection_starts_in_first_child, selection_ends_in_last_child;
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -5751,17 +6037,17 @@ format_change_list_to_list (WebKitDOMDocument *document,
 /**
  * e_html_editor_selection_set_block_format:
  * @selection: an #EHTMLEditorSelection
- * @format: an #EHTMLEditorSelectionBlockFormat value
+ * @format: an #EContentEditorBlockFormat value
  *
  * Changes block format of current paragraph to @format.
  */
 void
 dom_selection_set_block_format (WebKitDOMDocument *document,
                                 EHTMLEditorWebExtension *extension,
-                                EHTMLEditorSelectionBlockFormat format)
+                                EContentEditorBlockFormat format)
 {
-       EHTMLEditorSelectionBlockFormat current_format;
-       EHTMLEditorSelectionAlignment current_alignment;
+       EContentEditorBlockFormat current_format;
+       EContentEditorAlignment current_alignment;
        EHTMLEditorUndoRedoManager *manager;
        EHTMLEditorHistoryEvent *ev = NULL;
        const gchar *value;
@@ -5769,66 +6055,60 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
        WebKitDOMRange *range;
 
        current_format = dom_selection_get_block_format (document, extension);
-       if (current_format == format) {
+       if (current_format == format)
                return;
-       }
 
        switch (format) {
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE:
                        value = "BLOCKQUOTE";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H1:
                        value = "H1";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H2:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H2:
                        value = "H2";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H3:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H3:
                        value = "H3";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H4:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H4:
                        value = "H4";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H5:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H5:
                        value = "H5";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_H6:
                        value = "H6";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH:
                        value = "P";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_PRE:
                        value = "PRE";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_ADDRESS:
                        value = "ADDRESS";
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST:
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA:
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN:
                        to_list = TRUE;
                        value = NULL;
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST:
                        to_list = TRUE;
                        value = NULL;
                        break;
-               case E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_NONE:
+               case E_CONTENT_EDITOR_BLOCK_FORMAT_NONE:
                default:
                        value = NULL;
                        break;
        }
 
-       /* H1 - H6 have bold font by default */
-       if (format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1 &&
-           format <= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6)
-               set_dbus_property_boolean (extension, "Bold", TRUE);
-
        html_mode = e_html_editor_web_extension_get_html_mode (extension);
 
        from_list =
-               current_format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
+               current_format >= E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST;
 
        range = dom_get_current_range (document);
        if (!range)
@@ -5841,7 +6121,7 @@ dom_selection_set_block_format (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)) {
                ev = g_new0 (EHTMLEditorHistoryEvent, 1);
-               if (format != E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE)
+               if (format != E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE)
                        ev->type = HISTORY_BLOCK_FORMAT;
                else
                        ev->type = HISTORY_BLOCKQUOTE;
@@ -5853,7 +6133,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
                        &ev->before.end.x,
                        &ev->before.end.y);
 
-               if (format != E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE) {
+               if (format != E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE) {
                        ev->data.style.from = current_format;
                        ev->data.style.to = format;
                } else {
@@ -5897,7 +6177,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
 
        g_object_unref (range);
 
-       if (current_format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE) {
+       if (current_format == E_CONTENT_EDITOR_BLOCK_FORMAT_PRE) {
                WebKitDOMElement *selection_marker;
 
                selection_marker = webkit_dom_document_get_element_by_id (
@@ -5919,7 +6199,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
        if (from_list && !to_list) {
                format_change_list_to_block (document, extension, format, value);
 
-               if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE) {
+               if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE) {
                        dom_selection_restore (document);
                        format_change_block_to_block (document, extension, format, value);
                }
@@ -5946,8 +6226,6 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
                        &ev->after.end.y);
                e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
        }
-
-       set_dbus_property_unsigned (extension, "BlockFormat", format);
 }
 
 /**
@@ -5998,9 +6276,7 @@ dom_selection_set_background_color (WebKitDOMDocument *document,
                                     EHTMLEditorWebExtension *extension,
                                     const gchar *color)
 {
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR, color);
-/* FIXME WK2
-       set_dbus_property_string (extension, "BackgroundColor", color); */
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_BACKGROUND_COLOR, color);
 }
 
 /**
@@ -6009,13 +6285,13 @@ dom_selection_set_background_color (WebKitDOMDocument *document,
  *
  * Returns alignment of current paragraph
  *
- * Returns: #EHTMLEditorSelectionAlignment
+ * Returns: #EContentEditorAlignment
  */
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
 dom_selection_get_alignment (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension)
 {
-       EHTMLEditorSelectionAlignment alignment;
+       EContentEditorAlignment alignment;
        gchar *value;
        WebKitDOMCSSStyleDeclaration *style;
        WebKitDOMElement *element;
@@ -6024,14 +6300,14 @@ dom_selection_get_alignment (WebKitDOMDocument *document,
 
        range = dom_get_current_range (document);
        if (!range) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
                goto out;
        }
 
        node = webkit_dom_range_get_start_container (range, NULL);
        g_object_unref (range);
        if (!node) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
                goto out;
        }
 
@@ -6041,10 +6317,10 @@ dom_selection_get_alignment (WebKitDOMDocument *document,
                element = webkit_dom_node_get_parent_element (node);
 
        if (element_has_class (element, "-x-evo-align-right")) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
                goto out;
        } else if (element_has_class (element, "-x-evo-align-center")) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_CENTER;
                goto out;
        }
 
@@ -6053,21 +6329,19 @@ dom_selection_get_alignment (WebKitDOMDocument *document,
 
        if (!value || !*value ||
            (g_ascii_strncasecmp (value, "left", 4) == 0)) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        } else if (g_ascii_strncasecmp (value, "center", 6) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_CENTER;
        } else if (g_ascii_strncasecmp (value, "right", 5) == 0) {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
        } else {
-               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
        }
 
        g_object_unref (style);
        g_free (value);
 
  out:
-       set_dbus_property_unsigned (extension, "Alignment", alignment);
-
        return alignment;
 }
 
@@ -6092,16 +6366,16 @@ set_block_alignment (WebKitDOMElement *element,
 /**
  * e_html_editor_selection_set_alignment:
  * @selection: an #EHTMLEditorSelection
- * @alignment: an #EHTMLEditorSelectionAlignment value to apply
+ * @alignment: an #EContentEditorAlignment value to apply
  *
  * Sets alignment of current paragraph to give @alignment.
  */
 void
 dom_selection_set_alignment (WebKitDOMDocument *document,
                              EHTMLEditorWebExtension *extension,
-                             EHTMLEditorSelectionAlignment alignment)
+                             EContentEditorAlignment alignment)
 {
-       EHTMLEditorSelectionAlignment current_alignment;
+       EContentEditorAlignment current_alignment;
        EHTMLEditorUndoRedoManager *manager;
        EHTMLEditorHistoryEvent *ev = NULL;
        gboolean after_selection_end = FALSE;
@@ -6111,18 +6385,19 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
 
        current_alignment = e_html_editor_web_extension_get_alignment (extension);
 
+       printf ("%d:%d\n", current_alignment, alignment);
        if (current_alignment == alignment)
                return;
 
        switch (alignment) {
-               case E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER:
+               case E_CONTENT_EDITOR_ALIGNMENT_CENTER:
                        class = "-x-evo-align-center";
                        break;
 
-               case E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT:
+               case E_CONTENT_EDITOR_ALIGNMENT_LEFT:
                        break;
 
-               case E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT:
+               case E_CONTENT_EDITOR_ALIGNMENT_RIGHT:
                        class = "-x-evo-align-right";
                        break;
        }
@@ -6150,7 +6425,7 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
                        &ev->before.end.y);
                ev->data.style.from = current_alignment;
                ev->data.style.to = alignment;
-        }
+       }
 
        block = get_parent_block_node_from_child (
                WEBKIT_DOM_NODE (selection_start_marker));
@@ -6206,8 +6481,6 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
        dom_selection_restore (document);
 
        dom_force_spell_check_for_current_paragraph (document, extension);
-
-       set_dbus_property_unsigned (extension, "Alignment", alignment);
 }
 
 /**
@@ -6254,7 +6527,7 @@ dom_selection_replace (WebKitDOMDocument *document,
                g_object_unref (dom_window);
        }
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, replacement);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_TEXT, replacement);
 
        if (ev) {
                dom_selection_get_coordinates (
@@ -6421,17 +6694,17 @@ dom_selection_has_text (WebKitDOMDocument *document)
  *
  * Returns alignment of given list.
  *
- * Returns: #EHTMLEditorSelectionAlignment
+ * Returns: #EContentEditorAlignment
  */
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
 dom_get_list_alignment_from_node (WebKitDOMNode *node)
 {
        if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-align-center"))
-               return E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+               return E_CONTENT_EDITOR_ALIGNMENT_CENTER;
        if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-align-right"))
-               return E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+               return E_CONTENT_EDITOR_ALIGNMENT_RIGHT;
        else
-               return E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+               return E_CONTENT_EDITOR_ALIGNMENT_LEFT;
 }
 
 WebKitDOMElement *
diff --git a/web-extensions/composer/e-html-editor-selection-dom-functions.h 
b/web-extensions/composer/e-html-editor-selection-dom-functions.h
index c2b1314..562d7ae 100644
--- a/web-extensions/composer/e-html-editor-selection-dom-functions.h
+++ b/web-extensions/composer/e-html-editor-selection-dom-functions.h
@@ -76,6 +76,15 @@ void         dom_insert_base64_image         (WebKitDOMDocument *document,
                                                 const gchar *uri,
                                                 const gchar *base64_content);
 
+void           dom_insert_image                (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
+                                                const gchar *uri);
+
+void           dom_replace_image_src           (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
+                                                const gchar *selector,
+                                                const gchar *uri);
+
 void           dom_selection_unlink            (WebKitDOMDocument *document,
                                                  EHTMLEditorWebExtension *extension);
 
@@ -221,21 +230,21 @@ void              dom_selection_set_background_color
                                                 EHTMLEditorWebExtension *extension,
                                                 const gchar *font_color);
 
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
                dom_selection_get_block_format  (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_block_format  (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
-                                                EHTMLEditorSelectionBlockFormat format);
+                                                EContentEditorBlockFormat format);
 
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
                dom_selection_get_alignment     (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 
 void           dom_selection_set_alignment     (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
-                                                EHTMLEditorSelectionAlignment alignment);
+                                                EContentEditorAlignment alignment);
 
 void           dom_selection_replace           (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
@@ -249,7 +258,7 @@ gchar *             dom_get_caret_word              (WebKitDOMDocument *document);
 
 gboolean       dom_selection_has_text          (WebKitDOMDocument *document);
 
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
                dom_get_list_alignment_from_node
                                                (WebKitDOMNode *node);
 
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 e56301c..8c2d135 100644
--- a/web-extensions/composer/e-html-editor-undo-redo-manager.c
+++ b/web-extensions/composer/e-html-editor-undo-redo-manager.c
@@ -944,8 +944,8 @@ redo_delete (WebKitDOMDocument *document,
        for (ii = 0; ii < length; ii++) {
                dom_exec_command (
                        document, extension,
-                       delete_key ? E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE :
-                                    E_HTML_EDITOR_VIEW_COMMAND_DELETE,
+                       delete_key ? E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE :
+                                    E_CONTENT_EDITOR_COMMAND_DELETE,
                        NULL);
        }
 
@@ -957,7 +957,7 @@ redo_delete (WebKitDOMDocument *document,
                if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
                        dom_exec_command (
                                document, extension,
-                               E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE,
+                               E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE,
                                NULL);
                        break;
                }
@@ -968,7 +968,7 @@ redo_delete (WebKitDOMDocument *document,
                if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
                        dom_exec_command (
                                document, extension,
-                               E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE,
+                               E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE,
                                NULL);
                        break;
                }
@@ -1069,7 +1069,7 @@ undo_redo_font_color (WebKitDOMDocument *document,
        dom_exec_command (
                document,
                extension,
-               E_HTML_EDITOR_VIEW_COMMAND_FORE_COLOR,
+               E_CONTENT_EDITOR_COMMAND_FORE_COLOR,
                undo ? event->data.string.from : event->data.string.to);
 
        if (undo)
@@ -1367,7 +1367,7 @@ undo_redo_link_dialog (WebKitDOMDocument *document,
 
                                if (event->data.dom.from)
                                        dom_exec_command (document, extension,
-                                               E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+                                               E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
                        }
                }
        }
@@ -1562,7 +1562,7 @@ undo_redo_paste (WebKitDOMDocument *document,
 
                        dom_selection_restore (document);
 
-                       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+                       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
 
                        dom_force_spell_check_for_current_paragraph (document, extension);
                }
@@ -1665,7 +1665,7 @@ undo_redo_replace (WebKitDOMDocument *document,
        dom_exec_command (
                document,
                extension,
-               E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT,
+               E_CONTENT_EDITOR_COMMAND_INSERT_TEXT,
                undo ? event->data.string.from : event->data.string.to);
 
        dom_force_spell_check_for_current_paragraph (document, extension);
@@ -1869,7 +1869,7 @@ undo_input (EHTMLEditorUndoRedoManager *manager,
                g_free (text_content);
        }
 
-       dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+       dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
 
        if (remove_anchor) {
                WebKitDOMNode *child;
@@ -2048,7 +2048,7 @@ undo_redo_blockquote (WebKitDOMDocument *document,
                        NULL);
        } else {
                dom_selection_set_block_format (
-                       document, extension, E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE);
+                       document, extension, E_CONTENT_EDITOR_BLOCK_FORMAT_BLOCKQUOTE);
        }
 
        if (undo)
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 0bb90c0..1a9b09f 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.c
@@ -47,7 +47,7 @@
 /**
  * e_html_editor_view_dom_exec_command:
  * @document: a #WebKitDOMDocument
- * @command: an #EHTMLEditorViewCommand to execute
+ * @command: an #EContentEditorCommand to execute
  * @value: value of the command (or @NULL if the command does not require value)
  *
  * The function will fail when @value is @NULL or empty but the current @command
@@ -59,7 +59,7 @@
 gboolean
 dom_exec_command (WebKitDOMDocument *document,
                   EHTMLEditorWebExtension *extension,
-                  EHTMLEditorViewCommand command,
+                  EContentEditorCommand command,
                   const gchar *value)
 {
        const gchar *cmd_str = 0;
@@ -74,55 +74,55 @@ dom_exec_command (WebKitDOMDocument *document,
        break;
 
        switch (command) {
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR, "BackColor", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_BOLD, "Bold", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_COPY, "Copy", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_CREATE_LINK, "CreateLink", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_CUT, "Cut", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR, 
"DefaultParagraphSeparator", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_DELETE, "Delete", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FIND_STRING, "FindString", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME, "FontName", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE, "FontSize", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FONT_SIZE_DELTA, "FontSizeDelta", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FORE_COLOR, "ForeColor", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FORMAT_BLOCK, "FormatBlock", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_FORWARD_DELETE, "ForwardDelete", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_HILITE_COLOR, "HiliteColor", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INDENT, "Indent", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_HORIZONTAL_RULE, "InsertHorizontalRule", 
FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, "InsertHTML", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_IMAGE, "InsertImage", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_LINE_BREAK, "InsertLineBreak", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
"InsertNewlineInQuotedContent", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_ORDERED_LIST, "InsertOrderedList", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_PARAGRAPH, "InsertParagraph", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, "InsertText", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_INSERT_UNORDERED_LIST, "InsertUnorderedList", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_ITALIC, "Italic", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_CENTER, "JustifyCenter", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_FULL, "JustifyFull", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_LEFT, "JustifyLeft", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_NONE, "JustifyNone", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_RIGHT, "JustifyRight", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_OUTDENT, "Outdent", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_PASTE, "Paste", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_PASTE_AND_MATCH_STYLE, "PasteAndMatchStyle", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_PASTE_AS_PLAIN_TEXT, "PasteAsPlainText", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_PRINT, "Print", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_REDO, "Redo", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_REMOVE_FORMAT, "RemoveFormat", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_SELECT_ALL, "SelectAll", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_STRIKETHROUGH, "Strikethrough", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_STYLE_WITH_CSS, "StyleWithCSS", TRUE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT, "Subscript", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT, "Superscript", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_TRANSPOSE, "Transpose", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE, "Underline", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_UNDO, "Undo", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_UNLINK, "Unlink", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_UNSELECT, "Unselect", FALSE)
-               CHECK_COMMAND (E_HTML_EDITOR_VIEW_COMMAND_USE_CSS, "UseCSS", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_BACKGROUND_COLOR, "BackColor", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_BOLD, "Bold", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_COPY, "Copy", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_CREATE_LINK, "CreateLink", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_CUT, "Cut", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR, 
"DefaultParagraphSeparator", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_DELETE, "Delete", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FIND_STRING, "FindString", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FONT_NAME, "FontName", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FONT_SIZE, "FontSize", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FONT_SIZE_DELTA, "FontSizeDelta", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FORE_COLOR, "ForeColor", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FORMAT_BLOCK, "FormatBlock", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_FORWARD_DELETE, "ForwardDelete", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_HILITE_COLOR, "HiliteColor", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INDENT, "Indent", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_HORIZONTAL_RULE, "InsertHorizontalRule", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_HTML, "InsertHTML", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_IMAGE, "InsertImage", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_LINE_BREAK, "InsertLineBreak", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
"InsertNewlineInQuotedContent", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_ORDERED_LIST, "InsertOrderedList", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_PARAGRAPH, "InsertParagraph", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_TEXT, "InsertText", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_INSERT_UNORDERED_LIST, "InsertUnorderedList", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_ITALIC, "Italic", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_JUSTIFY_CENTER, "JustifyCenter", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_JUSTIFY_FULL, "JustifyFull", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_JUSTIFY_LEFT, "JustifyLeft", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_JUSTIFY_NONE, "JustifyNone", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_JUSTIFY_RIGHT, "JustifyRight", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_OUTDENT, "Outdent", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_PASTE, "Paste", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_PASTE_AND_MATCH_STYLE, "PasteAndMatchStyle", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_PASTE_AS_PLAIN_TEXT, "PasteAsPlainText", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_PRINT, "Print", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_REDO, "Redo", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_REMOVE_FORMAT, "RemoveFormat", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_SELECT_ALL, "SelectAll", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_STRIKETHROUGH, "Strikethrough", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_STYLE_WITH_CSS, "StyleWithCSS", TRUE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_SUBSCRIPT, "Subscript", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_SUPERSCRIPT, "Superscript", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_TRANSPOSE, "Transpose", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_UNDERLINE, "Underline", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_UNDO, "Undo", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_UNLINK, "Unlink", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_UNSELECT, "Unselect", FALSE)
+               CHECK_COMMAND (E_CONTENT_EDITOR_COMMAND_USE_CSS, "UseCSS", TRUE)
        }
 
        e_html_editor_web_extension_set_dont_save_history_in_body_input (extension, TRUE);
@@ -142,7 +142,7 @@ perform_spell_check (WebKitDOMDOMSelection *dom_selection,
        /* Go through all words to spellcheck them. To avoid this we have to wait for
         * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
        /* We are moving forward word by word until we hit the text on the end. */
-       while (actual && webkit_dom_range_compare_boundary_points (end_range, 2 /* END_TO_END */, actual, 
NULL) != 0) {
+       while (actual && webkit_dom_range_compare_boundary_points (end_range, WEBKIT_DOM_RANGE_END_TO_END, 
actual, NULL) != 0) {
                g_object_unref (actual);
                webkit_dom_dom_selection_modify (
                        dom_selection, "move", "forward", "word");
@@ -378,7 +378,8 @@ dom_force_spell_check_in_viewport (WebKitDOMDocument *document,
        /* We have to add 10 px offset as otherwise just the HTML element will be returned */
        viewport_height = webkit_dom_dom_window_get_inner_height (dom_window);
        last_element = webkit_dom_document_element_from_point (document, 10, viewport_height - 10);
-       if (last_element && !WEBKIT_DOM_IS_HTML_HTML_ELEMENT (last_element)) {
+       if (last_element && !WEBKIT_DOM_IS_HTML_HTML_ELEMENT (last_element) &&
+           !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (last_element)) {
                WebKitDOMElement *parent;
 
                parent = get_parent_block_element (WEBKIT_DOM_NODE (last_element));
@@ -586,8 +587,8 @@ get_parent_block_node_from_child (WebKitDOMNode *node)
 
 WebKitDOMElement *
 wrap_and_quote_element (WebKitDOMDocument *document,
-                       EHTMLEditorWebExtension *extension,
-                       WebKitDOMElement *element)
+                        EHTMLEditorWebExtension *extension,
+                        WebKitDOMElement *element)
 {
        gint citation_level;
        WebKitDOMElement *tmp_element = element;
@@ -712,7 +713,7 @@ dom_insert_new_line_into_citation (WebKitDOMDocument *document,
                e_html_editor_web_extension_block_selection_changed_callback (extension);
 
                ret_val = dom_exec_command (
-                       document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
NULL);
+                       document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, 
NULL);
 
                e_html_editor_web_extension_unblock_selection_changed_callback (extension);
                dom_register_input_event_listener_on_body (document, extension);
@@ -825,7 +826,7 @@ put_body_in_citation (WebKitDOMDocument *document)
 /* For purpose of this function see e-mail-formatter-quote.c */
 static void
 move_elements_to_body (WebKitDOMDocument *document,
-                      EHTMLEditorWebExtension *extension)
+                       EHTMLEditorWebExtension *extension)
 {
        WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
        WebKitDOMNodeList *list;
@@ -1222,7 +1223,7 @@ dom_embed_style_sheet (WebKitDOMDocument *document,
 }
 
 void
-dom_remove_embed_style_sheet (WebKitDOMDocument *document)
+dom_remove_embedded_style_sheet (WebKitDOMDocument *document)
 {
        WebKitDOMElement *sheet;
 
@@ -1234,7 +1235,7 @@ dom_remove_embed_style_sheet (WebKitDOMDocument *document)
 
 static void
 insert_delete_event (WebKitDOMDocument *document,
-                    EHTMLEditorWebExtension *extension,
+                     EHTMLEditorWebExtension *extension,
                      WebKitDOMRange *range)
 {
        EHTMLEditorHistoryEvent *ev;
@@ -1400,7 +1401,7 @@ emoticon_insert_span (EEmoticon *emoticon,
                insert_delete_event (document, extension, tmp_range);
                g_object_unref (tmp_range);
 
-               dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+               dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
 
                if (!smiley_written) {
                        if (!e_html_editor_undo_redo_manager_is_operation_in_progress (manager)) {
@@ -1912,7 +1913,7 @@ fix_paragraph_structure_after_pressing_enter_after_smiley (WebKitDOMDocument *do
 
 static gboolean
 fix_paragraph_structure_after_pressing_enter (WebKitDOMDocument *document,
-                                             EHTMLEditorWebExtension *extension)
+                                              EHTMLEditorWebExtension *extension)
 {
        gboolean prev_is_heading = FALSE;
        gint ii, length;
@@ -2206,7 +2207,7 @@ insert_tabulator (WebKitDOMDocument *document,
                ev->before.end.y = ev->before.start.y;
        }
 
-       success = dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, "\t");
+       success = dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_TEXT, "\t");
 
        if (ev) {
                if (success) {
@@ -2604,7 +2605,7 @@ body_scroll_event_cb (WebKitDOMElement *element,
        if (!e_html_editor_web_extension_get_inline_spelling_enabled (extension))
                return;
 
-       document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
+       document = webkit_dom_dom_window_get_document (WEBKIT_DOM_DOM_WINDOW (element));
 
        context = g_slice_new0 (TimeoutContext);
        context->extension = extension;
@@ -2626,8 +2627,8 @@ body_scroll_event_cb (WebKitDOMElement *element,
 
 void
 body_input_event_process (WebKitDOMDocument *document,
-                         EHTMLEditorWebExtension *extension,
-                         WebKitDOMEvent *event)
+                          EHTMLEditorWebExtension *extension,
+                          WebKitDOMEvent *event)
 {
        EHTMLEditorUndoRedoManager *manager;
        gboolean do_spell_check = FALSE;
@@ -3091,7 +3092,7 @@ dom_remove_node_and_parents_if_empty (WebKitDOMNode *node)
 
 void
 dom_merge_siblings_if_necessary (WebKitDOMDocument *document,
-                                WebKitDOMDocumentFragment *deleted_content)
+                                 WebKitDOMDocumentFragment *deleted_content)
 {
        gboolean equal_nodes;
        gint ii, length;
@@ -3177,7 +3178,7 @@ dom_merge_siblings_if_necessary (WebKitDOMDocument *document,
  * BackSpace or Delete. */
 void
 body_key_up_event_process_backspace_or_delete (WebKitDOMDocument *document,
-                                              EHTMLEditorWebExtension *extension,
+                                               EHTMLEditorWebExtension *extension,
                                                gboolean delete)
 {
        gint level;
@@ -3300,7 +3301,7 @@ body_key_up_event_process_backspace_or_delete (WebKitDOMDocument *document,
 
 void
 body_key_up_event_process_return_key (WebKitDOMDocument *document,
-                                     EHTMLEditorWebExtension *extension)
+                                      EHTMLEditorWebExtension *extension)
 {
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
        WebKitDOMNode *parent;
@@ -3412,7 +3413,7 @@ fix_structure_after_pasting_multiline_content (WebKitDOMNode *node)
 
 static gboolean
 delete_hidden_space (WebKitDOMDocument *document,
-                    EHTMLEditorWebExtension *extension)
+                     EHTMLEditorWebExtension *extension)
 {
        gint citation_level;
        WebKitDOMElement *selection_start_marker, *selection_end_marker, *block;
@@ -4463,7 +4464,7 @@ append_new_block (WebKitDOMElement *parent,
 
 static WebKitDOMElement *
 create_and_append_new_block (WebKitDOMDocument *document,
-                            EHTMLEditorWebExtension *extension,
+                             EHTMLEditorWebExtension *extension,
                              WebKitDOMElement *parent,
                              WebKitDOMElement *block_template,
                              const gchar *content)
@@ -4602,7 +4603,7 @@ replace_selection_markers (gchar **text)
  * setting it to another one and finally getting innerHTML from it */
 static void
 parse_html_into_blocks (WebKitDOMDocument *document,
-                       EHTMLEditorWebExtension *extension,
+                        EHTMLEditorWebExtension *extension,
                         WebKitDOMElement *parent,
                         WebKitDOMElement *passed_block_template,
                         const gchar *html)
@@ -4876,6 +4877,10 @@ parse_html_into_blocks (WebKitDOMDocument *document,
                        child = webkit_dom_node_get_last_child (
                                WEBKIT_DOM_NODE (parent));
                        if (child) {
+                               EContentEditorContentFlags flags;
+
+                               flags = e_html_editor_web_extension_get_current_content_flags (extension);
+
                                child = webkit_dom_node_get_first_child (child);
                                if (child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)) {
                                        /* If the processed HTML contained just
@@ -4884,7 +4889,7 @@ parse_html_into_blocks (WebKitDOMDocument *document,
                                                webkit_dom_element_set_id (
                                                        WEBKIT_DOM_ELEMENT (child),
                                                        "-x-evo-last-br");
-                               } else if (!e_html_editor_web_extension_is_editting_message (extension))
+                               } else if (!(flags & E_CONTENT_EDITOR_MESSAGE_EDITTING))
                                        create_and_append_new_block (
                                                document, extension, parent, block_template, "<br>");
                        } else
@@ -5299,21 +5304,6 @@ register_html_events_handlers (WebKitDOMHTMLElement *body,
                extension);
 }
 
-
-static void
-rename_attribute (WebKitDOMElement *element,
-                  const gchar *from,
-                  const gchar *to)
-{
-       gchar *value;
-
-       value = webkit_dom_element_get_attribute (element, from);
-       if (value)
-               webkit_dom_element_set_attribute (element, to, value, NULL);
-       webkit_dom_element_remove_attribute (element, from);
-       g_free (value);
-}
-
 static void
 set_monospace_font_family_on_body (WebKitDOMElement *body,
                                    gboolean html_mode)
@@ -5330,14 +5320,14 @@ set_monospace_font_family_on_body (WebKitDOMElement *body,
         * font-family style to the body, so WebKit will know about it and will
         * avoid the described behaviour. */
        if (!html_mode) {
-               rename_attribute (WEBKIT_DOM_ELEMENT (body), "data-style", "style");
+               element_rename_attribute (WEBKIT_DOM_ELEMENT (body), "data-style", "style");
                webkit_dom_element_set_attribute (
                        WEBKIT_DOM_ELEMENT (body),
                        "style",
                        "font-family: Monospace;",
                        NULL);
        } else {
-               rename_attribute (WEBKIT_DOM_ELEMENT (body), "style", "data-style");
+               element_rename_attribute (WEBKIT_DOM_ELEMENT (body), "style", "data-style");
        }
 }
 
@@ -5346,6 +5336,7 @@ dom_convert_content (WebKitDOMDocument *document,
                       EHTMLEditorWebExtension *extension,
                       const gchar *preferred_text)
 {
+       EContentEditorContentFlags flags;
        gboolean start_bottom, empty = FALSE;
        gchar *inner_html;
        gint ii, length;
@@ -5361,6 +5352,8 @@ dom_convert_content (WebKitDOMDocument *document,
        start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
        g_object_unref (settings);
 
+       flags = e_html_editor_web_extension_get_current_content_flags (extension);
+
        dom_window = webkit_dom_document_get_default_view (document);
        body = webkit_dom_document_get_body (document);
        /* Wrapper that will represent the new body. */
@@ -5570,8 +5563,8 @@ dom_convert_content (WebKitDOMDocument *document,
        /* If not editting a message, don't add any new block and just place
         * the carret in the beginning of content. We want to have the same
         * behaviour when editting message as new or we start replying on top. */
-       if (e_html_editor_web_extension_is_message_from_edit_as_new (extension) ||
-           !e_html_editor_web_extension_is_editting_message (extension) ||
+       if ((flags & E_CONTENT_EDITOR_MESSAGE_EDIT_AS_NEW) ||
+           !(flags & E_CONTENT_EDITOR_MESSAGE_EDITTING) ||
             !start_bottom) {
                WebKitDOMNode *child;
 
@@ -5720,7 +5713,7 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
 
                /* Remove the text that was meant to be replaced by the pasted text */
                dom_exec_command (
-                       document, extension, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+                       document, extension, E_CONTENT_EDITOR_COMMAND_DELETE, NULL);
 
                dom_selection_save (document);
 
@@ -5906,10 +5899,10 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
                inner_html = webkit_dom_element_get_inner_html (WEBKIT_DOM_ELEMENT (element));
 
        dom_exec_command (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
+               document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_HTML, inner_html);
 
        if (g_str_has_suffix (inner_html, " "))
-               dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, " ");
+               dom_exec_command (document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_TEXT, " ");
 
        g_free (inner_html);
 
@@ -6073,6 +6066,7 @@ dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
 
        dom_selection_restore (document);
  out:
+       dom_check_magic_links (document, extension, FALSE);
        dom_force_spell_check_in_viewport (document, extension);
        dom_scroll_to_caret (document);
 
@@ -6101,7 +6095,7 @@ get_indentation_level (WebKitDOMElement *element)
 
 static void
 process_blockquote (WebKitDOMElement *blockquote,
-                   gboolean replace_indentation_with_spaces)
+                    gboolean replace_indentation_with_spaces)
 {
        WebKitDOMNodeList *list;
        int jj, length;
@@ -6266,8 +6260,8 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                             gint level,
                             GString *output)
 {
-       EHTMLEditorSelectionBlockFormat format;
-       EHTMLEditorSelectionAlignment alignment;
+       EContentEditorBlockFormat format;
+       EContentEditorAlignment alignment;
        gint counter = 1;
        gchar *indent_per_level = g_strnfill (SPACES_PER_LIST_LEVEL, ' ');
        WebKitDOMNode *item;
@@ -6318,10 +6312,10 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                        node = webkit_dom_node_get_next_sibling (node);
                                }
 
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
+                               if (alignment == E_CONTENT_EDITOR_ALIGNMENT_LEFT)
                                        g_string_append (item_value, line->str);
 
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+                               if (alignment == E_CONTENT_EDITOR_ALIGNMENT_CENTER) {
                                        gchar *fill = NULL;
                                        gint fill_length;
 
@@ -6341,7 +6335,7 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                        g_free (fill);
                                }
 
-                               if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+                               if (alignment == E_CONTENT_EDITOR_ALIGNMENT_RIGHT) {
                                        gchar *fill = NULL;
                                        gint fill_length;
 
@@ -6366,14 +6360,14 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                g_free (text_content);
                        }
 
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) {
+                       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST) {
                                space = g_strnfill (SPACES_PER_LIST_LEVEL - 2, ' ');
                                item_str = g_strdup_printf (
                                        "%s* %s", space, item_value->str);
                                g_free (space);
                        }
 
-                       if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+                       if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST) {
                                gint length = 1, tmp = counter;
 
                                while ((tmp = tmp / 10) > 1)
@@ -6388,10 +6382,10 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                g_free (space);
                        }
 
-                       if (format > E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+                       if (format > E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST) {
                                gchar *value;
 
-                               if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
+                               if (format == E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
                                        value = get_alpha_value (counter, FALSE);
                                else
                                        value = get_roman_value (counter, FALSE);
@@ -6403,7 +6397,7 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                g_free (value);
                        }
 
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) {
+                       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_LEFT) {
                                for (ii = 0; ii < level - 1; ii++) {
                                        g_string_append (output, indent_per_level);
                                }
@@ -6413,7 +6407,7 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                g_string_append (output, item_str);
                        }
 
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+                       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_RIGHT) {
                                if (!wrapped) {
                                        gchar *fill = NULL;
                                        gint fill_length;
@@ -6438,7 +6432,7 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
                                        g_string_append (output, item_str);
                        }
 
-                       if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+                       if (alignment == E_CONTENT_EDITOR_ALIGNMENT_CENTER) {
                                if (!wrapped) {
                                        gchar *fill = NULL;
                                        gint fill_length = 0;
@@ -6518,7 +6512,7 @@ remove_evolution_attributes (WebKitDOMElement *element)
 
 static void
 convert_element_from_html_to_plain_text (WebKitDOMDocument *document,
-                                        EHTMLEditorWebExtension *extension,
+                                         EHTMLEditorWebExtension *extension,
                                          WebKitDOMElement *element,
                                          gboolean *wrap,
                                          gboolean *quote)
@@ -6623,6 +6617,14 @@ convert_element_from_html_to_plain_text (WebKitDOMDocument *document,
        g_free (inner_html);
 }
 
+void
+dom_convert_element_from_html_to_plain_text (WebKitDOMDocument *document,
+                                             EHTMLEditorWebExtension *extension,
+                                             WebKitDOMElement *element)
+{
+       convert_element_from_html_to_plain_text (document, extension, element, NULL, NULL);
+}
+
 static void
 process_elements (EHTMLEditorWebExtension *extension,
                   WebKitDOMNode *node,
@@ -6894,6 +6896,21 @@ process_elements (EHTMLEditorWebExtension *extension,
 
                        first_child = webkit_dom_node_get_first_child (child);
 
+                       /* Don't generate any text if the signature is set to None. */
+                       if (!changing_mode) {
+                               gchar *id;
+
+                               id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (first_child));
+                               if (g_strcmp0 (id, "none") == 0) {
+                                       g_free (id);
+
+                                       remove_node (child);
+                                       skip_node = TRUE;
+                                       goto next;
+                               }
+                               g_free (id);
+                       }
+
                        if (!to_plain_text) {
                                remove_base_attributes (
                                        WEBKIT_DOM_ELEMENT (child));
@@ -7194,7 +7211,7 @@ static void
 toggle_paragraphs_style_in_element (WebKitDOMDocument *document,
                                     EHTMLEditorWebExtension *extension,
                                     WebKitDOMElement *element,
-                                   gboolean html_mode)
+                                    gboolean html_mode)
 {
        gint ii, length;
        WebKitDOMNodeList *paragraphs;
@@ -7278,8 +7295,10 @@ toggle_paragraphs_style (WebKitDOMDocument *document,
 
 gchar *
 dom_process_content_for_draft (WebKitDOMDocument *document,
-                              gboolean only_inner_body)
+                               EHTMLEditorWebExtension *extension,
+                               gboolean only_inner_body)
 {
+       gboolean selection_saved = FALSE;
        gchar *content;
        gint ii, length;
        WebKitDOMHTMLElement *body;
@@ -7292,6 +7311,12 @@ dom_process_content_for_draft (WebKitDOMDocument *document,
        webkit_dom_element_set_attribute (
                WEBKIT_DOM_ELEMENT (body), "data-evo-draft", "", NULL);
 
+       if (webkit_dom_document_get_element_by_id (document, "-x-evo-selection-start-marker"))
+               selection_saved = TRUE;
+
+       if (!selection_saved)
+               dom_selection_save (document);
+
        document_element = webkit_dom_document_get_document_element (document);
 
        document_element_clone = webkit_dom_node_clone_node_with_error (
@@ -7335,6 +7360,12 @@ dom_process_content_for_draft (WebKitDOMDocument *document,
        webkit_dom_element_remove_attribute (
                WEBKIT_DOM_ELEMENT (body), "data-evo-draft");
 
+       dom_selection_restore (document);
+       dom_force_spell_check_in_viewport (document, extension);
+
+       if (selection_saved)
+               dom_selection_save (document);
+
        return content;
 }
 
@@ -7536,7 +7567,7 @@ restore_image (WebKitDOMDocument *document,
        g_object_unref (list);
 }
 
-static void
+void
 dom_restore_images (WebKitDOMDocument *document,
                     GVariant *inline_images_to_restore)
 {
@@ -7550,11 +7581,9 @@ dom_restore_images (WebKitDOMDocument *document,
 
 gchar *
 dom_process_content_for_html (WebKitDOMDocument *document,
-                              EHTMLEditorWebExtension *extension,
-                              const gchar *from_domain)
+                              EHTMLEditorWebExtension *extension)
 {
        gint ii, length;
-       GVariant *inline_images_to_restore = NULL;
        gchar *html_content;
        WebKitDOMElement *element;
        WebKitDOMNode *node, *document_clone;
@@ -7562,9 +7591,6 @@ dom_process_content_for_html (WebKitDOMDocument *document,
        GSettings *settings;
        gboolean send_editor_colors = FALSE;
 
-       if (from_domain != NULL)
-               inline_images_to_restore = dom_get_inline_images_data (document, extension, from_domain);
-
        document_clone = webkit_dom_node_clone_node_with_error (
                WEBKIT_DOM_NODE (webkit_dom_document_get_document_element (document)), TRUE, NULL);
        element = webkit_dom_element_query_selector (
@@ -7628,7 +7654,7 @@ dom_process_content_for_html (WebKitDOMDocument *document,
 
                data_style_node = webkit_dom_node_list_item (list, ii);
 
-               rename_attribute (WEBKIT_DOM_ELEMENT (data_style_node), "data-style", "style");
+               element_rename_attribute (WEBKIT_DOM_ELEMENT (data_style_node), "data-style", "style");
                g_object_unref (data_style_node);
        }
        g_object_unref (list);
@@ -7640,11 +7666,6 @@ dom_process_content_for_html (WebKitDOMDocument *document,
 
        g_object_unref (document_clone);
 
-       if (from_domain && inline_images_to_restore) {
-               dom_restore_images (document, inline_images_to_restore);
-               g_object_unref (inline_images_to_restore);
-       }
-
        return html_content;
 }
 
@@ -7857,9 +7878,9 @@ dom_process_content_after_load (WebKitDOMDocument *document,
        /* Don't use CSS when possible to preserve compatibility with older
         * versions of Evolution or other MUAs */
        dom_exec_command (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_STYLE_WITH_CSS, "false");
+               document, extension, E_CONTENT_EDITOR_COMMAND_STYLE_WITH_CSS, "false");
        dom_exec_command (
-               document, extension, E_HTML_EDITOR_VIEW_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR, "p");
+               document, extension, E_CONTENT_EDITOR_COMMAND_DEFAULT_PARAGRAPH_SEPARATOR, "p");
 
        body = webkit_dom_document_get_body (document);
 
@@ -7893,7 +7914,7 @@ dom_process_content_after_load (WebKitDOMDocument *document,
                /* Restore the selection how it was when the draft was saved */
                dom_move_caret_into_element (document, WEBKIT_DOM_ELEMENT (body), FALSE);
                dom_selection_restore (document);
-               dom_remove_embed_style_sheet (document);
+               dom_remove_embedded_style_sheet (document);
        }
 
        /* The composer body could be empty in some case (loading an empty string
@@ -8142,7 +8163,9 @@ dom_insert_html (WebKitDOMDocument *document,
                }
 
                dom_exec_command (
-                       document, extension, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html_text);
+                       document, extension, E_CONTENT_EDITOR_COMMAND_INSERT_HTML, html_text);
+               /* FIXME WK2 - dom_fix_file_uri_images
+               e_html_editor_view_fix_file_uri_images (view);*/
                if (strstr (html_text, "id=\"-x-evo-selection-start-marker\""))
                        dom_selection_restore (document);
 
@@ -8226,7 +8249,7 @@ save_history_for_delete_or_backspace (WebKitDOMDocument *document,
                        dom_selection, "move", delete_key ? "right" : "left", "character");
 
                tmp_range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
-               if (webkit_dom_range_compare_boundary_points (tmp_range, 2 /* END_TO_END */, range, NULL) == 
0) {
+               if (webkit_dom_range_compare_boundary_points (tmp_range, WEBKIT_DOM_RANGE_END_TO_END, range, 
NULL) == 0) {
                        g_object_unref (dom_selection);
                        g_object_unref (range);
                        g_object_unref (tmp_range);
@@ -8334,7 +8357,7 @@ save_history_for_delete_or_backspace (WebKitDOMDocument *document,
                                                dom_selection, "move", delete_key ? "right" : "left", 
"character");
 
                                        tmp_range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, 
NULL);
-                                       if (webkit_dom_range_compare_boundary_points (tmp_range, 2 /* 
END_TO_END */, actual_range, NULL) != 0) {
+                                       if (webkit_dom_range_compare_boundary_points (tmp_range, 
WEBKIT_DOM_RANGE_END_TO_END, actual_range, NULL) != 0) {
                                                WebKitDOMNode *actual_block;
                                                WebKitDOMNode *tmp_block;
 
@@ -8658,10 +8681,10 @@ save_history_for_delete_or_backspace (WebKitDOMDocument *document,
 
 gboolean
 dom_fix_structure_after_delete_before_quoted_content (WebKitDOMDocument *document,
-                                                     EHTMLEditorWebExtension *extension,
-                                                     glong key_code,
-                                                     gboolean control_key,
-                                                     gboolean delete_key)
+                                                      EHTMLEditorWebExtension *extension,
+                                                      glong key_code,
+                                                      gboolean control_key,
+                                                      gboolean delete_key)
 {
        gboolean collapsed = FALSE;
        WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -8880,9 +8903,9 @@ split_citation (WebKitDOMDocument *document,
 
 static gboolean
 delete_last_character_from_previous_line_in_quoted_block (WebKitDOMDocument *document,
-                                                         EHTMLEditorWebExtension *extension,
-                                                         glong key_code,
-                                                         guint state)
+                                                          EHTMLEditorWebExtension *extension,
+                                                          glong key_code,
+                                                          guint state)
 {
        EHTMLEditorHistoryEvent *ev = NULL;
        gboolean hidden_space = FALSE;
@@ -9022,9 +9045,9 @@ delete_last_character_from_previous_line_in_quoted_block (WebKitDOMDocument *doc
 
 gboolean
 dom_delete_last_character_on_line_in_quoted_block (WebKitDOMDocument *document,
-                                                  EHTMLEditorWebExtension *extension,
-                                                  glong key_code,
-                                                  gboolean control_key)
+                                                   EHTMLEditorWebExtension *extension,
+                                                   glong key_code,
+                                                   gboolean control_key)
 {
        gboolean success = FALSE;
        WebKitDOMElement *element;
@@ -9134,7 +9157,7 @@ selection_is_in_empty_list_item (WebKitDOMNode *selection_start_marker)
 
 static gboolean
 return_pressed_in_image_wrapper (WebKitDOMDocument *document,
-                                EHTMLEditorWebExtension *extension)
+                                 EHTMLEditorWebExtension *extension)
 {
        EHTMLEditorHistoryEvent *ev = NULL;
        EHTMLEditorUndoRedoManager *manager;
@@ -9215,7 +9238,7 @@ return_pressed_in_image_wrapper (WebKitDOMDocument *document,
 
 gboolean
 return_pressed_in_empty_list_item (WebKitDOMDocument *document,
-                                  EHTMLEditorWebExtension *extension)
+                                   EHTMLEditorWebExtension *extension)
 {
        WebKitDOMElement *selection_start_marker;
        WebKitDOMNode *parent;
@@ -9306,7 +9329,7 @@ return_pressed_in_empty_list_item (WebKitDOMDocument *document,
 
 static void
 process_smiley_on_delete_or_backspace (WebKitDOMDocument *document,
-                                      EHTMLEditorWebExtension *extension)
+                                       EHTMLEditorWebExtension *extension)
 {
        WebKitDOMElement *element;
        WebKitDOMNode *parent;
@@ -9378,7 +9401,7 @@ process_smiley_on_delete_or_backspace (WebKitDOMDocument *document,
 
 gboolean
 key_press_event_process_return_key (WebKitDOMDocument *document,
-                                   EHTMLEditorWebExtension *extension)
+                                    EHTMLEditorWebExtension *extension)
 {
        gboolean first_cell = FALSE;
        WebKitDOMNode *table = NULL;
@@ -9440,7 +9463,7 @@ key_press_event_process_return_key (WebKitDOMDocument *document,
 
 static gboolean
 remove_empty_bulleted_list_item (WebKitDOMDocument *document,
-                                EHTMLEditorWebExtension *extension)
+                                 EHTMLEditorWebExtension *extension)
 {
        EHTMLEditorUndoRedoManager *manager;
        WebKitDOMElement *selection_start;
@@ -9526,7 +9549,7 @@ remove_empty_bulleted_list_item (WebKitDOMDocument *document,
 
 gboolean
 key_press_event_process_backspace_key (WebKitDOMDocument *document,
-                                      EHTMLEditorWebExtension *extension)
+                                       EHTMLEditorWebExtension *extension)
 {
        /* BackSpace pressed in the beginning of quoted content changes
         * format to normal and inserts text into body */
@@ -9580,10 +9603,10 @@ key_press_event_process_backspace_key (WebKitDOMDocument *document,
 
 gboolean
 key_press_event_process_delete_or_backspace_key (WebKitDOMDocument *document,
-                                                EHTMLEditorWebExtension *extension,
-                                                glong key_code,
-                                                gboolean control_key,
-                                                gboolean delete)
+                                                 EHTMLEditorWebExtension *extension,
+                                                 glong key_code,
+                                                 gboolean control_key,
+                                                 gboolean delete)
 {
        gboolean html_mode;
        gboolean local_delete;
@@ -9767,18 +9790,18 @@ toggle_tables (WebKitDOMDocument *document,
 
                if (html_mode) {
                        element_remove_class (WEBKIT_DOM_ELEMENT (table), "-x-evo-plaintext-table");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-width", "width");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-cellspacing", "cellspacing");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-cellpadding", "cellpadding");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-border", "border");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-width", "width");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-cellspacing", 
"cellspacing");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-cellpadding", 
"cellpadding");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "data-border", "border");
                } else {
                        element_add_class (WEBKIT_DOM_ELEMENT (table), "-x-evo-plaintext-table");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "width", "data-width");
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "cellspacing", "data-cellspacing");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "width", "data-width");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "cellspacing", 
"data-cellspacing");
                        webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (table), "cellspacing", "0", 
NULL);
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "cellpadding", "data-cellpadding");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "cellpadding", 
"data-cellpadding");
                        webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (table), "cellpadding", "0", 
NULL);
-                       rename_attribute (WEBKIT_DOM_ELEMENT (table), "border", "data-border");
+                       element_rename_attribute (WEBKIT_DOM_ELEMENT (table), "border", "data-border");
                        webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (table), "border", "0", NULL);
                }
                g_object_unref (table);
@@ -9788,7 +9811,7 @@ toggle_tables (WebKitDOMDocument *document,
 
 static void
 toggle_unordered_lists (WebKitDOMDocument *document,
-                       gboolean html_mode)
+                        gboolean html_mode)
 {
        WebKitDOMNodeList *list;
        gint ii, length;
@@ -9877,11 +9900,11 @@ dom_process_content_after_mode_change (WebKitDOMDocument *document,
        e_html_editor_undo_redo_manager_clean_history (manager);
 }
 
-gint
+guint
 dom_get_caret_offset (WebKitDOMDocument *document,
-                     EHTMLEditorWebExtension *extension)
+                      EHTMLEditorWebExtension *extension)
 {
-       gint ret_val;
+       guint ret_val;
        gchar *text;
        WebKitDOMDOMWindow *dom_window;
        WebKitDOMDOMSelection *dom_selection;
@@ -9929,10 +9952,10 @@ dom_get_caret_offset (WebKitDOMDocument *document,
        return ret_val;
 }
 
-gint
+guint
 dom_get_caret_position (WebKitDOMDocument *document)
 {
-       gint ret_val;
+       guint ret_val;
        gchar *text;
        WebKitDOMHTMLElement *body;
        WebKitDOMDOMWindow *dom_window;
@@ -9970,7 +9993,7 @@ dom_get_caret_position (WebKitDOMDocument *document)
 
 void
 dom_save_history_for_drop (WebKitDOMDocument *document,
-                          EHTMLEditorWebExtension *extension)
+                           EHTMLEditorWebExtension *extension)
 {
        EHTMLEditorUndoRedoManager *manager;
        EHTMLEditorHistoryEvent *event;
@@ -10099,8 +10122,8 @@ dom_drag_and_drop_end (WebKitDOMDocument *document,
 
 static void
 dom_set_link_color_in_document (WebKitDOMDocument *document,
-                               const gchar *color,
-                               gboolean visited)
+                                const gchar *color,
+                                gboolean visited)
 {
        gchar *color_str = NULL;
        const gchar *style_id;
@@ -10139,14 +10162,36 @@ dom_set_link_color_in_document (WebKitDOMDocument *document,
 
 void
 dom_set_link_color (WebKitDOMDocument *document,
-                   const gchar *color)
+                    const gchar *color)
 {
        dom_set_link_color_in_document (document, color, FALSE);
 }
 
 void
 dom_set_visited_link_color (WebKitDOMDocument *document,
-                           const gchar *color)
+                            const gchar *color)
 {
        dom_set_link_color_in_document (document, color, TRUE);
 }
+
+void
+dom_fix_file_uri_images (WebKitDOMDocument *document)
+{
+       gint ii, length;
+       WebKitDOMNodeList *list;
+
+       list = webkit_dom_document_query_selector_all (
+               document, "img[src^=\"file://\"]", NULL);
+       length = webkit_dom_node_list_get_length (list);
+
+       for (ii = 0; ii < length; ii++) {
+               WebKitDOMNode *node;
+               gchar *uri;
+
+               node = webkit_dom_node_list_item (list, ii);
+               uri = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "src");
+               g_free (uri);
+       }
+
+       g_object_unref (list);
+}
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.h 
b/web-extensions/composer/e-html-editor-view-dom-functions.h
index cfd778d..75467ff 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.h
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.h
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
 
 gboolean       dom_exec_command                (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension,
-                                                EHTMLEditorViewCommand command,
+                                                EContentEditorCommand command,
                                                 const gchar *value);
 
 void           dom_force_spell_check_for_current_paragraph
@@ -52,7 +52,7 @@ void          dom_turn_spell_check_off        (WebKitDOMDocument *document,
 void           dom_embed_style_sheet           (WebKitDOMDocument *document,
                                                 const gchar *style_sheet_content);
 
-void           dom_remove_embed_style_sheet    (WebKitDOMDocument *document);
+void           dom_remove_embedded_style_sheet (WebKitDOMDocument *document);
 
 void           dom_register_input_event_listener_on_body
                                                (WebKitDOMDocument *document,
@@ -132,16 +132,24 @@ gboolean  dom_process_on_key_press        (WebKitDOMDocument *document,
                                                 glong key_code,
                                                 gboolean control_key);
 
+void           dom_convert_element_from_html_to_plain_text
+                                               (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
+                                                WebKitDOMElement *element);
+
 gchar *                dom_process_content_for_draft   (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
                                                 gboolean only_inner_body);
 
 gchar *                dom_process_content_for_plain_text
                                                (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 
+void           dom_restore_images              (WebKitDOMDocument *document,
+                                                GVariant *inline_images_to_restore);
+
 gchar *                dom_process_content_for_html    (WebKitDOMDocument *document,
-                                                EHTMLEditorWebExtension *extension,
-                                                const gchar *from_domain);
+                                                EHTMLEditorWebExtension *extension);
 
 gboolean       dom_check_if_conversion_needed  (WebKitDOMDocument *document);
 
@@ -149,9 +157,9 @@ void                dom_process_content_after_mode_change
                                                (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
 
-gint           dom_get_caret_offset            (WebKitDOMDocument *document,
+guint          dom_get_caret_offset            (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
-gint           dom_get_caret_position          (WebKitDOMDocument *document);
+guint          dom_get_caret_position          (WebKitDOMDocument *document);
 
 void           dom_drag_and_drop_end           (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
@@ -215,7 +223,7 @@ gint                get_citation_level              (WebKitDOMNode *node,
                                                 gboolean set_plaintext_quoted);
 void           dom_save_history_for_drop       (WebKitDOMDocument *document,
                                                 EHTMLEditorWebExtension *extension);
-
+void           dom_fix_file_uri_images         (WebKitDOMDocument *document);
 G_END_DECLS
 
 #endif /* E_HTML_EDITOR_VIEW_DOM_FUNCTIONS_H */
diff --git a/web-extensions/composer/e-html-editor-web-extension.c 
b/web-extensions/composer/e-html-editor-web-extension.c
index b6f6d32..1e07f8a 100644
--- a/web-extensions/composer/e-html-editor-web-extension.c
+++ b/web-extensions/composer/e-html-editor-web-extension.c
@@ -58,8 +58,8 @@ struct _EHTMLEditorWebExtensionPrivate {
        gboolean selection_changed_callbacks_blocked;
 
        /* These properties show the actual state of EHTMLEditorView */
-       EHTMLEditorSelectionAlignment alignment;
-       EHTMLEditorSelectionBlockFormat block_format;
+       EContentEditorAlignment alignment;
+       EContentEditorBlockFormat block_format;
        gchar *background_color;
        gchar *font_color;
        gchar *font_name;
@@ -75,11 +75,6 @@ struct _EHTMLEditorWebExtensionPrivate {
        gboolean underline;
 
        gboolean force_image_load;
-       gboolean changed;
-       gboolean inline_spelling;
-       gboolean magic_links;
-       gboolean magic_smileys;
-       gboolean unicode_smileys;
        gboolean html_mode;
        gboolean return_key_pressed;
        gboolean space_key_pressed;
@@ -88,11 +83,6 @@ struct _EHTMLEditorWebExtensionPrivate {
 
        gboolean convert_in_situ;
        gboolean body_input_event_removed;
-       gboolean is_message_from_draft;
-       gboolean is_editting_message;
-       gboolean is_from_new_message;
-       gboolean is_message_from_edit_as_new;
-       gboolean is_message_from_selection;
        gboolean dont_save_history_in_body_input;
        gboolean composition_in_progress;
        gboolean is_pasting_content_from_itself;
@@ -101,7 +91,10 @@ struct _EHTMLEditorWebExtensionPrivate {
        GHashTable *inline_images;
 
        WebKitDOMNode *node_under_mouse_click;
-       guint node_under_mouse_click_flags;
+
+       GSettings *mail_settings;
+
+       EContentEditorContentFlags content_flags;
 
        EHTMLEditorUndoRedoManager *undo_redo_manager;
        ESpellChecker *spell_checker;
@@ -113,39 +106,25 @@ static const char introspection_xml[] =
 "<node>"
 "  <interface name='" E_HTML_EDITOR_WEB_EXTENSION_INTERFACE "'>"
 "<!-- ********************************************************* -->"
-"<!--                       PROPERTIES                          -->"
-"<!-- ********************************************************* -->"
-"    <property type='b' name='ForceImageLoad' access='readwrite'/>"
-"    <property type='b' name='InlineSpelling' access='readwrite'/>"
-"    <property type='b' name='MagicLinks' access='readwrite'/>"
-"    <property type='b' name='MagicSmileys' access='readwrite'/>"
-"    <property type='b' name='HTMLMode' access='readwrite'/>"
-"    <property type='b' name='IsEdittingMessage' access='readwrite'/>"
-"    <property type='b' name='IsMessageFromEditAsNew' access='readwrite'/>"
-"    <property type='b' name='IsMessageFromDraft' access='readwrite'/>"
-"    <property type='b' name='IsMessageFromSelection' access='readwrite'/>"
-"    <property type='b' name='IsFromNewMessage' access='readwrite'/>"
-"    <property type='b' name='IsPastingContentFromItself' access='readwrite'/>"
-"    <property type='u' name='NodeUnderMouseClickFlags' access='readwrite'/>"
-"<!-- ********************************************************* -->"
-"<!-- These properties show the actual state of EHTMLEditorView -->"
+"<!--                          SIGNALS                          -->"
 "<!-- ********************************************************* -->"
-"    <property type='u' name='Alignment' access='readwrite'/>"
-"    <property type='s' name='BackgroundColor' access='readwrite'/>"
-"    <property type='u' name='BlockFormat' access='readwrite'/>"
-"    <property type='b' name='Bold' access='readwrite'/>"
-"    <property type='b' name='Changed' access='readwrite'/>"
-"    <property type='s' name='FontColor' access='readwrite'/>"
-"    <property type='s' name='FontName' access='readwrite'/>"
-"    <property type='u' name='FontSize' access='readwrite'/>"
-"    <property type='b' name='Indented' access='readwrite'/>"
-"    <property type='b' name='Italic' access='readwrite'/>"
-"    <property type='b' name='Monospaced' access='readwrite'/>"
-"    <property type='b' name='Strikethrough' access='readwrite'/>"
-"    <property type='b' name='Subscript' access='readwrite'/>"
-"    <property type='b' name='Superscript' access='readwrite'/>"
-"    <property type='b' name='Underline' access='readwrite'/>"
-"    <property type='s' name='Text' access='readwrite'/>"
+"    <signal name='SelectionChanged'>"
+"      <arg type='i' name='alignment' direction='out'/>"
+"      <arg type='i' name='block_format' direction='out'/>"
+"      <arg type='b' name='indented' direction='out'/>"
+"      <arg type='b' name='bold' direction='out'/>"
+"      <arg type='b' name='italic' direction='out'/>"
+"      <arg type='b' name='underline' direction='out'/>"
+"      <arg type='b' name='strikethrough' direction='out'/>"
+"      <arg type='b' name='monospaced' direction='out'/>"
+"      <arg type='b' name='subscript' direction='out'/>"
+"      <arg type='b' name='superscript' direction='out'/>"
+"      <arg type='b' name='underline' direction='out'/>"
+"      <arg type='i' name='font_size' direction='out'/>"
+"      <arg type='s' name='font_color' direction='out'/>"
+"    </signal>"
+"    <signal name='ContentChanged'>"
+"    </signal>"
 "<!-- ********************************************************* -->"
 "<!--                          METHODS                          -->"
 "<!-- ********************************************************* -->"
@@ -217,42 +196,42 @@ static const char introspection_xml[] =
 "    <method name='EHTMLEditorCellDialogSetElementVAlign'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementAlign'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementNoWrap'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='b' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementHeaderStyle'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='b' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementWidth'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementColSpan'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='i' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementRowSpan'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='i' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "    <method name='EHTMLEditorCellDialogSetElementBgColor'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='value' direction='in'/>"
-"      <arg type='u' name='scope' direction='in'/>"
+"      <arg type='i' name='scope' direction='in'/>"
 "    </method>"
 "<!-- ********************************************************* -->"
 "<!--     Functions that are used in EHTMLEditorHRuleDialog      -->"
@@ -349,6 +328,11 @@ static const char introspection_xml[] =
 "      <arg type='s' name='url' direction='in'/>"
 "      <arg type='s' name='inner_text' direction='in'/>"
 "    </method>"
+"    <method name='EHTMLEditorLinkDialogShow'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='s' name='url' direction='out'/>"
+"      <arg type='s' name='inner_text' direction='out'/>"
+"    </method>"
 "<!-- ********************************************************* -->"
 "<!--     Functions that are used in EHTMLEditorPageDialog     -->"
 "<!-- ********************************************************* -->"
@@ -450,13 +434,27 @@ static const char introspection_xml[] =
 "<!-- ********************************************************* -->"
 "<!--     Functions that are used in EHTMLEditorView            -->"
 "<!-- ********************************************************* -->"
-"    <method name='DOMForceSpellCheck'>"
+"    <method name='SetCurrentContentFlags'>"
 "      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='i' name='content_flags' direction='in'/>"
 "    </method>"
-"    <method name='DOMTurnSpellCheckOff'>"
+"    <method name='SetPastingContentFromItself'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='b' name='value' direction='in'/>"
+"    </method>"
+"    <method name='SetEditorHTMLMode'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='b' name='html_mode' direction='in'/>"
+"      <arg type='b' name='convert' direction='in'/>"
+"    </method>"
+"    <method name='SetConvertInSitu'>"
 "      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='b' name='value' direction='in'/>"
 "    </method>"
-"    <method name='DOMCheckMagicLinks'>"
+"    <method name='DOMForceSpellCheck'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"    <method name='DOMTurnSpellCheckOff'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
 "    <method name='DOMScrollToCaret'>"
@@ -466,7 +464,7 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='style_sheet_content' direction='in'/>"
 "    </method>"
-"    <method name='DOMRemoveEmbedStyleSheet'>"
+"    <method name='DOMRemoveEmbeddedStyleSheet'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
 "    <method name='DOMSaveSelection'>"
@@ -475,10 +473,6 @@ static const char introspection_xml[] =
 "    <method name='DOMRestoreSelection'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
-"    <method name='DOMIsSelectionSaved'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='b' name='selection_saved' direction='out'/>"
-"    </method>"
 "    <method name='DOMQuoteAndInsertTextIntoSelection'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='text' direction='in'/>"
@@ -492,25 +486,12 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='b' name='conversion_needed' direction='out'/>"
 "    </method>"
-"    <method name='DOMConvertWhenChangingComposerMode'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"    </method>"
-"    <method name='DOMProcessContentAfterModeChange'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"    </method>"
-"    <method name='DOMProcessContentForHTML'>"
+"    <method name='DOMGetContent'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='from_domain' direction='in'/>"
+"      <arg type='i' name='flags' direction='in'/>"
 "      <arg type='s' name='content' direction='out'/>"
-"    </method>"
-"    <method name='DOMProcessContentForDraft'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='b' name='only_inner_body' direction='in'/>"
-"      <arg type='s' name='content' direction='out'/>"
-"    </method>"
-"    <method name='DOMProcessContentForPlainText'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='s' name='content' direction='out'/>"
+"      <arg type='v' name='inline_images' direction='out'/>"
 "    </method>"
 "    <method name='DOMInsertHTML'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -520,22 +501,15 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='preffered_text' direction='in'/>"
 "    </method>"
-"    <method name='DOMGetInlineImagesData'>"
-"      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='s' name='uid_domain' direction='in'/>"
-"      <arg type='a*' name='image_data' direction='out'/>"
-"    </method>"
 "    <method name='DOMAddNewInlineImageIntoList'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='filename' direction='in'/>"
 "      <arg type='s' name='cid_src' direction='in'/>"
 "      <arg type='s' name='src' direction='in'/>"
 "    </method>"
-"    <method name='DOMReplaceBase64ImageSrc'>"
+"    <method name='DOMReplaceImageSrc'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "      <arg type='s' name='selector' direction='in'/>"
-"      <arg type='s' name='base64_content' direction='in'/>"
-"      <arg type='s' name='filename' direction='in'/>"
 "      <arg type='s' name='uri' direction='in'/>"
 "    </method>"
 "    <method name='DOMDragAndDropEnd'>"
@@ -557,10 +531,14 @@ static const char introspection_xml[] =
 "    <method name='DOMSelectionIndent'>"
 "      <arg type='t' name='page_id' direction='in'/>"
 "    </method>"
-"    <method name='DOMSelectionInsertBase64Image'>"
+"    <method name='DOMSelectionSave'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"    <method name='DOMSelectionRestore'>"
+"      <arg type='t' name='page_id' direction='in'/>"
+"    </method>"
+"    <method name='DOMSelectionInsertImage'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='s' name='base64_content' direction='in'/>"
-"      <arg type='s' name='filename' direction='in'/>"
 "      <arg type='s' name='uri' direction='in'/>"
 "    </method>"
 "    <method name='DOMSelectionReplace'>"
@@ -569,7 +547,7 @@ static const char introspection_xml[] =
 "    </method>"
 "    <method name='DOMSelectionSetAlignment'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='u' name='alignment' direction='in'/>"
+"      <arg type='i' name='alignment' direction='in'/>"
 "    </method>"
 "    <method name='DOMSelectionSetBold'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -577,7 +555,7 @@ static const char introspection_xml[] =
 "    </method>"
 "    <method name='DOMSelectionSetBlockFormat'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='u' name='block_format' direction='in'/>"
+"      <arg type='i' name='block_format' direction='in'/>"
 "    </method>"
 "    <method name='DOMSelectionSetFontColor'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -585,7 +563,7 @@ static const char introspection_xml[] =
 "    </method>"
 "    <method name='DOMSelectionSetFontSize'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='u' name='font_size' direction='in'/>"
+"      <arg type='i' name='font_size' direction='in'/>"
 "    </method>"
 "    <method name='DOMSelectionSetItalic'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -632,9 +610,16 @@ static const char introspection_xml[] =
 "    </method>"
 "    <method name='DOMInsertSignature'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='s' name='signature_html' direction='in'/>"
-"      <arg type='b' name='top_signature' direction='in'/>"
-"      <arg type='b' name='start_bottom' direction='in'/>"
+"      <arg type='s' name='content' direction='in'/>"
+"      <arg type='b' name='is_html' direction='in'/>"
+"      <arg type='s' name='signature_id' direction='in'/>"
+"      <arg type='b' name='set_signature_from_message' direction='in'/>"
+"      <arg type='b' name='check_if_signature_is_changed' direction='in'/>"
+"      <arg type='b' name='ignore_next_signature_change' direction='in'/>"
+"      <arg type='s' name='new_signature_id' direction='out'/>"
+"      <arg type='b' name='out_set_signature_from_message' direction='out'/>"
+"      <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'/>"
@@ -647,11 +632,11 @@ static const char introspection_xml[] =
 "<!-- ********************************************************* -->"
 "    <method name='DOMGetCaretPosition'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='i' name='position' direction='out'/>"
+"      <arg type='u' name='position' direction='out'/>"
 "    </method>"
 "    <method name='DOMGetCaretOffset'>"
 "      <arg type='t' name='page_id' direction='in'/>"
-"      <arg type='i' name='offset' direction='out'/>"
+"      <arg type='u' name='offset' direction='out'/>"
 "    </method>"
 "    <method name='DOMClearUndoRedoHistory'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -694,8 +679,6 @@ handle_method_call (GDBusConnection *connection,
        if (g_strcmp0 (interface_name, E_HTML_EDITOR_WEB_EXTENSION_INTERFACE) != 0)
                return;
 
-       if (camel_debug ("wex"))
-               printf ("%s - %s\n", G_STRFUNC, method_name);
        if (g_strcmp0 (method_name, "ElementHasAttribute") == 0) {
                gboolean value = FALSE;
                const gchar *element_id, *attribute;
@@ -921,9 +904,9 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementVAlign") == 0) {
                const gchar *value;
-               guint scope;
+               EContentEditorScope scope;
 
-               g_variant_get (parameters, "(t&su)", &page_id, &value, &scope);
+               g_variant_get (parameters, "(t&si)", &page_id, &value, &scope);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -936,7 +919,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementAlign") == 0) {
                const gchar *value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(t&su)", &page_id, &value, &scope);
 
@@ -951,7 +934,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementNoWrap") == 0) {
                gboolean value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(tbu)", &page_id, &value, &scope);
 
@@ -966,7 +949,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementHeaderStyle") == 0) {
                gboolean value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(tbu)", &page_id, &value, &scope);
 
@@ -982,7 +965,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementWidth") == 0) {
                const gchar *value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(t&su)", &page_id, &value, &scope);
 
@@ -997,7 +980,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementColSpan") == 0) {
                glong value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(tiu)", &page_id, &value, &scope);
 
@@ -1012,7 +995,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementRowSpan") == 0) {
                glong value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(tiu)", &page_id, &value, &scope);
 
@@ -1027,7 +1010,7 @@ handle_method_call (GDBusConnection *connection,
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorCellDialogSetElementBgColor") == 0) {
                const gchar *value;
-               guint scope;
+               EContentEditorScope scope;
 
                g_variant_get (parameters, "(t&su)", &page_id, &value, &scope);
 
@@ -1386,6 +1369,20 @@ handle_method_call (GDBusConnection *connection,
                e_html_editor_link_dialog_ok (document, extension, url, inner_text);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "EHTMLEditorLinkDialogShow") == 0) {
+               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;
+
+               printf ("%s:%d\n", __FUNCTION__, __LINE__);
+               document = webkit_web_page_get_dom_document (web_page);
+
+               g_dbus_method_invocation_return_value (
+                       invocation,
+                       e_html_editor_link_dialog_show (document));
        } else if (g_strcmp0 (method_name, "EHTMLEditorPageDialogSaveHistory") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -1763,21 +1760,6 @@ 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, "DOMIsSelectionSaved") == 0) {
-               gboolean selection_saved = FALSE;
-               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);
-               selection_saved = webkit_dom_document_get_element_by_id (
-                       document, "-x-evo-selection-start-marker") != NULL;
-
-               g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(b)", selection_saved));
        } else if (g_strcmp0 (method_name, "DOMTurnSpellCheckOff") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -1786,7 +1768,6 @@ handle_method_call (GDBusConnection *connection,
                if (!web_page)
                        goto error;
 
-               extension->priv->inline_spelling = FALSE;
                document = webkit_web_page_get_dom_document (web_page);
                dom_turn_spell_check_off (document, extension);
                g_dbus_method_invocation_return_value (invocation, NULL);
@@ -1830,7 +1811,7 @@ handle_method_call (GDBusConnection *connection,
                document = webkit_web_page_get_dom_document (web_page);
                dom_embed_style_sheet (document, style_sheet_content);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMRemoveEmbedStyleSheet") == 0) {
+       } else if (g_strcmp0 (method_name, "DOMRemoveEmbeddedStyleSheet") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
@@ -1839,35 +1820,30 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               dom_remove_embed_style_sheet (document);
+               dom_remove_embedded_style_sheet (document);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMForceSpellCheck") == 0) {
-               g_variant_get (parameters, "(t)", &page_id);
+       } else if (g_strcmp0 (method_name, "SetCurrentContentFlags") == 0) {
+               g_variant_get (parameters, "(ti)", &page_id, &extension->priv->content_flags);
 
                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);
-               extension->priv->inline_spelling = TRUE;
-               dom_force_spell_check (document, extension);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMCheckMagicLinks") == 0) {
-               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;
+       } else if (g_strcmp0 (method_name, "SetPastingContentFromItself") == 0) {
+               g_variant_get (
+                       parameters,
+                       "(tb)",
+                       &page_id,
+                       &extension->priv->is_pasting_content_from_itself);
 
-               document = webkit_web_page_get_dom_document (web_page);
-               dom_check_magic_links (document, extension, FALSE);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMCheckIfConversionNeeded") == 0) {
-               gboolean conversion_needed;
+       } else if (g_strcmp0 (method_name, "SetEditorHTMLMode") == 0) {
+               gboolean html_mode = FALSE;
+               gboolean convert = FALSE;
 
-               g_variant_get (parameters, "(t)", &page_id);
+               g_variant_get (parameters, "(tbb)", &page_id, &html_mode, &convert);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -1875,21 +1851,25 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               conversion_needed = dom_check_if_conversion_needed (document);
-               g_dbus_method_invocation_return_value (
-                       invocation, g_variant_new ("(b)", conversion_needed));
-       } else if (g_strcmp0 (method_name, "DOMConvertWhenChangingComposerMode") == 0) {
-               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;
+               convert = convert && extension->priv->html_mode && !html_mode;
+               extension->priv->html_mode = html_mode;
+
+               if (convert)
+                       dom_convert_when_changing_composer_mode (document, extension);
+               else
+                       dom_process_content_after_mode_change (document, extension);
 
-               document = webkit_web_page_get_dom_document (web_page);
-               dom_convert_when_changing_composer_mode (document, extension);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMProcessContentAfterModeChange") == 0) {
+       } else if (g_strcmp0 (method_name, "SetConvertInSitu") == 0) {
+               g_variant_get (
+                       parameters,
+                       "(tb)",
+                       &page_id,
+                       &extension->priv->convert_in_situ);
+
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "DOMForceSpellCheck") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
@@ -1898,13 +1878,12 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               dom_process_content_after_mode_change (document, extension);
+               dom_force_spell_check (document, extension);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMProcessContentForDraft") == 0) {
-               gboolean only_inner_body;
-               gchar *value = NULL;
+       } else if (g_strcmp0 (method_name, "DOMCheckIfConversionNeeded") == 0) {
+               gboolean conversion_needed;
 
-               g_variant_get (parameters, "(tb)", &page_id, &only_inner_body);
+               g_variant_get (parameters, "(t)", &page_id);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -1912,19 +1891,16 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               value = dom_process_content_for_draft (document, only_inner_body);
-
+               conversion_needed = dom_check_if_conversion_needed (document);
                g_dbus_method_invocation_return_value (
-                       invocation,
-                       g_variant_new (
-                               "(@s)",
-                               g_variant_new_take_string (
-                                       value ? value : g_strdup (""))));
-       } else if (g_strcmp0 (method_name, "DOMProcessContentForHTML") == 0) {
+                       invocation, g_variant_new ("(b)", conversion_needed));
+       } else if (g_strcmp0 (method_name, "DOMGetContent") == 0) {
+               EContentEditorGetContentFlags flags;
                const gchar *from_domain;
                gchar *value = NULL;
+               GVariant *inline_images = NULL;
 
-               g_variant_get (parameters, "(t&s)", &page_id, &from_domain);
+               g_variant_get (parameters, "(t&si)", &page_id, &from_domain, &flags);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -1932,33 +1908,48 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               value = dom_process_content_for_html (document, extension, from_domain);
 
-               g_dbus_method_invocation_return_value (
-                       invocation,
-                       g_variant_new (
-                               "(@s)",
-                               g_variant_new_take_string (
-                                       value ? value : g_strdup (""))));
-       } else if (g_strcmp0 (method_name, "DOMProcessContentForPlainText") == 0) {
-               gchar *value = NULL;
+               if ((flags & E_CONTENT_EDITOR_GET_INLINE_IMAGES) && from_domain && *from_domain)
+                       inline_images = dom_get_inline_images_data (document, extension, from_domain);
 
-               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);
-               value = dom_process_content_for_plain_text (document, extension);
+               if ((flags & E_CONTENT_EDITOR_GET_TEXT_HTML) &&
+                   !(flags & E_CONTENT_EDITOR_GET_PROCESSED)) {
+                       value = dom_process_content_for_draft (
+                               document, extension, (flags & E_CONTENT_EDITOR_GET_BODY));
+               } else if ((flags & E_CONTENT_EDITOR_GET_TEXT_HTML) &&
+                          (flags & E_CONTENT_EDITOR_GET_PROCESSED) &&
+                          !(flags & E_CONTENT_EDITOR_GET_BODY)) {
+                       value = dom_process_content_for_html (document, extension);
+               } else if ((flags & E_CONTENT_EDITOR_GET_TEXT_PLAIN) &&
+                          (flags & E_CONTENT_EDITOR_GET_PROCESSED) &&
+                          !(flags & E_CONTENT_EDITOR_GET_BODY)) {
+                       value = dom_process_content_for_plain_text (document, extension);
+               } else if ((flags & E_CONTENT_EDITOR_GET_TEXT_PLAIN) &&
+                          (flags & E_CONTENT_EDITOR_GET_BODY) &&
+                          !(flags & E_CONTENT_EDITOR_GET_PROCESSED)) {
+                       if (flags & E_CONTENT_EDITOR_GET_EXCLUDE_SIGNATURE)
+                               value = dom_get_raw_body_content_without_signature  (document);
+                       else
+                               value = dom_get_raw_body_content (document);
+               } else {
+                       g_warning ("Unsupported flags combination (%d) in (%s)", flags, G_STRFUNC);
+               }
 
+               /* If no inline images are requested we still have to return
+                * something even it won't be used at all. */
                g_dbus_method_invocation_return_value (
                        invocation,
                        g_variant_new (
-                               "(@s)",
-                               g_variant_new_take_string (
-                                       value ? value : g_strdup (""))));
+                               "(sv)",
+                               value ? value : "",
+                               inline_images ? inline_images : g_variant_new_int32 (0)));
+
+               g_free (value);
+
+               if ((flags & E_CONTENT_EDITOR_GET_INLINE_IMAGES) && from_domain && *from_domain && 
inline_images) {
+                       dom_restore_images (document, inline_images);
+                       g_object_unref (inline_images);
+               }
        } else if (g_strcmp0 (method_name, "DOMInsertHTML") == 0) {
                const gchar *html;
 
@@ -1985,20 +1976,6 @@ handle_method_call (GDBusConnection *connection,
                document = webkit_web_page_get_dom_document (web_page);
                dom_convert_content (document, extension, preferred_text);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMGetInlineImagesData") == 0) {
-               const gchar *uid_domain;
-               GVariant *images_data;
-
-               g_variant_get (parameters, "(t&s)", &page_id, &uid_domain);
-
-               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);
-               images_data = dom_get_inline_images_data (document, extension, uid_domain);
-               g_dbus_method_invocation_return_value (invocation, images_data);
        } else if (g_strcmp0 (method_name, "DOMAddNewInlineImageIntoList") == 0) {
                const gchar *cid_uri, *src, *filename;
 
@@ -2016,10 +1993,10 @@ handle_method_call (GDBusConnection *connection,
                dom_insert_base64_image (document, extension, filename, cid_uri, src);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMReplaceBase64ImageSrc") == 0) {
-               const gchar *selector, *base64_content, *filename, *uri;
+       } else if (g_strcmp0 (method_name, "DOMReplaceImageSrc") == 0) {
+               const gchar *selector, *uri;
 
-               g_variant_get (parameters, "(t&s&s)", &page_id, &selector, &base64_content, &filename, &uri);
+               g_variant_get (parameters, "(t&s&s)", &page_id, &selector, &uri);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2027,21 +2004,7 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               dom_replace_base64_image_src (document, selector, base64_content, filename, uri);
-
-               g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMReplaceBase64ImageSrc") == 0) {
-               const gchar *selector, *base64_content, *filename, *uri;
-
-               g_variant_get (parameters, "(t&s&s)", &page_id, &selector, &base64_content, &filename, &uri);
-
-               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);
-               dom_replace_base64_image_src (document, selector, base64_content, filename, uri);
+               dom_replace_image_src (document, extension, selector, uri);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMDragAndDropEnd") == 0) {
@@ -2097,10 +2060,32 @@ handle_method_call (GDBusConnection *connection,
                document = webkit_web_page_get_dom_document (web_page);
                dom_selection_indent (document, extension);
                g_dbus_method_invocation_return_value (invocation, NULL);
-       } else if (g_strcmp0 (method_name, "DOMSelectionInsertBase64Image") == 0) {
-               const gchar *base64_content, *filename, *uri;
+       } else if (g_strcmp0 (method_name, "DOMSelectionSave") == 0) {
+               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);
+               dom_selection_save (document);
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "DOMSelectionRestore") == 0) {
+               g_variant_get (parameters, "(t)", &page_id);
 
-               g_variant_get (parameters, "(t&s&s&s)", &page_id, &base64_content, &filename, &uri);
+               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);
+               dom_selection_restore (document);
+               g_dbus_method_invocation_return_value (invocation, NULL);
+       } else if (g_strcmp0 (method_name, "DOMSelectionInsertImage") == 0) {
+               const gchar *uri;
+
+               g_variant_get (parameters, "(t&s)", &page_id, &uri);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2108,7 +2093,7 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               dom_insert_base64_image (document, extension, filename, uri, base64_content);
+               dom_insert_image (document, extension, uri);
 
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionReplace") == 0) {
@@ -2125,9 +2110,9 @@ handle_method_call (GDBusConnection *connection,
                dom_selection_replace (document, extension, replacement);
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionSetAlignment") == 0) {
-               guint32 alignment;
+               EContentEditorAlignment alignment;
 
-               g_variant_get (parameters, "(tu)", &page_id, &alignment);
+               g_variant_get (parameters, "(ti)", &page_id, &alignment);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2136,6 +2121,7 @@ handle_method_call (GDBusConnection *connection,
 
                document = webkit_web_page_get_dom_document (web_page);
                dom_selection_set_alignment (document, extension, alignment);
+               extension->priv->alignment = alignment;
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionSetBold") == 0) {
                gboolean bold;
@@ -2151,9 +2137,9 @@ handle_method_call (GDBusConnection *connection,
                dom_selection_set_bold (document, extension, bold);
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionSetBlockFormat") == 0) {
-               guint32 block_format;
+               EContentEditorBlockFormat block_format;
 
-               g_variant_get (parameters, "(tu)", &page_id, &block_format);
+               g_variant_get (parameters, "(ti)", &page_id, &block_format);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2177,9 +2163,9 @@ handle_method_call (GDBusConnection *connection,
                dom_selection_set_font_color (document, extension, color);
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionSetFontSize") == 0) {
-               guint32 font_size;
+               EContentEditorFontSize font_size;
 
-               g_variant_get (parameters, "(tu)", &page_id, &font_size);
+               g_variant_get (parameters, "(ti)", &page_id, &font_size);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2344,11 +2330,21 @@ handle_method_call (GDBusConnection *connection,
                                g_variant_new_take_string (
                                        active_signature ? active_signature : g_strdup (""))));
        } else if (g_strcmp0 (method_name, "DOMInsertSignature") == 0) {
-               gboolean top_signature, start_bottom;
-               const gchar *signature_html;
+               gboolean is_html, set_signature_from_message;
+               gboolean check_if_signature_is_changed, ignore_next_signature_change;
+               const gchar *content, *signature_id;
+               gchar *new_signature_id = NULL;
 
                g_variant_get (
-                       parameters, "(t&sbb)", &page_id, &signature_html, &top_signature, &start_bottom);
+                       parameters,
+                       "(t&sb&sbbb)",
+                       &page_id,
+                       &content,
+                       &is_html,
+                       &signature_id,
+                       &set_signature_from_message,
+                       &check_if_signature_is_changed,
+                       &ignore_next_signature_change);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
                        invocation, web_extension, page_id);
@@ -2356,9 +2352,26 @@ handle_method_call (GDBusConnection *connection,
                        goto error;
 
                document = webkit_web_page_get_dom_document (web_page);
-               dom_insert_signature (document, extension, signature_html, top_signature, start_bottom);
+               new_signature_id = dom_insert_signature (
+                       document,
+                       extension,
+                       content,
+                       is_html,
+                       signature_id,
+                       &set_signature_from_message,
+                       &check_if_signature_is_changed,
+                       &ignore_next_signature_change);
 
-               g_dbus_method_invocation_return_value (invocation, NULL);
+               g_dbus_method_invocation_return_value (
+                       invocation,
+                       g_variant_new (
+                               "(sbbb)",
+                               new_signature_id ? new_signature_id : "",
+                               set_signature_from_message,
+                               check_if_signature_is_changed,
+                               ignore_next_signature_change));
+
+               g_free (new_signature_id);
        } else if (g_strcmp0 (method_name, "DOMSaveDragAndDropHistory") == 0) {
                g_variant_get (
                        parameters, "(t)", &page_id);
@@ -2404,46 +2417,8 @@ handle_method_call (GDBusConnection *connection,
                                "(@s)",
                                g_variant_new_take_string (
                                        value ? value : g_strdup (""))));
-       } else if (g_strcmp0 (method_name, "DOMGetRawBodyContentWithoutSignature") == 0) {
-               gchar *value;
-
-               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);
-               value = dom_get_raw_body_content_without_signature (document);
-
-               g_dbus_method_invocation_return_value (
-                       invocation,
-                       g_variant_new (
-                               "(@s)",
-                               g_variant_new_take_string (
-                                       value ? value : g_strdup (""))));
-       } else if (g_strcmp0 (method_name, "DOMGetRawBodyContent") == 0) {
-               gchar *value;
-
-               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);
-               value = dom_get_raw_body_content (document);
-
-               g_dbus_method_invocation_return_value (
-                       invocation,
-                       g_variant_new (
-                               "(@s)",
-                               g_variant_new_take_string (
-                                       value ? value : g_strdup (""))));
        } else if (g_strcmp0 (method_name, "DOMGetCaretPosition") == 0) {
-               gint32 value;
+               guint32 value;
 
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -2457,9 +2432,9 @@ handle_method_call (GDBusConnection *connection,
 
                g_dbus_method_invocation_return_value (
                        invocation,
-                       value ? g_variant_new_int32 (value) : NULL);
+                       value ? g_variant_new_uint32 (value) : NULL);
        } else if (g_strcmp0 (method_name, "DOMGetCaretOffset") == 0) {
-               gint32 value;
+               guint32 value;
 
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -2473,7 +2448,7 @@ handle_method_call (GDBusConnection *connection,
 
                g_dbus_method_invocation_return_value (
                        invocation,
-                       value ? g_variant_new_int32 (value) : NULL);
+                       value ? g_variant_new_uint32 (value) : NULL);
        } else if (g_strcmp0 (method_name, "DOMClearUndoRedoHistory") == 0) {
                g_variant_get (parameters, "(t)", &page_id);
 
@@ -2495,471 +2470,10 @@ handle_method_call (GDBusConnection *connection,
        g_warning ("Cannot obtain WebKitWebPage for '%ld'", page_id);
 }
 
-static GVariant *
-handle_get_property (GDBusConnection *connection,
-                     const gchar *sender,
-                     const gchar *object_path,
-                     const gchar *interface_name,
-                     const gchar *property_name,
-                     GError **error,
-                     gpointer user_data)
-{
-       EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
-       GVariant *variant;
-
-       if (camel_debug ("wex"))
-               printf ("%s - %s - %s\n", G_STRFUNC, sender, property_name);
-       if (g_strcmp0 (property_name, "ForceImageLoad") == 0)
-               variant = g_variant_new_boolean (extension->priv->force_image_load);
-       else if (g_strcmp0 (property_name, "InlineSpelling") == 0)
-               variant = g_variant_new_boolean (extension->priv->inline_spelling);
-       else if (g_strcmp0 (property_name, "MagicLinks") == 0)
-               variant = g_variant_new_boolean (extension->priv->magic_links);
-       else if (g_strcmp0 (property_name, "MagicSmileys") == 0)
-               variant = g_variant_new_boolean (extension->priv->magic_smileys);
-       else if (g_strcmp0 (property_name, "HTMLMode") == 0)
-               variant = g_variant_new_boolean (extension->priv->html_mode);
-       else if (g_strcmp0 (property_name, "IsEdittingMessage") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_editting_message);
-       else if (g_strcmp0 (property_name, "IsFromNewMessage") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_from_new_message);
-       else if (g_strcmp0 (property_name, "IsMessageFromEditAsNew") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_message_from_edit_as_new);
-       else if (g_strcmp0 (property_name, "IsMessageFromDraft") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_message_from_draft);
-       else if (g_strcmp0 (property_name, "IsMessageFromSelection") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_message_from_selection);
-       else if (g_strcmp0 (property_name, "IsPastingContentFromItself") == 0)
-               variant = g_variant_new_boolean (extension->priv->is_pasting_content_from_itself);
-       else if (g_strcmp0 (property_name, "Alignment") == 0)
-               variant = g_variant_new_uint32 (extension->priv->alignment);
-       else if (g_strcmp0 (property_name, "BackgroundColor") == 0)
-               variant = g_variant_new_string (extension->priv->background_color);
-       else if (g_strcmp0 (property_name, "BlockFormat") == 0)
-               variant = g_variant_new_uint32 (extension->priv->block_format);
-       else if (g_strcmp0 (property_name, "Bold") == 0)
-               variant = g_variant_new_boolean (extension->priv->bold);
-       else if (g_strcmp0 (property_name, "Changed") == 0)
-               variant = g_variant_new_boolean (extension->priv->changed);
-       else if (g_strcmp0 (property_name, "FontColor") == 0)
-               variant = g_variant_new_string (extension->priv->font_color);
-       else if (g_strcmp0 (property_name, "FontName") == 0)
-               variant = g_variant_new_string (extension->priv->font_name);
-       else if (g_strcmp0 (property_name, "FontSize") == 0)
-               variant = g_variant_new_uint32 (extension->priv->font_size);
-       else if (g_strcmp0 (property_name, "Indented") == 0)
-               variant = g_variant_new_boolean (extension->priv->indented);
-       else if (g_strcmp0 (property_name, "Italic") == 0)
-               variant = g_variant_new_boolean (extension->priv->italic);
-       else if (g_strcmp0 (property_name, "Monospaced") == 0)
-               variant = g_variant_new_boolean (extension->priv->monospaced);
-       else if (g_strcmp0 (property_name, "Strikethrough") == 0)
-               variant = g_variant_new_boolean (extension->priv->strikethrough);
-       else if (g_strcmp0 (property_name, "Subscript") == 0)
-               variant = g_variant_new_boolean (extension->priv->subscript);
-       else if (g_strcmp0 (property_name, "Superscript") == 0)
-               variant = g_variant_new_boolean (extension->priv->superscript);
-       else if (g_strcmp0 (property_name, "Superscript") == 0)
-               variant = g_variant_new_boolean (extension->priv->superscript);
-       else if (g_strcmp0 (property_name, "Underline") == 0)
-               variant = g_variant_new_boolean (extension->priv->underline);
-       else if (g_strcmp0 (property_name, "Text") == 0)
-               variant = g_variant_new_string (extension->priv->text);
-       else if (g_strcmp0 (property_name, "NodeUnderMouseClickFlags") == 0)
-               variant = g_variant_new_uint32 (extension->priv->node_under_mouse_click_flags);
-
-       return variant;
-}
-
-static gboolean
-handle_set_property (GDBusConnection *connection,
-                     const gchar *sender,
-                     const gchar *object_path,
-                     const gchar *interface_name,
-                     const gchar *property_name,
-                     GVariant *variant,
-                     GError **error,
-                     gpointer user_data)
-{
-       EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
-       GError *local_error = NULL;
-       GVariantBuilder *builder;
-
-       if (camel_debug ("wex"))
-               printf ("%s - %s - %s\n", G_STRFUNC, sender, property_name);
-       builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
-
-       if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->force_image_load)
-                       goto exit;
-
-               extension->priv->force_image_load = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "ForceImageLoad",
-                       g_variant_new_boolean (extension->priv->force_image_load));
-       } else if (g_strcmp0 (property_name, "IsMessageFromDraft") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_message_from_draft)
-                       goto exit;
-
-               extension->priv->is_message_from_draft = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsMessageFromDraft",
-                       g_variant_new_boolean (extension->priv->is_message_from_draft));
-       } else if (g_strcmp0 (property_name, "IsEdittingMessage") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_editting_message)
-                       goto exit;
-
-               extension->priv->is_editting_message = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsEdittingMessage",
-                       g_variant_new_boolean (extension->priv->is_editting_message));
-       } else if (g_strcmp0 (property_name, "IsMessageFromSelection") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_message_from_selection)
-                       goto exit;
-
-               extension->priv->is_message_from_selection = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsMessageFromSelection",
-                       g_variant_new_boolean (extension->priv->is_message_from_selection));
-       } else if (g_strcmp0 (property_name, "IsFromNewMessage") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_from_new_message)
-                       goto exit;
-
-               extension->priv->is_from_new_message = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsFromNewMessage",
-                       g_variant_new_boolean (extension->priv->is_from_new_message));
-       } else if (g_strcmp0 (property_name, "IsMessageFromEditAsNew") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_message_from_edit_as_new)
-                       goto exit;
-
-               extension->priv->is_message_from_edit_as_new = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsMessageFromEditAsNew",
-                       g_variant_new_boolean (extension->priv->is_message_from_edit_as_new));
-       } else if (g_strcmp0 (property_name, "IsPastingContentFromItself") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->is_pasting_content_from_itself)
-                       goto exit;
-
-               extension->priv->is_pasting_content_from_itself = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "IsPastingContentFromItself",
-                       g_variant_new_boolean (extension->priv->is_pasting_content_from_itself));
-       } else if (g_strcmp0 (property_name, "HTMLMode") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->html_mode)
-                       goto exit;
-
-               extension->priv->html_mode = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "HTMLMode",
-                       g_variant_new_boolean (extension->priv->html_mode));
-       } else if (g_strcmp0 (property_name, "MagicLinks") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->magic_links)
-                       goto exit;
-
-               extension->priv->magic_links = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "MagicLinks",
-                       g_variant_new_boolean (extension->priv->magic_links));
-       } else if (g_strcmp0 (property_name, "MagicSmileys") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->magic_smileys)
-                       goto exit;
-
-               extension->priv->magic_smileys = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "MagicSmileys",
-                       g_variant_new_boolean (extension->priv->magic_smileys));
-       } else if (g_strcmp0 (property_name, "InlineSpelling") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->inline_spelling)
-                       goto exit;
-
-               extension->priv->inline_spelling = value;
-               /*if (extension->priv->inline_spelling)
-                       dom_force_spell_check (document, extension);
-               else
-                       dom_turn_spell_check_off (document, extension);*/
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "InlineSpelling",
-                       g_variant_new_boolean (extension->priv->inline_spelling));
-       } else if (g_strcmp0 (property_name, "Alignment") == 0) {
-               gint32 value = g_variant_get_uint32 (variant);
-
-               if (value == extension->priv->alignment)
-                       goto exit;
-
-               extension->priv->alignment = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Alignment",
-                       g_variant_new_uint32 (extension->priv->alignment));
-       } else if (g_strcmp0 (property_name, "BackgroundColor") == 0) {
-               const gchar *value = g_variant_get_string (variant, NULL);
-
-               if (g_strcmp0 (value, extension->priv->background_color) != 0)
-                       goto exit;
-
-               g_free (extension->priv->background_color);
-               extension->priv->background_color = g_strdup (value);
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "BackgroundColor",
-                       g_variant_new_string (extension->priv->background_color));
-       } else if (g_strcmp0 (property_name, "BlockFormat") == 0) {
-               guint32 value = g_variant_get_uint32 (variant);
-
-               if (value == extension->priv->block_format)
-                       goto exit;
-
-               extension->priv->block_format = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "BlockFormat",
-                       g_variant_new_uint32 (extension->priv->block_format));
-       } else if (g_strcmp0 (property_name, "Bold") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->bold)
-                       goto exit;
-
-               extension->priv->bold = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Bold",
-                       g_variant_new_boolean (extension->priv->bold));
-       } else if (g_strcmp0 (property_name, "Changed") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->changed)
-                       goto exit;
-
-               extension->priv->changed = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Changed",
-                       g_variant_new_boolean (extension->priv->changed));
-       } else if (g_strcmp0 (property_name, "FontColor") == 0) {
-               const gchar *value = g_variant_get_string (variant, NULL);
-
-               if (g_strcmp0 (value, extension->priv->font_color) == 0)
-                       goto exit;
-
-               g_free (extension->priv->font_color);
-               extension->priv->font_color = g_strdup (value);
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "FontColor",
-                       g_variant_new_string (extension->priv->font_color));
-       } else if (g_strcmp0 (property_name, "FontName") == 0) {
-               const gchar *value = g_variant_get_string (variant, NULL);
-
-               if (g_strcmp0 (value, extension->priv->font_name) == 0)
-                       goto exit;
-
-               g_free (extension->priv->font_name);
-               extension->priv->font_name = g_strdup (value);
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "FontName",
-                       g_variant_new_string (extension->priv->font_name));
-       } else if (g_strcmp0 (property_name, "FontSize") == 0) {
-               gint32 value = g_variant_get_uint32 (variant);
-
-               if (value == extension->priv->font_size)
-                       goto exit;
-
-               extension->priv->font_size = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "FontSize",
-                       g_variant_new_uint32 (extension->priv->font_size));
-       } else if (g_strcmp0 (property_name, "Indented") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->indented)
-                       goto exit;
-
-               extension->priv->indented = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Indented",
-                       g_variant_new_boolean (extension->priv->indented));
-       } else if (g_strcmp0 (property_name, "Italic") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->italic)
-                       goto exit;
-
-               extension->priv->italic = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Italic",
-                       g_variant_new_boolean (extension->priv->italic));
-       } else if (g_strcmp0 (property_name, "Monospaced") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->monospaced)
-                       goto exit;
-
-               extension->priv->monospaced = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Monospaced",
-                       g_variant_new_boolean (extension->priv->monospaced));
-       } else if (g_strcmp0 (property_name, "Strikethrough") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->strikethrough)
-                       goto exit;
-
-               extension->priv->strikethrough = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Strikethrough",
-                       g_variant_new_boolean (extension->priv->strikethrough));
-       } else if (g_strcmp0 (property_name, "Subscript") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->subscript)
-                       goto exit;
-
-               extension->priv->subscript = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Subscript",
-                       g_variant_new_boolean (extension->priv->subscript));
-       } else if (g_strcmp0 (property_name, "Superscript") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->superscript)
-                       goto exit;
-
-               extension->priv->superscript = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Superscript",
-                       g_variant_new_boolean (extension->priv->superscript));
-       } else if (g_strcmp0 (property_name, "Underline") == 0) {
-               gboolean value = g_variant_get_boolean (variant);
-
-               if (value == extension->priv->underline)
-                       goto exit;
-
-               extension->priv->underline = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Underline",
-                       g_variant_new_boolean (extension->priv->underline));
-       } else if (g_strcmp0 (property_name, "Text") == 0) {
-               const gchar *value = g_variant_get_string (variant, NULL);
-
-               if (g_strcmp0 (value, extension->priv->text) == 0)
-                       goto exit;
-
-               g_free (extension->priv->text);
-               extension->priv->text = g_strdup (value);
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "Text",
-                       g_variant_new_string (extension->priv->text));
-       } else if (g_strcmp0 (property_name, "NodeUnderMouseClickFlags") == 0) {
-               guint32 value = g_variant_get_uint32 (variant);
-
-               extension->priv->node_under_mouse_click_flags = value;
-
-               g_variant_builder_add (builder,
-                       "{sv}",
-                       "NodeUnderMouseClickFlags",
-                       g_variant_new_uint32 (extension->priv->node_under_mouse_click_flags));
-       } else {
-               g_warning ("UNKNOWN PROPERY '%s'", property_name);
-       }
-
-       g_dbus_connection_emit_signal (connection,
-               NULL,
-               object_path,
-               "org.freedesktop.DBus.Properties",
-               "PropertiesChanged",
-               g_variant_new (
-                       "(sa{sv}as)",
-                       interface_name,
-                       builder,
-                       NULL),
-               &local_error);
-
-       g_assert_no_error (local_error);
-
- exit:
-       if (camel_debug ("wex"))
-               printf ("\tExitting\n");
-       g_variant_builder_unref (builder);
-
-       return TRUE;
-}
-
 static const GDBusInterfaceVTable interface_vtable = {
        handle_method_call,
-       handle_get_property,
-       handle_set_property
+       NULL,
+       NULL
 };
 
 static void
@@ -3005,6 +2519,12 @@ e_html_editor_web_extension_dispose (GObject *object)
                extension->priv->undo_redo_manager = NULL;
        }
 
+       if (extension->priv->mail_settings != NULL) {
+               g_signal_handlers_disconnect_by_data (extension->priv->mail_settings, object);
+               g_object_unref (extension->priv->mail_settings);
+               extension->priv->mail_settings = NULL;
+       }
+
        g_clear_object (&extension->priv->wk_extension);
        g_clear_object (&extension->priv->spell_checker);
 
@@ -3038,14 +2558,16 @@ e_html_editor_web_extension_class_init (EHTMLEditorWebExtensionClass *class)
 static void
 e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
 {
-       extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, E_TYPE_HTML_EDITOR_WEB_EXTENSION, 
EHTMLEditorWebExtensionPrivate);
+       GSettings *g_settings;
+
+       extension->priv = E_HTML_EDITOR_WEB_EXTENSION_GET_PRIVATE (extension);
 
        extension->priv->bold = FALSE;
        extension->priv->background_color = g_strdup ("");
        extension->priv->font_color = g_strdup ("");
        extension->priv->font_name = g_strdup ("");
        extension->priv->text = g_strdup ("");
-       extension->priv->font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+       extension->priv->font_size = E_CONTENT_EDITOR_FONT_SIZE_NORMAL;
        extension->priv->indented = FALSE;
        extension->priv->italic = FALSE;
        extension->priv->monospaced = FALSE;
@@ -3053,36 +2575,31 @@ e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
        extension->priv->subscript = FALSE;
        extension->priv->superscript = FALSE;
        extension->priv->underline = FALSE;
-       extension->priv->alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
-       extension->priv->block_format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
-       extension->priv->changed = FALSE;
+       extension->priv->alignment = E_CONTENT_EDITOR_ALIGNMENT_LEFT;
+       extension->priv->block_format = E_CONTENT_EDITOR_BLOCK_FORMAT_PARAGRAPH;
        extension->priv->force_image_load = FALSE;
-       extension->priv->inline_spelling = FALSE;
-       extension->priv->magic_links = FALSE;
-       extension->priv->magic_smileys = FALSE;
-       extension->priv->unicode_smileys = FALSE;
        extension->priv->html_mode = FALSE;
        extension->priv->return_key_pressed = FALSE;
        extension->priv->space_key_pressed = FALSE;
        extension->priv->smiley_written = FALSE;
-       extension->priv->word_wrap_length = 71;
 
        extension->priv->convert_in_situ = FALSE;
        extension->priv->body_input_event_removed = TRUE;
-       extension->priv->is_editting_message = TRUE;
-       extension->priv->is_message_from_draft = FALSE;
-       extension->priv->is_message_from_edit_as_new = FALSE;
-       extension->priv->is_from_new_message = FALSE;
-       extension->priv->is_message_from_selection = FALSE;
        extension->priv->dont_save_history_in_body_input = FALSE;
        extension->priv->is_pasting_content_from_itself = FALSE;
        extension->priv->composition_in_progress = FALSE;
        extension->priv->renew_history_after_coordinates = TRUE;
 
-       extension->priv->node_under_mouse_click = NULL;
+       extension->priv->content_flags = 0;
 
        extension->priv->spell_check_on_scroll_event_source_id = 0;
 
+       g_settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       extension->priv->mail_settings = g_settings;
+
+       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,
@@ -3141,14 +2658,11 @@ image_exists_in_cache (const gchar *image_uri)
 }
 
 static EImageLoadingPolicy
-get_image_loading_policy (void)
+get_image_loading_policy (EHTMLEditorWebExtension *extension)
 {
-       GSettings *settings;
        EImageLoadingPolicy image_policy;
 
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       image_policy = g_settings_get_enum (settings, "image-loading-policy");
-       g_object_unref (settings);
+       image_policy = g_settings_get_enum (extension->priv->mail_settings, "image-loading-policy");
 
        return image_policy;
 }
@@ -3172,7 +2686,7 @@ redirect_http_uri (EHTMLEditorWebExtension *extension,
        /* If the URI is not cached and we are not allowed to load it
         * then redirect to invalid URI, so that webkit would display
         * a native placeholder for it. */
-       image_policy = get_image_loading_policy ();
+       image_policy = get_image_loading_policy (extension);
        if (!image_exists && !extension->priv->force_image_load &&
            (image_policy == E_IMAGE_LOADING_POLICY_NEVER)) {
                webkit_uri_request_set_uri (request, "about:blank");
@@ -3242,46 +2756,80 @@ web_page_context_menu_cb (WebKitWebPage *web_page,
                           EHTMLEditorWebExtension *web_extension)
 {
        WebKitDOMNode *node;
-       guint flags = 0;
+       EContentEditorNodeFlags flags = 0;
+       GVariant *variant;
 
        node = webkit_web_hit_test_result_get_node (hit_test_result);
        web_extension->priv->node_under_mouse_click = node;
 
        if (WEBKIT_DOM_IS_HTML_HR_ELEMENT (node))
-               flags |= E_HTML_EDITOR_NODE_IS_HR;
+               flags |= E_CONTENT_EDITOR_NODE_IS_H_RULE;
 
        if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
            (dom_node_find_parent_element (node, "A") != NULL))
-               flags |= E_HTML_EDITOR_NODE_IS_ANCHOR;
+               flags |= E_CONTENT_EDITOR_NODE_IS_ANCHOR;
 
        if (WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node) ||
-           (dom_node_find_parent_element (node, "IMG") != NULL)) {
-
-               flags |= E_HTML_EDITOR_NODE_IS_IMAGE;
-       }
+           (dom_node_find_parent_element (node, "IMG") != NULL))
+               flags |= E_CONTENT_EDITOR_NODE_IS_IMAGE;
 
        if (WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (node) ||
            (dom_node_find_parent_element (node, "TD") != NULL) ||
-           (dom_node_find_parent_element (node, "TH") != NULL)) {
-
-               flags |= E_HTML_EDITOR_NODE_IS_TABLE_CELL;
-       }
+           (dom_node_find_parent_element (node, "TH") != NULL))
+               flags |= E_CONTENT_EDITOR_NODE_IS_TABLE_CELL;
 
-       if (flags && E_HTML_EDITOR_NODE_IS_TABLE_CELL &&
+       if (flags & E_CONTENT_EDITOR_NODE_IS_TABLE_CELL &&
            (WEBKIT_DOM_IS_HTML_TABLE_ELEMENT (node) ||
-           dom_node_find_parent_element (node, "TABLE") != NULL)) {
-
-               flags |= E_HTML_EDITOR_NODE_IS_TABLE;
-       }
+           dom_node_find_parent_element (node, "TABLE") != NULL))
+               flags |= E_CONTENT_EDITOR_NODE_IS_TABLE;
 
        if (flags == 0)
-               flags |= E_HTML_EDITOR_NODE_IS_TEXT;
+               flags |= E_CONTENT_EDITOR_NODE_IS_TEXT;
 
-       set_dbus_property_unsigned (web_extension, "NodeUnderMouseClickFlags", flags);
+       variant = g_variant_new_int32 (flags);
+       webkit_context_menu_set_user_data (context_menu, variant);
 
        return FALSE;
 }
 
+static GVariant *
+create_parameters_and_update_font_properties (WebKitDOMDocument *document,
+                                              EHTMLEditorWebExtension *extension)
+{
+       extension->priv->alignment = dom_selection_get_alignment (document, extension);
+       extension->priv->block_format = dom_selection_get_block_format (document, extension);
+       extension->priv->indented = dom_selection_is_indented (document);
+
+       if (extension->priv->html_mode) {
+               extension->priv->bold = dom_selection_is_bold (document, extension);
+               extension->priv->italic = dom_selection_is_italic (document, extension);
+               extension->priv->underline = dom_selection_is_underline (document, extension);
+               extension->priv->strikethrough = dom_selection_is_strikethrough (document, extension);
+               extension->priv->monospaced = dom_selection_is_monospaced (document, extension);
+               extension->priv->subscript = dom_selection_is_subscript (document, extension);
+               extension->priv->superscript = dom_selection_is_superscript (document, extension);
+               extension->priv->underline = dom_selection_is_underline (document, extension);
+               extension->priv->font_size = dom_selection_get_font_size (document, extension);
+               g_free (extension->priv->font_color);
+               extension->priv->font_color = dom_selection_get_font_color (document, extension);
+       }
+
+       return g_variant_new ("(iibbbbbbbbbis)",
+               (gint32) extension->priv->alignment,
+               (gint32) extension->priv->block_format,
+               extension->priv->indented,
+               extension->priv->bold,
+               extension->priv->italic,
+               extension->priv->underline,
+               extension->priv->strikethrough,
+               extension->priv->monospaced,
+               extension->priv->subscript,
+               extension->priv->superscript,
+               extension->priv->underline,
+               (gint32) extension->priv->font_size,
+               extension->priv->font_color ? extension->priv->font_color : "");
+}
+
 static void
 web_editor_selection_changed_cb (WebKitWebEditor *editor,
                                  EHTMLEditorWebExtension *extension)
@@ -3289,6 +2837,14 @@ web_editor_selection_changed_cb (WebKitWebEditor *editor,
        WebKitWebPage *page;
        WebKitDOMDocument *document;
        WebKitDOMRange *range;
+       GError *error = NULL;
+       GVariant *parameters;
+
+       if (extension->priv->selection_changed_callbacks_blocked)
+               return;
+
+       if (!extension->priv->dbus_connection)
+               return;
 
        page = webkit_web_editor_get_page (editor);
        document = webkit_web_page_get_dom_document (page);
@@ -3297,28 +2853,25 @@ web_editor_selection_changed_cb (WebKitWebEditor *editor,
                return;
        g_object_unref (range);
 
-       set_dbus_property_unsigned (extension, "Alignment", dom_selection_get_alignment (document, 
extension));
-       set_dbus_property_unsigned (extension, "BlockFormat", dom_selection_get_block_format (document, 
extension));
-       set_dbus_property_boolean (extension, "Indented", dom_selection_is_indented (document));
        /*
-       g_object_notify (G_OBJECT (selection), "text");
-*/
-       if (!extension->priv->html_mode)
-               return;
-
-       set_dbus_property_boolean (extension, "Bold", dom_selection_is_bold (document, extension));
-       set_dbus_property_boolean (extension, "Italic", dom_selection_is_italic (document, extension));
-       set_dbus_property_boolean (extension, "Underline", dom_selection_is_underline (document, extension));
-       set_dbus_property_boolean (extension, "Strikethrough", dom_selection_is_strikethrough (document, 
extension));
-       set_dbus_property_boolean (extension, "Monospaced", dom_selection_is_monospaced (document, 
extension));
-       set_dbus_property_boolean (extension, "Subscript", dom_selection_is_subscript (document, extension));
-       set_dbus_property_boolean (extension, "Superscript", dom_selection_is_superscript (document, 
extension));
-       set_dbus_property_unsigned (extension, "FontSize", dom_selection_get_font_size (document, extension));
-       set_dbus_property_take_string (extension, "FontColor", dom_selection_get_font_color (document, 
extension));
-/*
        g_object_notify (G_OBJECT (selection), "background-color");
        g_object_notify (G_OBJECT (selection), "font-name");
        */
+       parameters = create_parameters_and_update_font_properties (document, extension);
+
+       g_dbus_connection_emit_signal (
+               extension->priv->dbus_connection,
+               NULL,
+               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+               "SelectionChanged",
+               parameters,
+               &error);
+
+       if (error) {
+               g_warning ("Error emitting signal SelectionChanged: %s\n", error->message);
+               g_error_free (error);
+       }
 }
 
 static void
@@ -3408,115 +2961,28 @@ e_html_editor_web_extension_dbus_register (EHTMLEditorWebExtension *extension,
 }
 
 void
-set_dbus_property_string (EHTMLEditorWebExtension *extension,
-                          const gchar *name,
-                          const gchar *value)
+e_html_editor_web_extension_set_content_changed (EHTMLEditorWebExtension *extension)
 {
-       if (extension->priv->dbus_connection) {
-               g_dbus_connection_call (
-                       extension->priv->dbus_connection,
-                       E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
-                       E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
-                       "org.freedesktop.DBus.Properties",
-                       "Set",
-                       g_variant_new (
-                               "(ssv)",
-                               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
-                               name,
-                               g_variant_new_string (value)),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
-       }
-}
+       GError *error = NULL;
 
-void
-set_dbus_property_take_string (EHTMLEditorWebExtension *extension,
-                               const gchar *name,
-                               gchar *value)
-{
-       if (extension->priv->dbus_connection) {
-               g_dbus_connection_call (
-                       extension->priv->dbus_connection,
-                       E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
-                       E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
-                       "org.freedesktop.DBus.Properties",
-                       "Set",
-                       g_variant_new (
-                               "(ssv)",
-                               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
-                               name,
-                               g_variant_new_take_string (value)),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
-       }
-}
+       if (!extension->priv->dbus_connection)
+               return;
 
-void
-set_dbus_property_unsigned (EHTMLEditorWebExtension *extension,
-                            const gchar *name,
-                            guint32 value)
-{
-       if (extension->priv->dbus_connection) {
-               g_dbus_connection_call (
-                       extension->priv->dbus_connection,
-                       E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
-                       E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
-                       "org.freedesktop.DBus.Properties",
-                       "Set",
-                       g_variant_new (
-                               "(ssv)",
-                               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
-                               name,
-                               g_variant_new_uint32 (value)),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
-       }
-}
+       g_dbus_connection_emit_signal (
+               extension->priv->dbus_connection,
+               NULL,
+               E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+               "ContentChanged",
+               NULL,
+               &error);
 
-void
-set_dbus_property_boolean (EHTMLEditorWebExtension *extension,
-                           const gchar *name,
-                           gboolean value)
-{
-       if (extension->priv->dbus_connection) {
-               g_dbus_connection_call (
-                       extension->priv->dbus_connection,
-                       E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
-                       E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
-                       "org.freedesktop.DBus.Properties",
-                       "Set",
-                       g_variant_new (
-                               "(ssv)",
-                               E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
-                               name,
-                               g_variant_new_boolean (value)),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL,
-                       NULL);
+       if (error) {
+               g_warning ("Error emitting signal ContentChanged: %s\n", error->message);
+               g_error_free (error);
        }
 }
 
-void
-e_html_editor_web_extension_set_content_changed (EHTMLEditorWebExtension *extension)
-{
-       set_dbus_property_boolean (extension, "Changed", TRUE);
-}
-
 gboolean
 e_html_editor_web_extension_get_html_mode (EHTMLEditorWebExtension *extension)
 {
@@ -3583,22 +3049,16 @@ e_html_editor_web_extension_get_font_color (EHTMLEditorWebExtension *extension)
        return extension->priv->font_color;
 }
 
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
 e_html_editor_web_extension_get_alignment (EHTMLEditorWebExtension *extension)
 {
        return extension->priv->alignment;
 }
 
-gboolean
-e_html_editor_web_extension_is_message_from_edit_as_new (EHTMLEditorWebExtension *extension)
+EContentEditorContentFlags
+e_html_editor_web_extension_get_current_content_flags (EHTMLEditorWebExtension *extension)
 {
-       return extension->priv->is_message_from_edit_as_new;
-}
-
-gboolean
-e_html_editor_web_extension_is_editting_message (EHTMLEditorWebExtension *extension)
-{
-       return extension->priv->is_editting_message;
+       return extension->priv->content_flags;
 }
 
 gboolean
@@ -3630,37 +3090,29 @@ e_html_editor_web_extension_set_space_key_pressed (EHTMLEditorWebExtension *exte
 gboolean
 e_html_editor_web_extension_get_magic_links_enabled (EHTMLEditorWebExtension *extension)
 {
-       return extension->priv->magic_links;
+       return g_settings_get_boolean (
+               extension->priv->mail_settings, "composer-magic-links");
 }
 
 gboolean
 e_html_editor_web_extension_get_magic_smileys_enabled (EHTMLEditorWebExtension *extension)
 {
-       return extension->priv->magic_smileys;
+       return g_settings_get_boolean (
+               extension->priv->mail_settings, "composer-magic-smileys");
 }
 
 gboolean
 e_html_editor_web_extension_get_unicode_smileys_enabled (EHTMLEditorWebExtension *extension)
 {
-       return extension->priv->unicode_smileys;
-}
-
-void
-e_html_editor_web_extension_set_inline_spelling (EHTMLEditorWebExtension *extension,
-                                                 gboolean value)
-{
-       g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
-
-       if (extension->priv->inline_spelling == value)
-               return;
-
-       extension->priv->inline_spelling = value;
+       return g_settings_get_boolean (
+               extension->priv->mail_settings, "composer-unicode-smileys");
 }
 
 gboolean
 e_html_editor_web_extension_get_inline_spelling_enabled (EHTMLEditorWebExtension *extension)
 {
-       return extension->priv->inline_spelling;
+       return g_settings_get_boolean (
+               extension->priv->mail_settings, "composer-inline-spelling");
 }
 
 gboolean
@@ -3719,18 +3171,6 @@ e_html_editor_web_extension_add_new_inline_image_into_list (EHTMLEditorWebExtens
 }
 
 gboolean
-e_html_editor_web_extension_is_message_from_draft (EHTMLEditorWebExtension *extension)
-{
-       return extension->priv->is_message_from_draft;
-}
-
-gboolean
-e_html_editor_web_extension_is_from_new_message (EHTMLEditorWebExtension *extension)
-{
-       return extension->priv->is_from_new_message;
-}
-
-gboolean
 e_html_editor_web_extension_get_is_smiley_written (EHTMLEditorWebExtension *extension)
 {
        return extension->priv->smiley_written;
@@ -3813,22 +3253,13 @@ e_html_editor_web_extension_set_spell_check_on_scroll_event_source_id (EHTMLEdit
 void
 e_html_editor_web_extension_block_selection_changed_callback (EHTMLEditorWebExtension *extension)
 {
-       if (!extension->priv->selection_changed_callbacks_blocked) {
-               /* FIXME WK2 - the handler is added on WebKitWebEditor, not extension */
-               g_signal_handlers_block_by_func (extension, web_editor_selection_changed_cb, NULL);
+       if (!extension->priv->selection_changed_callbacks_blocked)
                extension->priv->selection_changed_callbacks_blocked = TRUE;
-       }
 }
 
 void
 e_html_editor_web_extension_unblock_selection_changed_callback (EHTMLEditorWebExtension *extension)
 {
-       if (extension->priv->selection_changed_callbacks_blocked) {
-               /* FIXME WK2 - the handler is added on WebKitWebEditor, not extension */
-               g_signal_handlers_unblock_by_func (extension, web_editor_selection_changed_cb, NULL);
+       if (extension->priv->selection_changed_callbacks_blocked)
                extension->priv->selection_changed_callbacks_blocked = FALSE;
-
-               /* FIXME WK2 - missing page-ID, to get to the WebKitWebEditor instance */
-               /*web_editor_selection_changed_cb (editor, extension);*/
-       }
 }
diff --git a/web-extensions/composer/e-html-editor-web-extension.h 
b/web-extensions/composer/e-html-editor-web-extension.h
index 31fbac1..fc65c08 100644
--- a/web-extensions/composer/e-html-editor-web-extension.h
+++ b/web-extensions/composer/e-html-editor-web-extension.h
@@ -79,7 +79,7 @@ void          e_html_editor_web_extension_initialize
 void           e_html_editor_web_extension_dbus_register
                                                (EHTMLEditorWebExtension *extension,
                                                 GDBusConnection *connection);
-
+/*
 void           set_dbus_property_string        (EHTMLEditorWebExtension *extension,
                                                 const gchar *name,
                                                 const gchar *value);
@@ -95,7 +95,7 @@ void          set_dbus_property_unsigned      (EHTMLEditorWebExtension *extension,
 void           set_dbus_property_boolean       (EHTMLEditorWebExtension *extension,
                                                 const gchar *name,
                                                 gboolean value);
-
+*/
 void           e_html_editor_web_extension_set_content_changed
                                                (EHTMLEditorWebExtension *extension);
 
@@ -133,14 +133,12 @@ guint             e_html_editor_web_extension_get_font_size
 const gchar *  e_html_editor_web_extension_get_font_color
                                                (EHTMLEditorWebExtension *extension);
 
-EHTMLEditorSelectionAlignment
+EContentEditorAlignment
                e_html_editor_web_extension_get_alignment
                                                (EHTMLEditorWebExtension *extension);
 
-gboolean       e_html_editor_web_extension_is_message_from_edit_as_new
-                                               (EHTMLEditorWebExtension *extension);
-
-gboolean       e_html_editor_web_extension_is_editting_message
+EContentEditorContentFlags
+               e_html_editor_web_extension_get_current_content_flags
                                                (EHTMLEditorWebExtension *extension);
 
 gboolean       e_html_editor_web_extension_get_return_key_pressed
@@ -166,12 +164,9 @@ gboolean   e_html_editor_web_extension_get_magic_smileys_enabled
 gboolean       e_html_editor_web_extension_get_unicode_smileys_enabled
                                                (EHTMLEditorWebExtension *extension);
 
-void           e_html_editor_web_extension_set_inline_spelling
-                                               (EHTMLEditorWebExtension *extension,
-                                                 gboolean value);
-
 gboolean       e_html_editor_web_extension_get_inline_spelling_enabled
                                                (EHTMLEditorWebExtension *extension);
+
 gboolean       e_html_editor_web_extension_check_word_spelling
                                                (EHTMLEditorWebExtension *extension,
                                                 const gchar *word,
@@ -199,12 +194,6 @@ void               e_html_editor_web_extension_add_new_inline_image_into_list
                                                 const gchar *cid_src,
                                                 const gchar *src);
 
-gboolean       e_html_editor_web_extension_is_message_from_draft
-                                               (EHTMLEditorWebExtension *extension);
-
-gboolean       e_html_editor_web_extension_is_from_new_message
-                                               (EHTMLEditorWebExtension *extension);
-
 gboolean       e_html_editor_web_extension_get_is_smiley_written
                                                (EHTMLEditorWebExtension *extension);
 
@@ -218,10 +207,13 @@ gboolean  e_html_editor_web_extension_get_dont_save_history_in_body_input
 void           e_html_editor_web_extension_set_dont_save_history_in_body_input
                                                (EHTMLEditorWebExtension *extension,
                                                 gboolean value);
+
 gboolean       e_html_editor_web_extension_is_pasting_content_from_itself
                                                (EHTMLEditorWebExtension *extension);
+
 gboolean       e_html_editor_web_extension_get_renew_history_after_coordinates
                                                (EHTMLEditorWebExtension *extension);
+
 void           e_html_editor_web_extension_set_renew_history_after_coordinates
                                                (EHTMLEditorWebExtension *extension,
                                                 gboolean renew_history_after_coordinates);
diff --git a/web-extensions/composer/e-msg-composer-dom-functions.c 
b/web-extensions/composer/e-msg-composer-dom-functions.c
index 7751c95..83c902f 100644
--- a/web-extensions/composer/e-msg-composer-dom-functions.c
+++ b/web-extensions/composer/e-msg-composer-dom-functions.c
@@ -28,30 +28,10 @@ gchar *
 dom_get_active_signature_uid (WebKitDOMDocument *document)
 {
        gchar *uid = NULL;
-       gulong ii, length;
-       WebKitDOMHTMLCollection *nodes;
-
-       nodes = webkit_dom_document_get_elements_by_class_name_as_html_collection (
-               document, "-x-evo-signature");
-       length = webkit_dom_html_collection_get_length (nodes);
-       for (ii = 0; ii < length; ii++) {
-               WebKitDOMNode *node;
-               gchar *id;
-
-               node = webkit_dom_html_collection_item (nodes, ii);
-               id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (node));
-               if (id && (strlen (id) == 1) && (*id == '1')) {
-                       uid = webkit_dom_element_get_attribute (
-                               WEBKIT_DOM_ELEMENT (node), "name");
-                       g_free (id);
-                       g_object_unref (node);
-                       break;
-               }
-               g_free (id);
-               g_object_unref (node);
-       }
+       WebKitDOMElement *element;
 
-       g_object_unref (nodes);
+       if ((element = webkit_dom_document_query_selector (document, ".-x-evo-signature[id]", NULL)))
+               uid = webkit_dom_element_get_id (element);
 
        return uid;
 }
diff --git a/web-extensions/e-dom-utils.c b/web-extensions/e-dom-utils.c
index 70e4bc5..5fc4d03 100644
--- a/web-extensions/e-dom-utils.c
+++ b/web-extensions/e-dom-utils.c
@@ -1594,6 +1594,22 @@ element_remove_class (WebKitDOMElement *element,
 }
 
 void
+element_rename_attribute (WebKitDOMElement *element,
+                      const gchar *from,
+                      const gchar *to)
+{
+       gchar *value;
+
+       if (!webkit_dom_element_has_attribute (element, from))
+               return;
+
+       value = webkit_dom_element_get_attribute (element, from);
+       webkit_dom_element_set_attribute (element, to, (value && *value) ? value : "", NULL);
+       webkit_dom_element_remove_attribute (element, from);
+       g_free (value);
+}
+
+void
 remove_node (WebKitDOMNode *node)
 {
        WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
@@ -1796,13 +1812,13 @@ node_is_list (WebKitDOMNode *node)
  *
  * Returns block format of given list.
  *
- * Returns: #EHTMLEditorSelectionBlockFormat
+ * Returns: #EContentEditorBlockFormat
  */
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
 dom_get_list_format_from_node (WebKitDOMNode *node)
 {
-       EHTMLEditorSelectionBlockFormat format =
-               E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
+       EContentEditorBlockFormat format =
+               E_CONTENT_EDITOR_BLOCK_FORMAT_UNORDERED_LIST;
 
        if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (node))
                return -1;
@@ -1815,14 +1831,14 @@ dom_get_list_format_from_node (WebKitDOMNode *node)
                        WEBKIT_DOM_ELEMENT (node), "type");
 
                if (!type_value)
-                       return E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
+                       return E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST;
 
                if (!*type_value)
-                       format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
+                       format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST;
                else if (g_ascii_strcasecmp (type_value, "A") == 0)
-                       format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA;
+                       format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ALPHA;
                else if (g_ascii_strcasecmp (type_value, "I") == 0)
-                       format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN;
+                       format = E_CONTENT_EDITOR_BLOCK_FORMAT_ORDERED_LIST_ROMAN;
                g_free (type_value);
 
                return format;
@@ -1858,7 +1874,7 @@ merge_list_into_list (WebKitDOMNode *from,
 void
 merge_lists_if_possible (WebKitDOMNode *list)
 {
-       EHTMLEditorSelectionBlockFormat format, prev, next;
+       EContentEditorBlockFormat format, prev, next;
        gint ii, length;
        WebKitDOMNode *prev_sibling, *next_sibling;
        WebKitDOMNodeList *lists;
diff --git a/web-extensions/e-dom-utils.h b/web-extensions/e-dom-utils.h
index f25f603..218e323 100644
--- a/web-extensions/e-dom-utils.h
+++ b/web-extensions/e-dom-utils.h
@@ -124,6 +124,9 @@ void                element_add_class               (WebKitDOMElement *element,
                                                 const gchar* class);
 void           element_remove_class            (WebKitDOMElement *element,
                                                 const gchar* class);
+void           element_rename_attribute        (WebKitDOMElement *element,
+                                                const gchar *from,
+                                                const gchar *to);
 void           remove_node                     (WebKitDOMNode *node);
 void           remove_node_if_empty            (WebKitDOMNode *node);
 WebKitDOMNode *        split_list_into_two             (WebKitDOMNode *item,
@@ -151,7 +154,7 @@ gboolean    node_is_list                    (WebKitDOMNode *node);
 
 gboolean       node_is_list_or_item            (WebKitDOMNode *node);
 
-EHTMLEditorSelectionBlockFormat
+EContentEditorBlockFormat
                dom_get_list_format_from_node   (WebKitDOMNode *node);
 
 void           merge_list_into_list            (WebKitDOMNode *from,



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