[evolution] Bug 732609 - Cannot decrease indentation



commit de8a0a960ebb3854d614e3f10cb56a29c50737eb
Author: Tomas Popela <tpopela redhat com>
Date:   Wed Jul 2 17:11:55 2014 +0200

    Bug 732609 - Cannot decrease indentation
    
    Don't use WebKit indent/unindent commands. Make our indentation/undentation
    code (that was used when there was no selection) selection aware.

 e-util/e-html-editor-selection.c |  634 ++++++++++++++++++++++++--------------
 1 files changed, 408 insertions(+), 226 deletions(-)
---
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index 3fcdad8..f566693 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -1055,6 +1055,38 @@ e_html_editor_selection_get_list_alignment_from_node (WebKitDOMNode *node)
        return E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
 }
 
+static EHTMLEditorSelectionAlignment
+e_html_editor_selection_get_alignment_from_node (WebKitDOMNode *node)
+{
+       EHTMLEditorSelectionAlignment alignment;
+       gchar *value;
+       WebKitDOMCSSStyleDeclaration *style;
+       WebKitDOMDocument *document;
+       WebKitDOMDOMWindow *window;
+
+       document = webkit_dom_node_get_owner_document (node);
+       window = webkit_dom_document_get_default_view (document);
+
+       style = webkit_dom_dom_window_get_computed_style (
+               window, WEBKIT_DOM_ELEMENT (node), NULL);
+       value = webkit_dom_css_style_declaration_get_property_value (style, "text-align");
+
+       if (!value || !*value ||
+           (g_ascii_strncasecmp (value, "left", 4) == 0)) {
+               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+       } else if (g_ascii_strncasecmp (value, "center", 6) == 0) {
+               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER;
+       } else if (g_ascii_strncasecmp (value, "right", 5) == 0) {
+               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT;
+       } else {
+               alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+       }
+
+       g_free (value);
+
+       return alignment;
+}
+
 /**
  * e_html_editor_selection_get_alignment:
  * @selection: #an EHTMLEditorSelection
@@ -2471,6 +2503,18 @@ e_html_editor_selection_is_citation (EHTMLEditorSelection *selection)
        return ret_val;
 }
 
+static WebKitDOMElement*
+get_element_for_inspection (WebKitDOMRange *range)
+{
+       WebKitDOMNode *node;
+
+       node = webkit_dom_range_get_end_container (range, NULL);
+       if (!WEBKIT_DOM_IS_ELEMENT (node))
+               node = WEBKIT_DOM_NODE (webkit_dom_node_get_parent_element (node));
+
+       return webkit_dom_node_get_parent_element (node);
+}
+
 /**
  * e_html_editor_selection_is_indented:
  * @selection: an #EHTMLEditorSelection
@@ -2484,9 +2528,8 @@ e_html_editor_selection_is_citation (EHTMLEditorSelection *selection)
 gboolean
 e_html_editor_selection_is_indented (EHTMLEditorSelection *selection)
 {
-       WebKitDOMRange *range;
-       WebKitDOMNode *node;
        WebKitDOMElement *element;
+       WebKitDOMRange *range;
 
        g_return_val_if_fail (E_IS_HTML_EDITOR_SELECTION (selection), FALSE);
 
@@ -2494,13 +2537,29 @@ e_html_editor_selection_is_indented (EHTMLEditorSelection *selection)
        if (!range)
                return FALSE;
 
-       node = webkit_dom_range_get_end_container (range, NULL);
-       if (!WEBKIT_DOM_IS_ELEMENT (node))
-               node = WEBKIT_DOM_NODE (webkit_dom_node_get_parent_element (node));
+       if (g_strcmp0 (e_html_editor_selection_get_string (selection), "") == 0) {
+               element = get_element_for_inspection (range);
+               return element_has_class (element, "-x-evo-indented");
+       } else {
+               /* If there is a selection search in it and don't look just in
+                * the end container */
+               WebKitDOMDocumentFragment *fragment;
+
+               fragment = webkit_dom_range_clone_contents (range, NULL);
 
