[evolution/wip/webkit2] EHTMLEditor - Don't insert new HR element when trying to change properties of existing one



commit 2e7932bae64cd7ed6ff21bfcf30c8f953b0b5e6b
Author: Tomas Popela <tpopela redhat com>
Date:   Fri Mar 27 13:44:49 2015 +0100

    EHTMLEditor - Don't insert new HR element when trying to change properties of existing one

 e-util/e-html-editor.c                             |   18 ++++-
 e-util/e-html-editor.h                             |    4 +-
 web-extensions/e-dom-utils.c                       |   20 +++++
 web-extensions/e-dom-utils.h                       |    2 +
 web-extensions/e-html-editor-dom-functions.c       |   80 --------------------
 web-extensions/e-html-editor-dom-functions.h       |   33 --------
 .../e-html-editor-hrule-dialog-dom-functions.c     |   56 +++++---------
 .../e-html-editor-hrule-dialog-dom-functions.h     |    6 +-
 web-extensions/e-html-editor-view-dom-functions.c  |   20 -----
 web-extensions/e-html-editor-web-extension.c       |   80 ++++++++++++++++++-
 10 files changed, 136 insertions(+), 183 deletions(-)
---
diff --git a/e-util/e-html-editor.c b/e-util/e-html-editor.c
index 1918320..2b7775f 100644
--- a/e-util/e-html-editor.c
+++ b/e-util/e-html-editor.c
@@ -307,14 +307,12 @@ html_editor_spell_checkers_foreach (EHTMLEditor *editor,
 }
 
 static void
-html_editor_update_actions (EHTMLEditor *editor,
-                            guint flags)
+html_editor_update_actions (EHTMLEditor *editor)
 {
 //     WebKitSpellChecker *checker;
-       WebKitHitTestResult *hit_test;
-       WebKitHitTestResultContext context;
        EHTMLEditorSelection *selection;
        EHTMLEditorView *view;
+       GDBusProxy *web_extension;
        ESpellChecker *spell_checker;
        GtkUIManager *manager;
        GtkActionGroup *action_group;
@@ -324,8 +322,20 @@ html_editor_update_actions (EHTMLEditor *editor,
        gboolean visible;
        guint merge_id;
        gint loc, len;
+       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);
+               }
+       }
+
        spell_checker = e_html_editor_view_get_spell_checker (view);
 
        manager = e_html_editor_get_ui_manager (editor);
diff --git a/e-util/e-html-editor.h b/e-util/e-html-editor.h
index 5071435..a8e06e8 100644
--- a/e-util/e-html-editor.h
+++ b/e-util/e-html-editor.h
@@ -63,8 +63,8 @@ struct _EHTMLEditor {
 struct _EHTMLEditorClass {
        GtkGridClass parent_class;
 
-       void            (*update_actions)       (EHTMLEditor *editor,
-                                                guint flags);
+       void            (*update_actions)       (EHTMLEditor *editor);
+
        void            (*spell_languages_changed)
                                                (EHTMLEditor *editor);
 };
diff --git a/web-extensions/e-dom-utils.c b/web-extensions/e-dom-utils.c
index 8598deb..1603467 100644
--- a/web-extensions/e-dom-utils.c
+++ b/web-extensions/e-dom-utils.c
@@ -1595,3 +1595,23 @@ remove_node_if_empty (WebKitDOMNode *node)
                g_free (text_content);
        }
 }
+
+WebKitDOMElement *
+get_parent_block_element (WebKitDOMNode *node)
+{
+       WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
+
+       while (parent &&
+              !WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) &&
+              !WEBKIT_DOM_IS_HTML_HEADING_ELEMENT (parent) &&
+              !element_has_tag (parent, "address")) {
+               parent = webkit_dom_node_get_parent_element (
+                       WEBKIT_DOM_NODE (parent));
+       }
+
+       return parent;
+}
diff --git a/web-extensions/e-dom-utils.h b/web-extensions/e-dom-utils.h
index 14521b4..912223b 100644
--- a/web-extensions/e-dom-utils.h
+++ b/web-extensions/e-dom-utils.h
@@ -120,6 +120,8 @@ void                element_remove_class            (WebKitDOMElement *element,
                                                 const gchar* class);
 void           remove_node                     (WebKitDOMNode *node);
 void           remove_node_if_empty            (WebKitDOMNode *node);
