[evolution/wip/mcrha/webkit-jsc-api: 236/292] Be able to flip between format modes



commit f6352aded20e6509213f61779abc4affa7e91d8e
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 12 18:59:46 2019 +0100

    Be able to flip between format modes
    
    Without conversion from HTML to Plain for now.

 data/webkit/e-editor.js                     | 53 ++++++++++++++++++++--
 data/webkit/e-undo-redo.js                  | 12 +++--
 src/e-util/e-html-editor-actions.c          | 29 ++++++++----
 src/modules/webkit-editor/e-webkit-editor.c | 69 ++++++++++++-----------------
 4 files changed, 107 insertions(+), 56 deletions(-)
---
diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js
index 6625a9fe2f..6e3ee6edff 100644
--- a/data/webkit/e-editor.js
+++ b/data/webkit/e-editor.js
@@ -47,16 +47,20 @@ var EvoEditor = {
        CLAIM_CONTENT_FLAG_USE_PARENT_BLOCK_NODE : 1 << 0,
        CLAIM_CONTENT_FLAG_SAVE_HTML : 1 << 1,
 
-       TEXT_INDENT_SIZE : 3, /* in characters */
+       TEXT_INDENT_SIZE : 3, // in characters
 
        FORCE_NO : 0,
        FORCE_YES : 1,
        FORCE_MAYBE : 2,
 
-       htmlFormat : false,
+       MODE_PLAIN_TEXT : 0,
+       MODE_HTML : 1,
+
+       mode : 1, // one of the MODE constants
        storedSelection : null,
        forceFormatStateUpdate : false,
        formattingState : {
+               mode : -1,
                baseElement : null, // to avoid often notifications when just moving within the same node
                bold : false,
                italic : false,
@@ -105,7 +109,7 @@ EvoEditor.maybeUpdateFormattingState = function(force)
        if (baseElem && baseElem.nodeType == baseElem.TEXT_NODE)
                baseElem = baseElem.parentElement;
 
-       if (force == EvoEditor.FORCE_NO && EvoEditor.formattingState.baseElement === baseElem) {
+       if (force == EvoEditor.FORCE_NO && EvoEditor.formattingState.baseElement === baseElem && 
EvoEditor.mode == EvoEditor.formattingState.mode) {
                return;
        }
 
@@ -115,6 +119,13 @@ EvoEditor.maybeUpdateFormattingState = function(force)
 
        var changes = {}, nchanges = 0, value, tmp, computedStyle;
 
+       value = EvoEditor.mode;
+       if (value != EvoEditor.formattingState.mode) {
+               EvoEditor.formattingState.mode = value;
+               changes["mode"] = value;
+               nchanges++;
+       }
+
        computedStyle = baseElem ? window.getComputedStyle(baseElem) : null;
 
        value = (computedStyle ? computedStyle.fontWeight : "") == "bold";
@@ -1186,6 +1197,42 @@ EvoEditor.initializeContent = function()
        }
 }
 
+EvoEditor.SetMode = function(mode)
+{
+       if (EvoEditor.mode != mode) {
+               var opType = "setMode::" + (mode == EvoEditor.MODE_PLAIN_TEXT ? "PlainText" : "HTML"), record;
+
+               record = EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_DOCUMENT, opType, null, null);
+
+               if (record) {
+                       record.modeBefore = EvoEditor.mode;
+                       record.modeAfter = mode;
+                       record.apply = function(record, isUndo) {
+                               var useMode = isUndo ? record.modeBefore : record.modeAfter;
+
+                               if (EvoEditor.mode != useMode) {
+                                       EvoEditor.mode = useMode;
+                               }
+                       }
+               }
+
+               EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_DOCUMENT, opType);
+
+               EvoUndoRedo.Disable();
+               try {
+                       EvoEditor.mode = mode;
+
+                       if (mode == EvoEditor.MODE_PLAIN_TEXT) {
+                               // TODO convert HTML to "rich" plain-text
+                       } else {
+                               // TODO convert plain to HTML
+                       }
+               } finally {
+                       EvoUndoRedo.Enable();
+               }
+       }
+}
+
 document.onload = EvoEditor.initializeContent;
 
 document.onselectionchange = function() {
diff --git a/data/webkit/e-undo-redo.js b/data/webkit/e-undo-redo.js
index bb9cf0004f..454f865b3a 100644
--- a/data/webkit/e-undo-redo.js
+++ b/data/webkit/e-undo-redo.js
@@ -509,9 +509,13 @@ EvoUndoRedo.applyRecord = function(record, isUndo, withSelection)
        try {
                if (kind == EvoUndoRedo.RECORD_KIND_DOCUMENT) {
                        if (isUndo) {
-                               document.documentElement.outerHTML = record.htmlBefore;
+                               document.documentElement.innerHTML = record.htmlBefore;
                        } else {
-                               document.documentElement.outerHTML = record.htmlAfter;
+                               document.documentElement.innerHTML = record.htmlAfter;
+                       }
+
+                       if (record.apply != null) {
+                               record.apply(record, isUndo);
                        }
                } else if (kind == EvoUndoRedo.RECORD_KIND_CUSTOM && record.apply != null) {
                        record.apply(record, isUndo);
@@ -596,7 +600,7 @@ EvoUndoRedo.StartRecord = function(kind, opType, startNode, endNode, flags)
        record.selectionBefore = EvoSelection.Store(document);
 
        if (kind == EvoUndoRedo.RECORD_KIND_DOCUMENT) {
-               record.htmlBefore = document.documentElement.outerHTML;
+               record.htmlBefore = document.documentElement.innerHTML;
        } else if (kind != EvoUndoRedo.RECORD_KIND_GROUP) {
                var affected;
 
@@ -647,7 +651,7 @@ EvoUndoRedo.StopRecord = function(kind, opType)
        }
 
        if (kind == EvoUndoRedo.RECORD_KIND_DOCUMENT) {
-               record.htmlAfter = document.documentElement.outerHTML;
+               record.htmlAfter = document.documentElement.innerHTML;
        } else if (record.htmlBefore != window.undefined) {
                var commonParent, first, last, ii, html = "";
 
diff --git a/src/e-util/e-html-editor-actions.c b/src/e-util/e-html-editor-actions.c
index 40aa850b95..b45e7b5a75 100644
--- a/src/e-util/e-html-editor-actions.c
+++ b/src/e-util/e-html-editor-actions.c
@@ -605,18 +605,21 @@ update_mode_combobox (gpointer data)
 }
 
 static void
-action_mode_cb (GtkRadioAction *action,
-                GtkRadioAction *current,
-                EHTMLEditor *editor)
+html_editor_actions_notify_html_mode_cb (EContentEditor *cnt_editor,
+                                        GParamSpec *param,
+                                        EHTMLEditor *editor)
 {
-       EContentEditor *cnt_editor;
        GtkActionGroup *action_group;
        GtkWidget *style_combo_box;
        gboolean is_html;
 
-       cnt_editor = e_html_editor_get_content_editor (editor);
+       g_return_if_fail (E_IS_CONTENT_EDITOR (cnt_editor));
+       g_return_if_fail (E_IS_HTML_EDITOR (editor));
+
        is_html = e_content_editor_get_html_mode (cnt_editor);
 
+       g_object_set (G_OBJECT (editor->priv->html_actions), "sensitive", is_html, NULL);
+
        /* This must be done from idle callback, because apparently we can change
         * current value in callback of current value change */
        g_idle_add (update_mode_combobox, editor);
@@ -657,6 +660,15 @@ action_mode_cb (GtkRadioAction *action,
        e_action_combo_box_update_model (E_ACTION_COMBO_BOX (style_combo_box));
 }
 
+static void
+action_mode_cb (GtkRadioAction *action,
+               GtkRadioAction *current,
+               EHTMLEditor *editor)
+{
+       /* Nothing to do here, wait for notification of
+          a property change from the EContentEditor */
+}
+
 static void
 clipboard_text_received_for_paste_as_text (GtkClipboard *clipboard,
                                            const gchar *text,
@@ -1046,6 +1058,7 @@ html_editor_actions_notify_superscript_cb (EContentEditor *cnt_editor,
        manage_format_subsuperscript_notify (editor, GTK_TOGGLE_ACTION (ACTION (SUPERSCRIPT)), "superscript", 
GTK_TOGGLE_ACTION (ACTION (SUBSCRIPT)));
 }
 
+
 /*****************************************************************************
  * Core Actions
  *
@@ -2311,10 +2324,8 @@ editor_actions_bind (EHTMLEditor *editor)
        g_signal_connect_object (cnt_editor, "notify::superscript",
                G_CALLBACK (html_editor_actions_notify_superscript_cb), editor, 0);
 
-       e_binding_bind_property (
-               cnt_editor, "html-mode",
-               editor->priv->html_actions, "sensitive",
-               G_BINDING_SYNC_CREATE);
+       g_signal_connect_object (cnt_editor, "notify::html-mode",
+               G_CALLBACK (html_editor_actions_notify_html_mode_cb), editor, 0);
 
        /* Disable all actions and toolbars when editor is not editable */
        e_binding_bind_property (
diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c
index 8f20d0f264..572f6aa5a6 100644
--- a/src/modules/webkit-editor/e-webkit-editor.c
+++ b/src/modules/webkit-editor/e-webkit-editor.c
@@ -411,6 +411,9 @@ webkit_editor_update_color_value (JSCValue *jsc_params,
        return res;
 }
 
+static void webkit_editor_update_styles (EContentEditor *editor);
+static void webkit_editor_style_updated_cb (EWebKitEditor *wk_editor);
+
 static void
 formatting_changed_cb (WebKitUserContentManager *manager,
                       WebKitJavascriptResult *js_result,
@@ -457,6 +460,26 @@ formatting_changed_cb (WebKitUserContentManager *manager,
        }
        g_clear_object (&jsc_value);
 
+       changed = FALSE;
+       jsc_value = jsc_value_object_get_property (jsc_params, "mode");
+       if (jsc_value && jsc_value_is_number (jsc_value)) {
+               gint value = jsc_value_to_int32 (jsc_value);
+
+               if ((value ? 1 : 0) != (wk_editor->priv->html_mode ? 1 : 0)) {
+                       wk_editor->priv->html_mode = value;
+                       changed = TRUE;
+               }
+       }
+       g_clear_object (&jsc_value);
+
+       if (changed) {
+               /* Update fonts - in plain text we only want monospaced */
+               webkit_editor_update_styles (E_CONTENT_EDITOR (wk_editor));
+               webkit_editor_style_updated_cb (wk_editor);
+
+               g_object_notify (object, "html-mode");
+       }
+
        changed = FALSE;
        jsc_value = jsc_value_object_get_property (jsc_params, "alignment");
        if (jsc_value && jsc_value_is_number (jsc_value)) {
@@ -1576,52 +1599,18 @@ static void
 webkit_editor_set_html_mode (EWebKitEditor *wk_editor,
                              gboolean html_mode)
 {
-       gboolean convert = FALSE;
-       GVariant *result;
-
        g_return_if_fail (E_IS_WEBKIT_EDITOR (wk_editor));
 
-       if (!wk_editor->priv->web_extension_proxy) {
-               printf ("EHTMLEditorWebExtension not ready at %s!\n", G_STRFUNC);
-               return;
-       }
-
        if (html_mode == wk_editor->priv->html_mode)
                return;
 
-       result = e_util_invoke_g_dbus_proxy_call_sync_wrapper_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "DOMCheckIfConversionNeeded",
-               g_variant_new ("(t)", current_page_id (wk_editor)),
-               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) {
-               if (!show_lose_formatting_dialog (wk_editor))
-                       return;
-
-               webkit_editor_set_changed (wk_editor, TRUE);
+       if (html_mode) {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.SetMode(EvoEditor.MODE_HTML);");
+       } else {
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable,
+                       "EvoEditor.SetMode(EvoEditor.MODE_PLAIN_TEXT);");
        }
-
-       wk_editor->priv->html_mode = html_mode;
-
-       e_util_invoke_g_dbus_proxy_call_with_error_check (
-               wk_editor->priv->web_extension_proxy,
-               "SetEditorHTMLMode",
-               g_variant_new ("(tbb)", current_page_id (wk_editor), html_mode, convert),
-               wk_editor->priv->cancellable);
-
-       /* Update fonts - in plain text we only want monospaced */
-       webkit_editor_update_styles (E_CONTENT_EDITOR (wk_editor));
-       webkit_editor_style_updated_cb (wk_editor);
-
-       g_object_notify (G_OBJECT (wk_editor), "html-mode");
 }
 
 static void


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