-       element = webkit_dom_node_get_parent_element (node);
+               if (fragment) {
+                       element = webkit_dom_document_fragment_query_selector (
+                               fragment, ".-x-evo-indented", NULL);
 
-       return element_has_class (element, "-x-evo-indented");
+                       if (element)
+                               return TRUE;
+
+                       element = get_element_for_inspection (range);
+                       return element_has_class (element, "-x-evo-indented");
+               }
+       }
+
+       return FALSE;
 }
 
 static gboolean
@@ -2532,6 +2591,73 @@ get_list_level (WebKitDOMNode *node)
        return level;
 }
 
+static WebKitDOMNode *
+get_parent_block_node (WebKitDOMNode *node)
+{
+       WebKitDOMNode *parent;
+
+       parent = webkit_dom_node_get_parent_node (node);
+
+       while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+               node = parent;
+               parent = webkit_dom_node_get_parent_node (parent);
+       }
+
+       return node;
+}
+
+static void
+indent_list (EHTMLEditorSelection *selection,
+             WebKitDOMDocument *document)
+{
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
+       WebKitDOMNode *item, *next_item;
+       gboolean after_selection_end = FALSE;
+
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
+
+       item = get_parent_block_node_from_child (
+               WEBKIT_DOM_NODE (selection_start_marker));
+
+       if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
+               gboolean html_mode = is_in_html_mode (selection);
+               WebKitDOMElement *list;
+               WebKitDOMNode *source_list = webkit_dom_node_get_parent_node (item);
+               EHTMLEditorSelectionBlockFormat format;
+
+               format = e_html_editor_selection_get_list_format_from_node (source_list);
+
+               list = create_list_element (
+                       selection, document, format, get_list_level (item), html_mode);
+
+               element_add_class (list, "-x-evo-indented");
+
+               webkit_dom_node_insert_before (
+                       source_list, WEBKIT_DOM_NODE (list), item, NULL);
+
+               while (item) {
+                       after_selection_end = webkit_dom_node_contains (
+                               item, WEBKIT_DOM_NODE (selection_end_marker));
+
+                       next_item = webkit_dom_node_get_next_sibling (item);
+
+                       webkit_dom_node_append_child (
+                               WEBKIT_DOM_NODE (list), item, NULL);
+
+                       item = next_item;
+
+                       if (after_selection_end)
+                               break;
+               }
+
+               merge_lists_if_possible (WEBKIT_DOM_NODE (list));
+       }
+}
+
 /**
  * e_html_editor_selection_indent:
  * @selection: an #EHTMLEditorSelection
@@ -2541,129 +2667,165 @@ get_list_level (WebKitDOMNode *node)
 void
 e_html_editor_selection_indent (EHTMLEditorSelection *selection)
 {
-       gboolean has_selection;
        EHTMLEditorView *view;
-       EHTMLEditorViewCommand command;
+       WebKitDOMDocument *document;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
+       WebKitDOMNode *block;
 
        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);
 
-       has_selection = g_strcmp0 (e_html_editor_selection_get_string (selection), "") != 0;
+       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+
+       e_html_editor_selection_save (selection);
+
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
 
-       if (!has_selection) {
-               WebKitDOMDocument *document;
-               WebKitDOMRange *range;
-               WebKitDOMNode *node, *clone;
-               WebKitDOMElement *element, *caret_position;
+       /* If the selection was not saved, move it into the first child of body */
+       if (!selection_start_marker || !selection_end_marker) {
+               WebKitDOMHTMLElement *body;
+
+               body = webkit_dom_document_get_body (document);
+               selection_start_marker = webkit_dom_document_create_element (
+                       document, "SPAN", NULL);
+               webkit_dom_element_set_id (
+                       selection_start_marker, "-x-evo-selection-start-marker");
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       WEBKIT_DOM_NODE (selection_start_marker),
+                       webkit_dom_node_get_first_child (
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body))),
+                       NULL);
+               selection_end_marker = webkit_dom_document_create_element (
+                       document, "SPAN", NULL);
+               webkit_dom_element_set_id (
+                       selection_end_marker, "-x-evo-selection-end-marker");
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       WEBKIT_DOM_NODE (selection_end_marker),
+                       webkit_dom_node_get_first_child (
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body))),
+                       NULL);
+       }
+
+       block = get_parent_block_node (
+               WEBKIT_DOM_NODE (selection_start_marker));
+
+       while (block) {
+               gboolean after_selection_end = FALSE;
+               gint ii, length, level, final_width = 0;
                gint word_wrap_length = selection->priv->word_wrap_length;
-               gint level;
-               gint final_width = 0;
+               WebKitDOMElement *element;
+               WebKitDOMNode *next_block, *block_to_process;
+               WebKitDOMNodeList *list;
 
-               document = webkit_web_view_get_dom_document (
-                       WEBKIT_WEB_VIEW (view));
+               next_block = webkit_dom_node_get_next_sibling (block);
 
-               caret_position = e_html_editor_selection_save_caret_position (selection);
+               list = webkit_dom_element_query_selector_all (
+                       WEBKIT_DOM_ELEMENT (block),
+                       ".-x-evo-indented > *:not(.-x-evo-indented):not(li)",
+                       NULL);
 
-               range = html_editor_selection_get_current_range (selection);
-               if (!range) {
-                       g_object_unref (view);
-                       return;
-               }
+               length = webkit_dom_node_list_get_length (list);
+               if (length == 0) {
+                       block_to_process = block;
 
-               node = webkit_dom_range_get_end_container (range, NULL);
-               if (!WEBKIT_DOM_IS_ELEMENT (node))
-                       node = WEBKIT_DOM_NODE (
-                               webkit_dom_node_get_parent_element (node));
+                       after_selection_end = webkit_dom_node_contains (
+                               block_to_process, WEBKIT_DOM_NODE (selection_end_marker));
 
-               if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (node)) {
-                       gboolean html_mode = e_html_editor_view_get_html_mode (view);
-                       WebKitDOMElement *list;
-                       WebKitDOMNode *source_list = webkit_dom_node_get_parent_node (node);
-                       EHTMLEditorSelectionBlockFormat format;
+                       if (node_is_list (block_to_process)) {
+                               indent_list (selection, document);
+                               if (!after_selection_end) {
+                                       block = next_block;
+                                       continue;
+                               } else
+                                       goto out;
+                       }
 
-                       format = e_html_editor_selection_get_list_format_from_node (source_list);
+                       level = get_indentation_level (WEBKIT_DOM_ELEMENT (block_to_process));
 
-                       list = create_list_element (
-                               selection, document, format, get_list_level (node), html_mode);
+                       final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
+                       if (final_width < 10 && !is_in_html_mode (selection)) {
+                               if (!after_selection_end) {
+                                       block = next_block;
+                                       continue;
+                               } else
+                                       goto out;
+                       }
+
+                       element = e_html_editor_selection_get_indented_element (
+                               selection, document, final_width);
 
-                       element_add_class (list, "-x-evo-indented");
                        webkit_dom_node_insert_before (
-                               source_list, WEBKIT_DOM_NODE (list), node, NULL);
+                               webkit_dom_node_get_parent_node (block_to_process),
+                               WEBKIT_DOM_NODE (element),
+                               block_to_process,
+                               NULL);
+
+                       /* Remove style and let the paragraph inherit it from parent */
+                       if (element_has_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-paragraph"))
+                               webkit_dom_element_remove_attribute (
+                                       WEBKIT_DOM_ELEMENT (block_to_process), "style");
+
                        webkit_dom_node_append_child (
-                               WEBKIT_DOM_NODE (list), node, NULL);
+                               WEBKIT_DOM_NODE (element),
+                               block_to_process,
+                               NULL);
 
-                       if (!webkit_dom_node_contains (node, WEBKIT_DOM_NODE (caret_position)))
-                               webkit_dom_node_append_child (
-                                       node, WEBKIT_DOM_NODE (caret_position), NULL);
+                       if (after_selection_end)
+                               goto out;
+               }
 