+WebKitDOMElement *
+               get_parent_block_element        (WebKitDOMNode *node);
 G_END_DECLS
 
 #endif /* E_DOM_UTILS_H */
diff --git a/web-extensions/e-html-editor-hrule-dialog-dom-functions.c 
b/web-extensions/e-html-editor-hrule-dialog-dom-functions.c
index ac1adf9..ef158b2 100644
--- a/web-extensions/e-html-editor-hrule-dialog-dom-functions.c
+++ b/web-extensions/e-html-editor-hrule-dialog-dom-functions.c
@@ -18,6 +18,7 @@
 
 #include "e-html-editor-hrule-dialog-dom-functions.h"
 
+#include "e-dom-utils.h"
 #include "e-html-editor-selection-dom-functions.h"
 
 #define WEBKIT_DOM_USE_UNSTABLE_API
@@ -25,57 +26,36 @@
 #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
 
 gboolean
-e_html_editor_hrule_dialog_find_hrule (WebKitDOMDocument *document)
+e_html_editor_hrule_dialog_find_hrule (WebKitDOMDocument *document,
+                                       EHTMLEditorWebExtension *extension,
+                                       WebKitDOMNode *node_under_mouse_click)
 {
-       gboolean found = TRUE;
-       WebKitDOMDOMWindow *window;
-       WebKitDOMDOMSelection *selection;
-       WebKitDOMElement *rule = NULL;
-       WebKitDOMRange *range;
-       WebKitDOMNode *node;
+       if (node_under_mouse_click && WEBKIT_DOM_IS_HTML_HR_ELEMENT (node_under_mouse_click)) {
+               webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (node_under_mouse_click), "-x-evo-current-hr");
 
-       window = webkit_dom_document_get_default_view (document);
-       selection = webkit_dom_dom_window_get_selection (window);
-       if (webkit_dom_dom_selection_get_range_count (selection) < 1)
                return FALSE;
+       } else {
+               WebKitDOMElement *selection_start, *parent, *rule;
 
-       range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
-       node = webkit_dom_range_get_common_ancestor_container (range, NULL);
-       if (node && !WEBKIT_DOM_IS_HTML_HR_ELEMENT (node)) {
-               rule = dom_node_find_parent_element (node, "A");
-               if (rule && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (rule))
-                       rule = NULL;
-       } else
-               rule = WEBKIT_DOM_ELEMENT (node);
+               dom_selection_save (document);
 
-       if (!rule) {
-               WebKitDOMElement *caret, *parent, *element;
-
-               caret = dom_save_caret_position (document);
-               parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (caret));
-               element = caret;
-
-               while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
-                       element = parent;
-                       parent = webkit_dom_node_get_parent_element (
-                               WEBKIT_DOM_NODE (parent));
-               }
+               selection_start = webkit_dom_document_get_element_by_id (
+                       document, "-x-evo-selection-start-marker");
+               parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start));
 
                rule = webkit_dom_document_create_element (document, "HR", NULL);
+               webkit_dom_element_set_id (rule, "-x-evo-current-hr");
 
                /* Insert horizontal rule into body below the caret */
                webkit_dom_node_insert_before (
-                       WEBKIT_DOM_NODE (parent),
+                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (parent)),
                        WEBKIT_DOM_NODE (rule),
-                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element)),
+                       webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)),
                        NULL);
 
-               dom_clear_caret_position_marker (document);
+               dom_selection_restore (document);
 
-               found = FALSE;
+               e_html_editor_web_extension_set_content_changed (extension);
        }
-
-       webkit_dom_element_set_id (rule, "-x-evo-current-hr");
-
-       return found;
+       return TRUE;
 }
diff --git a/web-extensions/e-html-editor-hrule-dialog-dom-functions.h 
b/web-extensions/e-html-editor-hrule-dialog-dom-functions.h
index 4f6e57c..1d7c55a 100644
--- a/web-extensions/e-html-editor-hrule-dialog-dom-functions.h
+++ b/web-extensions/e-html-editor-hrule-dialog-dom-functions.h
@@ -21,10 +21,14 @@
 
 #include <webkitdom/webkitdom.h>
 
+#include "e-html-editor-web-extension.h"
+
 G_BEGIN_DECLS
 
 gboolean       e_html_editor_hrule_dialog_find_hrule
-                                               (WebKitDOMDocument *document);
+                                               (WebKitDOMDocument *document,
+                                                EHTMLEditorWebExtension *extension,
+                                                WebKitDOMNode *node_under_mouse_click);
 
 G_END_DECLS
 
diff --git a/web-extensions/e-html-editor-view-dom-functions.c 
b/web-extensions/e-html-editor-view-dom-functions.c
index e504352..747b6f5 100644
--- a/web-extensions/e-html-editor-view-dom-functions.c
+++ b/web-extensions/e-html-editor-view-dom-functions.c
@@ -122,26 +122,6 @@ dom_exec_command (WebKitDOMDocument *document,
                document, cmd_str, FALSE, has_value ? value : "" );
 }
 
-static WebKitDOMElement *
-get_parent_block_element (WebKitDOMNode *node)
-{
-       WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
-
-       while (parent &&
-              !WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) &&
-              !WEBKIT_DOM_IS_HTML_HEADING_ELEMENT (parent) &&
-              !element_has_tag (parent, "address")) {
-               parent = webkit_dom_node_get_parent_element (
-                       WEBKIT_DOM_NODE (parent));
-       }
-
-       return parent;
-}
-
 void
 dom_force_spell_check_for_current_paragraph (WebKitDOMDocument *document,
                                              EHTMLEditorWebExtension *extension)
diff --git a/web-extensions/e-html-editor-web-extension.c b/web-extensions/e-html-editor-web-extension.c
index f91ee23..526ff32 100644
--- a/web-extensions/e-html-editor-web-extension.c
+++ b/web-extensions/e-html-editor-web-extension.c
@@ -30,11 +30,12 @@
 
 #include <e-util/e-misc-utils.h>
 
+#include <e-util/e-html-editor-defines.h>
+
 #include "e-composer-private-dom-functions.h"
 #include "e-dom-utils.h"
 #include "e-html-editor-actions-dom-functions.h"
 #include "e-html-editor-cell-dialog-dom-functions.h"
-#include "e-html-editor-dom-functions.h"
 #include "e-html-editor-hrule-dialog-dom-functions.h"
 #include "e-html-editor-image-dialog-dom-functions.h"
 #include "e-html-editor-link-dialog-dom-functions.h"
@@ -92,6 +93,9 @@ struct _EHTMLEditorWebExtensionPrivate {
        gboolean remove_initial_input_line;
 
        GHashTable *inline_images;
+
+       WebKitDOMNode *node_under_mouse_click;
+       guint node_under_mouse_click_flags;
 };
 
 static CamelDataCache *emd_global_http_cache = NULL;
@@ -111,6 +115,7 @@ static const char introspection_xml[] =
 "    <property type='b' name='IsMessageFromSelection' access='readwrite'/>"
 "    <property type='b' name='IsFromNewMessage' access='readwrite'/>"
 "    <property type='b' name='RemoveInitialInputLine' access='readwrite'/>"
+"    <property type='b' name='NodeUnderMouseClickFlags' access='read'/>"
 "<!-- ********************************************************* -->"
 "<!-- These properties show the actual state of EHTMLEditorView -->"
 "<!-- ********************************************************* -->"
@@ -239,6 +244,7 @@ static const char introspection_xml[] =
 "<!-- ********************************************************* -->"
 "    <method name='EHTMLEditorHRuleDialogFindHRule'>"
 "      <arg type='t' name='page_id' direction='in'/>"
+"      <arg type='b' name='created' direction='out'/>"
 "    </method>"
 "    <method name='HRElementSetNoShade'>"
 "      <arg type='t' name='page_id' direction='in'/>"