-                       merge_lists_if_possible (WEBKIT_DOM_NODE (list));
+               for (ii = 0; ii < length; ii++) {
+                       block_to_process = webkit_dom_node_list_item (list, ii);
 
-                       e_html_editor_selection_restore_caret_position (selection);
+                       after_selection_end = webkit_dom_node_contains (
+                               block_to_process, WEBKIT_DOM_NODE (selection_end_marker));
 
-                       g_object_unref (view);
-                       return;
-               }
+                       level = get_indentation_level (WEBKIT_DOM_ELEMENT (block_to_process));
 
-               level = get_indentation_level (WEBKIT_DOM_ELEMENT (node));
+                       final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
+                       if (final_width < 10 && !is_in_html_mode (selection))
+                               continue;
 
-               final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
-               if (final_width < 10 && !is_in_html_mode (selection)) {
-                       e_html_editor_selection_restore_caret_position (selection);
-                       g_object_unref (view);
-                       return;
-               }
+                       element = e_html_editor_selection_get_indented_element (
+                               selection, document, final_width);
 
-               element = webkit_dom_node_get_parent_element (node);
-               clone = webkit_dom_node_clone_node (node, TRUE);
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (block_to_process),
+                               WEBKIT_DOM_NODE (element),
+                               block_to_process,
+                               NULL);
+
+                       /* Remove style and let the paragraph inherit it from parent */
+                       if (element_has_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-paragraph"))
+                               webkit_dom_element_remove_attribute (
+                                       WEBKIT_DOM_ELEMENT (block_to_process), "style");
 
-               /* Remove style and let the paragraph inherit it from parent */
-               if (element_has_class (WEBKIT_DOM_ELEMENT (clone), "-x-evo-paragraph"))
-                       webkit_dom_element_remove_attribute (
-                               WEBKIT_DOM_ELEMENT (clone), "style");
-
-               element = e_html_editor_selection_get_indented_element (
-                       selection, document, final_width);
-
-               /* Reinsert caret position node if the node is missing it */
-               if (!webkit_dom_node_contains (clone, WEBKIT_DOM_NODE (caret_position))) {
-                       gchar *text_content = webkit_dom_node_get_text_content (clone);
-                       if (!*text_content) {
-                               webkit_dom_html_element_set_inner_html (
-                                       WEBKIT_DOM_HTML_ELEMENT (clone),
-                                       UNICODE_ZERO_WIDTH_SPACE,
-                                       NULL);
-                       }
-                       g_free (text_content);
                        webkit_dom_node_append_child (
-                               clone,
-                               WEBKIT_DOM_NODE (caret_position),
+                               WEBKIT_DOM_NODE (element),
+                               block_to_process,
                                NULL);
-               }
-
-               webkit_dom_node_append_child (
-                       WEBKIT_DOM_NODE (element),
-                       clone,
-                       NULL);
 
-               webkit_dom_node_replace_child (
-                       webkit_dom_node_get_parent_node (node),
-                       WEBKIT_DOM_NODE (element),
-                       node,
-                       NULL);
+                       if (after_selection_end)
+                               goto out;
+               }
 
-               e_html_editor_selection_restore_caret_position (selection);
-       } else {
-               command = E_HTML_EDITOR_VIEW_COMMAND_INDENT;
-               e_html_editor_selection_save (selection);
-               e_html_editor_view_exec_command (view, command, NULL);
+               block = next_block;
        }
 
+ out:
        e_html_editor_view_force_spell_check (view);
 
-       if (has_selection)
-               e_html_editor_selection_restore (selection);
+       e_html_editor_selection_restore (selection);
 
        g_object_unref (view);
 
@@ -2691,9 +2853,9 @@ unindent_list (EHTMLEditorSelection *selection,
 {
        gboolean after = FALSE;
        WebKitDOMElement *new_list;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
        WebKitDOMNode *source_list, *source_list_clone, *current_list, *item;
-       WebKitDOMElement *selection_start_marker;
-       WebKitDOMElement *selection_end_marker;
+       WebKitDOMNode *prev_item;
 
        selection_start_marker = webkit_dom_document_query_selector (
                document, "span#-x-evo-selection-start-marker", NULL);
@@ -2704,7 +2866,7 @@ unindent_list (EHTMLEditorSelection *selection,
                return;
 
        /* Copy elements from previous block to list */
-       item = webkit_dom_node_get_parent_node (
+       item = get_parent_block_node_from_child (
                WEBKIT_DOM_NODE (selection_start_marker));
        source_list = webkit_dom_node_get_parent_node (item);
        new_list = WEBKIT_DOM_ELEMENT (
@@ -2721,20 +2883,21 @@ unindent_list (EHTMLEditorSelection *selection,
        if (element_has_class (WEBKIT_DOM_ELEMENT (source_list), "-x-evo-indented"))
                element_add_class (WEBKIT_DOM_ELEMENT (new_list), "-x-evo-indented");
 
+       prev_item = source_list;
+
        while (item) {
                WebKitDOMNode *next_item = webkit_dom_node_get_next_sibling (item);
 
                if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
-                       if (after) {
-                               webkit_dom_node_append_child (
+                       if (after)
+                               prev_item = webkit_dom_node_append_child (
                                        source_list_clone, WEBKIT_DOM_NODE (item), NULL);
-                       } else {
-                               webkit_dom_node_insert_before (
-                                       webkit_dom_node_get_parent_node (source_list),
+                       else
+                               prev_item = webkit_dom_node_insert_before (
+                                       webkit_dom_node_get_parent_node (prev_item),
                                        item,
-                                       webkit_dom_node_get_next_sibling (source_list),
+                                       webkit_dom_node_get_next_sibling (prev_item),
                                        NULL);
-                       }
                }
 
                if (webkit_dom_node_contains (item, WEBKIT_DOM_NODE (selection_end_marker)))
@@ -2762,165 +2925,184 @@ unindent_list (EHTMLEditorSelection *selection,
 void
 e_html_editor_selection_unindent (EHTMLEditorSelection *selection)
 {
-       gboolean has_selection;
        EHTMLEditorView *view;
-       EHTMLEditorViewCommand command;
+       EHTMLEditorSelectionAlignment alignment;
+       WebKitDOMDocument *document;
+       WebKitDOMElement *selection_start_marker, *selection_end_marker;
+       WebKitDOMNode *block;
 
        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);
 
-       has_selection = g_strcmp0 (e_html_editor_selection_get_string (selection), "") != 0;
+       document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
 
-       if (!has_selection) {
-               EHTMLEditorSelectionAlignment alignment;
-               gboolean before_node = TRUE, reinsert_caret_position = FALSE;
-               const gchar *align_value;
-               gint word_wrap_length = selection->priv->word_wrap_length;
-               gint level, width;
-               WebKitDOMDocument *document;
-               WebKitDOMElement *element;
-               WebKitDOMElement *prev_blockquote = NULL, *next_blockquote = NULL;
-               WebKitDOMNode *node, *clone, *node_clone, *caret_node;
-               WebKitDOMRange *range;
+       e_html_editor_selection_save (selection);
 
-               document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+       selection_start_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-start-marker", NULL);
+       selection_end_marker = webkit_dom_document_query_selector (
+               document, "span#-x-evo-selection-end-marker", NULL);
 
-               e_html_editor_selection_save_caret_position (selection);
+       /* If the selection was not saved, move it into the first child of body */
+       if (!selection_start_marker || !selection_end_marker) {
+               WebKitDOMHTMLElement *body;
+
+               body = webkit_dom_document_get_body (document);
+               selection_start_marker = webkit_dom_document_create_element (
+                       document, "SPAN", NULL);
+               webkit_dom_element_set_id (
+                       selection_start_marker, "-x-evo-selection-start-marker");
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       WEBKIT_DOM_NODE (selection_start_marker),
+                       webkit_dom_node_get_first_child (
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body))),
+                       NULL);
+               selection_end_marker = webkit_dom_document_create_element (
+                       document, "SPAN", NULL);
+               webkit_dom_element_set_id (
+                       selection_end_marker, "-x-evo-selection-end-marker");
+               webkit_dom_node_insert_before (
+                       webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+                       WEBKIT_DOM_NODE (selection_end_marker),
+                       webkit_dom_node_get_first_child (
+                               webkit_dom_node_get_first_child (
+                                       WEBKIT_DOM_NODE (body))),
+                       NULL);
+       }
 
-               alignment = e_html_editor_selection_get_alignment (selection);
-               align_value = get_css_alignment_value (alignment);
+       block = get_parent_block_node (
+               WEBKIT_DOM_NODE (selection_start_marker));
 
-               range = html_editor_selection_get_current_range (selection);
-               if (!range) {
-                       g_object_unref (view);
-                       return;
-               }
+       while (block) {
+               gboolean after_selection_end = FALSE;
+               gint ii, length;
+               WebKitDOMNode *next_block;
+               WebKitDOMNodeList *list;
 
-               node = webkit_dom_range_get_end_container (range, NULL);
-               if (!WEBKIT_DOM_IS_ELEMENT (node))
-                       node = WEBKIT_DOM_NODE (webkit_dom_node_get_parent_element (node));
+               next_block = webkit_dom_node_get_next_sibling (block);
 
-               element = webkit_dom_node_get_parent_element (node);
+               list = webkit_dom_element_query_selector_all (
+                       WEBKIT_DOM_ELEMENT (block),
+                       ".-x-evo-indented > *:not(.-x-evo-indented):not(li)",
+                       NULL);
 
-               if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (node)) {
-                       e_html_editor_selection_save (selection);
-                       e_html_editor_selection_clear_caret_position_marker (selection);
+               after_selection_end = webkit_dom_node_contains (
+                       block, WEBKIT_DOM_NODE (selection_end_marker));
 
+               length = webkit_dom_node_list_get_length (list);
+               if (length == 0 && node_is_list (block)) {
                        unindent_list (selection, document);
-                       e_html_editor_view_force_spell_check (view);
-                       e_html_editor_selection_restore (selection);
-                       g_object_unref (view);
-                       return;
+                       if (!after_selection_end) {
+                               block = next_block;
+                               continue;
+                       } else
+                               goto out;
                }
 
-               if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (element))
-                       return;
-
-               element_add_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-to-unindent");
-
-               level = get_indentation_level (element);
-               width = word_wrap_length - SPACES_PER_INDENTATION * level;
-               clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
-
-               /* Look if we have previous siblings, if so, we have to
-                * create new blockquote that will include them */
-               if (webkit_dom_node_get_previous_sibling (node))
-                       prev_blockquote = e_html_editor_selection_get_indented_element (
-                               selection, document, width);
+               for (ii = 0; ii < length; ii++) {
+                       gboolean before_node = TRUE;
+                       const gchar *align_value;
+                       gint word_wrap_length = selection->priv->word_wrap_length;
+                       gint level, width;
+                       WebKitDOMElement *element;
+                       WebKitDOMElement *prev_blockquote = NULL, *next_blockquote = NULL;
+                       WebKitDOMNode *block_to_process, *node_clone, *child;
 
-               /* Look if we have next siblings, if so, we have to
-                * create new blockquote that will include them */
-               if (webkit_dom_node_get_next_sibling (node))
-                       next_blockquote = e_html_editor_selection_get_indented_element (
-                               selection, document, width);
+                       block_to_process = webkit_dom_node_list_item (list, ii);
 
-               /* Copy nodes that are before / after the element that we want to unindent */
-               while (webkit_dom_node_has_child_nodes (clone)) {
-                       WebKitDOMNode *child;
+                       alignment = e_html_editor_selection_get_alignment_from_node (block_to_process);
+                       align_value = get_css_alignment_value (alignment);
 
-                       child = webkit_dom_node_get_first_child (clone);
+                       element = webkit_dom_node_get_parent_element (block_to_process);
 
-                       if (is_caret_position_node (child)) {
-                               reinsert_caret_position = TRUE;
-                               caret_node = webkit_dom_node_clone_node (child, TRUE);
-                               remove_node (child);
+                       if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (element))
                                continue;
-                       }
 
-                       if (webkit_dom_node_is_equal_node (child, node)) {
-                               before_node = FALSE;
-                               node_clone = webkit_dom_node_clone_node (child, TRUE);
-                               remove_node (child);
-                               continue;
-                       }
+                       element_add_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-to-unindent");
+
+                       level = get_indentation_level (element);
+                       width = word_wrap_length - SPACES_PER_INDENTATION * level;
+
+                       /* Look if we have previous siblings, if so, we have to
+                        * create new blockquote that will include them */
+                       if (webkit_dom_node_get_previous_sibling (block_to_process))
+                               prev_blockquote = e_html_editor_selection_get_indented_element (
+                                       selection, document, width);
+
+                       /* Look if we have next siblings, if so, we have to
+                        * create new blockquote that will include them */
+                       if (webkit_dom_node_get_next_sibling (block_to_process))
+                               next_blockquote = e_html_editor_selection_get_indented_element (
+                                       selection, document, width);
+
+                       /* Copy nodes that are before / after the element that we want to unindent */
+                       while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
+                               if (webkit_dom_node_is_equal_node (child, block_to_process)) {
+                                       before_node = FALSE;
+                                       node_clone = webkit_dom_node_clone_node (child, TRUE);
+                                       remove_node (child);
+                                       continue;
+                               }
 
-                       webkit_dom_node_append_child (
-                               before_node ?
-                                       WEBKIT_DOM_NODE (prev_blockquote) :
-                                       WEBKIT_DOM_NODE (next_blockquote),
-                               child,
-                               NULL);
-               }
+                               webkit_dom_node_append_child (
+                                       before_node ?
+                                               WEBKIT_DOM_NODE (prev_blockquote) :
+                                               WEBKIT_DOM_NODE (next_blockquote),
+                                       child,
+                                       NULL);
+                       }
 
-               element_remove_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-to-unindent");
+                       element_remove_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-to-unindent");
 
-               /* Insert blockqoute with nodes that were before the element that we want to unindent */
-               if (prev_blockquote) {
-                       if (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (prev_blockquote))) {
-                               webkit_dom_node_insert_before (
-                                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-                                       WEBKIT_DOM_NODE (prev_blockquote),
-                                       WEBKIT_DOM_NODE (element),
-                                       NULL);
+                       /* Insert blockqoute with nodes that were before the element that we want to unindent 
*/
+                       if (prev_blockquote) {
+                               if (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (prev_blockquote))) {
+                                       webkit_dom_node_insert_before (
+                                               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+                                               WEBKIT_DOM_NODE (prev_blockquote),
+                                               WEBKIT_DOM_NODE (element),
+                                               NULL);
+                               }
                        }
-               }
 
-               /* Reinsert the caret position */
-               if (reinsert_caret_position) {
-                       webkit_dom_node_append_child (
+                       if (level == 1 && element_has_class (WEBKIT_DOM_ELEMENT (node_clone), 
"-x-evo-paragraph"))
+                               e_html_editor_selection_set_paragraph_style (
+                                       selection, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, 
align_value);
+
+                       /* Insert the unindented element */
+                       webkit_dom_node_insert_before (
+                               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
                                node_clone,
-                               caret_node,
+                               WEBKIT_DOM_NODE (element),
                                NULL);
-               }
-
-               if (level == 1 && element_has_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-paragraph"))
-                       e_html_editor_selection_set_paragraph_style (
-                               selection, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, align_value);
-
-               /* Insert the unindented element */
-               webkit_dom_node_insert_before (
-                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-                       node_clone,
-                       WEBKIT_DOM_NODE (element),
-                       NULL);
 
-               /* Insert blockqoute with nodes that were after the element that we want to unindent */
-               if (next_blockquote) {
-                       if (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (prev_blockquote))) {
-                               webkit_dom_node_insert_before (
-                                       webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
-                                       WEBKIT_DOM_NODE (next_blockquote),
-                                       WEBKIT_DOM_NODE (element),
-                                       NULL);
+                       /* Insert blockqoute with nodes that were after the element that we want to unindent 
*/
+                       if (next_blockquote) {
+                               if (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (next_blockquote))) {
+                                       webkit_dom_node_insert_before (
+                                               webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+                                               WEBKIT_DOM_NODE (next_blockquote),
+                                               WEBKIT_DOM_NODE (element),
+                                               NULL);
+                               }
                        }
-               }
 
-               /* Remove old blockquote */
-               remove_node (WEBKIT_DOM_NODE (element));
+                       /* Remove old blockquote */
+                       remove_node (WEBKIT_DOM_NODE (element));
 
-               e_html_editor_selection_restore_caret_position (selection);
-       } else {
-               command = E_HTML_EDITOR_VIEW_COMMAND_OUTDENT;
-               e_html_editor_selection_save (selection);
-               e_html_editor_view_exec_command (view, command, NULL);
+                       if (after_selection_end)
+                               goto out;
+               }
+               block = next_block;
        }
-
+ out:
        e_html_editor_view_force_spell_check (view);
 
-       if (has_selection)
-               e_html_editor_selection_restore (selection);
+       e_html_editor_selection_restore (selection);
 
        g_object_unref (view);
 


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