@@ -851,6 +857,7 @@ handle_method_call (GDBusConnection *connection,
 
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "EHTMLEditorHRuleDialogFindHRule") == 0) {
+               gboolean created = FALSE;
                g_variant_get (parameters, "(t)", &page_id);
 
                web_page = get_webkit_web_page_or_return_dbus_error (
@@ -859,9 +866,11 @@ handle_method_call (GDBusConnection *connection,
                        return;
 
                document = webkit_web_page_get_dom_document (web_page);
-               e_html_editor_hrule_dialog_find_hrule (document);
+               created = e_html_editor_hrule_dialog_find_hrule (
+                       document, extension, extension->priv->node_under_mouse_click);
 
-               g_dbus_method_invocation_return_value (invocation, NULL);
+               g_dbus_method_invocation_return_value (
+                       invocation, g_variant_new_boolean (created));
        } else if (g_strcmp0 (method_name, "HRElementSetNoShade") == 0) {
                gboolean value = FALSE;
                const gchar *element_id;
@@ -1620,10 +1629,10 @@ handle_method_call (GDBusConnection *connection,
                        return;
 
                document = webkit_web_page_get_dom_document (web_page);
-               if (cancel_if_not_collapsed)
+               if (cancel_if_not_collapsed) {
                        if (dom_selection_is_collapsed (document))
                                dom_selection_set_on_point (document, x, y);
-               else
+               } else
                        dom_selection_set_on_point (document, x, y);
                g_dbus_method_invocation_return_value (invocation, NULL);
        } else if (g_strcmp0 (method_name, "DOMSelectionIndent") == 0) {
@@ -1807,6 +1816,8 @@ handle_get_property (GDBusConnection *connection,
                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;
 }
@@ -2250,6 +2261,8 @@ e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
        extension->priv->is_message_from_selection = FALSE;
        extension->priv->remove_initial_input_line = FALSE;
 
+       extension->priv->node_under_mouse_click = NULL;
+
        extension->priv->inline_images = g_hash_table_new_full (
                g_str_hash, g_str_equal,
                (GDestroyNotify) g_free,
@@ -2382,6 +2395,58 @@ web_page_document_loaded_cb (WebKitWebPage *web_page,
        dom_process_content_after_load (document, web_extension);
 }
 
+static gboolean
+web_page_context_menu_cb (WebKitWebPage *web_page,
+                         WebKitContextMenu *context_menu,
+                         WebKitWebHitTestResult *hit_test_result,
+                          EHTMLEditorWebExtension *web_extension)
+{
+       WebKitDOMNode *node;
+       guint flags = 0;
+
+       node = webkit_web_hit_test_result_get_node (hit_test_result);
+       web_extension->priv->node_under_mouse_click = node;
+
+       if (WEBKIT_DOM_IS_TEXT (node)) {
+               flags |= E_HTML_EDITOR_NODE_IS_TEXT;
+               return flags;
+       }
+
+       if (WEBKIT_DOM_IS_HTML_HR_ELEMENT (node))
+               flags |= E_HTML_EDITOR_NODE_IS_HR;
+
+       if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
+           (dom_node_find_parent_element (node, "A") != NULL))
+               flags |= E_HTML_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;
+       }
+
+       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;
+       }
+
+       if (flags && E_HTML_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;
+       }
+
+       if (flags == 0)
+               flags |= E_HTML_EDITOR_NODE_IS_TEXT;
+
+       web_extension->priv->node_under_mouse_click_flags = flags;
+
+       return FALSE;
+}
+
 static void
 web_page_created_cb (WebKitWebExtension *wk_extension,
                      WebKitWebPage *web_page,
@@ -2396,6 +2461,11 @@ web_page_created_cb (WebKitWebExtension *wk_extension,
                web_page, "document-loaded",
                G_CALLBACK (web_page_document_loaded_cb),
                extension, 0);
+
+       g_signal_connect_object (
+               web_page, "context-menu",
+               G_CALLBACK (web_page_context_menu_cb),
+               extension, 0);
 }
 
 void


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