diff options
author | Tomas Popela <tpopela@redhat.com> | 2014-08-14 21:11:53 +0800 |
---|---|---|
committer | Tomas Popela <tpopela@redhat.com> | 2014-08-14 21:11:53 +0800 |
commit | 32f222cadb2fed88f111eeb1622802ab684662b2 (patch) | |
tree | 6bbbf025c49d9fc3ea182d8b7dca1f93e1779532 | |
parent | a1ea8e92718f342daa0e0dec3d3a0622d1127e3f (diff) | |
download | gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar.gz gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar.bz2 gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar.lz gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar.xz gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.tar.zst gsoc2013-evolution-32f222cadb2fed88f111eeb1622802ab684662b2.zip |
EHTMLEditor - Change the way how the Indent/Unindent and Alignment works
Before this change the indent was done with BLOCKQUOTE element. But the
BLOCKQUOTE elements have marings around them set by the HTML engine.
For composer we can override them, but when someone will receive that
HTML message he will have unwanted margin around them. To solve this we
will use the DIV elements instead.
Also for the alignment we switched away from WebKit Editor, but we are
doing it ourselves.
-rw-r--r-- | e-util/e-html-editor-selection.c | 200 | ||||
-rw-r--r-- | e-util/e-html-editor-view.c | 46 |
2 files changed, 157 insertions, 89 deletions
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c index ee9937fa7b..5141b08956 100644 --- a/e-util/e-html-editor-selection.c +++ b/e-util/e-html-editor-selection.c @@ -1303,6 +1303,41 @@ format_change_list_from_list (EHTMLEditorSelection *selection, remove_node (source_list); } +static gboolean +node_is_list_or_item (WebKitDOMNode *node) +{ + return node && ( + WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (node) || + WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (node) || + WEBKIT_DOM_IS_HTMLLI_ELEMENT (node)); +} + +static gboolean +node_is_list (WebKitDOMNode *node) +{ + return node && ( + WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (node) || + WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (node)); +} + +static void +set_block_alignment (WebKitDOMElement *element, + const gchar *class) +{ + WebKitDOMElement *parent; + + element_remove_class (element, "-x-evo-align-center"); + element_remove_class (element, "-x-evo-align-right"); + element_add_class (element, class); + parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element)); + while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) { + element_remove_class (parent, "-x-evo-align-center"); + element_remove_class (parent, "-x-evo-align-right"); + parent = webkit_dom_node_get_parent_element ( + WEBKIT_DOM_NODE (parent)); + } +} + /** * e_html_editor_selection_set_alignment: * @selection: an #EHTMLEditorSelection @@ -1315,11 +1350,11 @@ e_html_editor_selection_set_alignment (EHTMLEditorSelection *selection, EHTMLEditorSelectionAlignment alignment) { EHTMLEditorView *view; - EHTMLEditorViewCommand command; - const gchar *class = ""; + gboolean after_selection_end = FALSE; + const gchar *class = "", *list_class = ""; WebKitDOMDocument *document; - WebKitDOMElement *selection_start_marker; - WebKitDOMNode *parent; + WebKitDOMElement *selection_start_marker, *selection_end_marker; + WebKitDOMNode *block; g_return_if_fail (E_IS_HTML_EDITOR_SELECTION (selection)); @@ -1328,17 +1363,16 @@ e_html_editor_selection_set_alignment (EHTMLEditorSelection *selection, switch (alignment) { case E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER: - command = E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_CENTER; - class = "-x-evo-list-item-align-center"; + class = "-x-evo-align-center"; + list_class = "-x-evo-list-item-align-center"; break; case E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT: - command = E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_LEFT; break; case E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT: - command = E_HTML_EDITOR_VIEW_COMMAND_JUSTIFY_RIGHT; - class = "-x-evo-list-item-align-right"; + class = "-x-evo-align-right"; + list_class = "-x-evo-list-item-align-right"; break; } @@ -1353,26 +1387,72 @@ e_html_editor_selection_set_alignment (EHTMLEditorSelection *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 (!selection_start_marker) { g_object_unref (view); return; } - parent = webkit_dom_node_get_parent_node ( + block = webkit_dom_node_get_parent_node ( WEBKIT_DOM_NODE (selection_start_marker)); - if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (parent)) { - element_remove_class ( - WEBKIT_DOM_ELEMENT (parent), - "-x-evo-list-item-align-center"); - element_remove_class ( - WEBKIT_DOM_ELEMENT (parent), - "-x-evo-list-item-align-right"); + while (block && !after_selection_end) { + WebKitDOMNode *next_block; - element_add_class (WEBKIT_DOM_ELEMENT (parent), class); - } else { - e_html_editor_view_exec_command (view, command, NULL); + next_block = webkit_dom_node_get_next_sibling (block); + + after_selection_end = webkit_dom_node_contains ( + block, WEBKIT_DOM_NODE (selection_end_marker)); + + if (node_is_list (block)) { + WebKitDOMNode *item = webkit_dom_node_get_first_child (block); + + while (item && WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) { + element_remove_class ( + WEBKIT_DOM_ELEMENT (item), + "-x-evo-list-item-align-center"); + element_remove_class ( + WEBKIT_DOM_ELEMENT (item), + "-x-evo-list-item-align-right"); + + element_add_class (WEBKIT_DOM_ELEMENT (item), list_class); + after_selection_end = webkit_dom_node_contains ( + item, WEBKIT_DOM_NODE (selection_end_marker)); + if (after_selection_end) + break; + item = webkit_dom_node_get_next_sibling (item); + } + } else { + if (element_has_class (WEBKIT_DOM_ELEMENT (block), "-x-evo-indented")) { + gint ii, length; + WebKitDOMNodeList *list; + + list = webkit_dom_element_query_selector_all ( + WEBKIT_DOM_ELEMENT (block), + ".-x-evo-indented > *:not(.-x-evo-indented):not(li)", + NULL); + length = webkit_dom_node_list_get_length (list); + + for (ii = 0; ii < length; ii++) { + WebKitDOMNode *item = webkit_dom_node_list_item (list, ii); + + set_block_alignment (WEBKIT_DOM_ELEMENT (item), class); + + after_selection_end = webkit_dom_node_contains ( + item, WEBKIT_DOM_NODE (selection_end_marker)); + if (after_selection_end) + break; + } + + g_object_unref (list); + } else { + set_block_alignment (WEBKIT_DOM_ELEMENT (block), class); + } + } + + block = next_block; } e_html_editor_selection_restore (selection); @@ -1709,23 +1789,6 @@ remove_quoting_from_element (WebKitDOMElement *element) webkit_dom_node_normalize (WEBKIT_DOM_NODE (element)); } -static gboolean -node_is_list_or_item (WebKitDOMNode *node) -{ - return node && ( - WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (node) || - WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (node) || - WEBKIT_DOM_IS_HTMLLI_ELEMENT (node)); -} - -static gboolean -node_is_list (WebKitDOMNode *node) -{ - return node && ( - WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (node) || - WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (node)); -} - static gint get_citation_level (WebKitDOMNode *node) { @@ -2901,16 +2964,16 @@ e_html_editor_selection_indent (EHTMLEditorSelection *selection) } static const gchar * -get_css_alignment_value (EHTMLEditorSelectionAlignment alignment) +get_css_alignment_value_class (EHTMLEditorSelectionAlignment alignment) { if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) return ""; /* Left is by default on ltr */ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) - return "text-align: center;"; + return "-x-evo-align-center"; if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) - return "text-align: right;"; + return "-x-evo-align-right"; return ""; } @@ -2991,7 +3054,6 @@ unindent_block (EHTMLEditorSelection *selection, WebKitDOMNode *block) { gboolean before_node = TRUE; - const gchar *align_value; gint word_wrap_length = selection->priv->word_wrap_length; gint level, width; EHTMLEditorSelectionAlignment alignment; @@ -3002,11 +3064,11 @@ unindent_block (EHTMLEditorSelection *selection, block_to_process = block; alignment = e_html_editor_selection_get_alignment_from_node (block_to_process); - align_value = get_css_alignment_value (alignment); element = webkit_dom_node_get_parent_element (block_to_process); - if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (element)) + if (!WEBKIT_DOM_IS_HTML_DIV_ELEMENT (element) && + !element_has_class (element, "-x-evo-indented")) return; element_add_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-to-unindent"); @@ -3056,9 +3118,13 @@ unindent_block (EHTMLEditorSelection *selection, } } - if (level == 1 && element_has_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-paragraph")) + 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); + selection, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, ""); + element_add_class ( + WEBKIT_DOM_ELEMENT (node_clone), + get_css_alignment_value_class (alignment)); + } /* Insert the unindented element */ webkit_dom_node_insert_before ( @@ -5418,39 +5484,17 @@ e_html_editor_selection_set_indented_style (EHTMLEditorSelection *selection, WebKitDOMElement *element, gint width) { - EHTMLEditorSelectionAlignment alignment; gchar *style; - const gchar *align_value; gint word_wrap_length = (width == -1) ? selection->priv->word_wrap_length : width; - gint start = 0, end = 0; - - alignment = e_html_editor_selection_get_alignment (selection); - align_value = get_css_alignment_value (alignment); - - if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) - start = SPACES_PER_INDENTATION; - - if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) { - start = SPACES_PER_INDENTATION; - } - - if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) { - start = 0; - end = SPACES_PER_INDENTATION; - } webkit_dom_element_set_class_name (element, "-x-evo-indented"); - /* We don't want vertical space bellow and above blockquote inserted by - * WebKit's User Agent Stylesheet. We have to override it through style attribute. */ + if (is_in_html_mode (selection)) - style = g_strdup_printf ( - "-webkit-margin-start: %dch; -webkit-margin-end : %dch; %s", - start, end, align_value); + style = g_strdup_printf ("margin-left: %dch;", SPACES_PER_INDENTATION); else style = g_strdup_printf ( - "-webkit-margin-start: %dch; -webkit-margin-end : %dch; " - "word-wrap: normal; width: %dch; %s", - start, end, word_wrap_length, align_value); + "margin-left: %dch; word-wrap: normal; width: %dch;", + SPACES_PER_INDENTATION, word_wrap_length); webkit_dom_element_set_attribute (element, "style", style, NULL); g_free (style); @@ -5463,7 +5507,7 @@ e_html_editor_selection_get_indented_element (EHTMLEditorSelection *selection, { WebKitDOMElement *element; - element = webkit_dom_document_create_element (document, "BLOCKQUOTE", NULL); + element = webkit_dom_document_create_element (document, "DIV", NULL); e_html_editor_selection_set_indented_style (selection, element, width); return element; @@ -5477,22 +5521,20 @@ e_html_editor_selection_set_paragraph_style (EHTMLEditorSelection *selection, const gchar *style_to_add) { EHTMLEditorSelectionAlignment alignment; - const gchar *align_value = NULL; char *style = NULL; gint word_wrap_length = (width == -1) ? selection->priv->word_wrap_length : width; alignment = e_html_editor_selection_get_alignment (selection); - align_value = get_css_alignment_value (alignment); element_add_class (element, "-x-evo-paragraph"); + element_add_class (element, get_css_alignment_value_class (alignment)); if (!is_in_html_mode (selection)) { style = g_strdup_printf ( - "width: %dch; word-wrap: normal; %s %s", - (word_wrap_length + offset), align_value, style_to_add); + "width: %dch; word-wrap: normal; %s", + (word_wrap_length + offset), style_to_add); } else { - if (*align_value || *style_to_add) - style = g_strdup_printf ( - "%s %s", align_value, style_to_add); + if (*style_to_add) + style = g_strdup_printf ("%s", style_to_add); } if (style) { webkit_dom_element_set_attribute (element, "style", style, NULL); diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c index 8db6b6b909..0b3212c184 100644 --- a/e-util/e-html-editor-view.c +++ b/e-util/e-html-editor-view.c @@ -5621,7 +5621,7 @@ process_elements (EHTMLEditorView *view, } if (to_plain_text && !changing_mode) { - gchar *style; + gchar *class; const gchar *css_align; if (strstr (content, UNICODE_NBSP)) { @@ -5634,10 +5634,8 @@ process_elements (EHTMLEditorView *view, content = g_string_free (nbsp_free, FALSE); } - style = webkit_dom_element_get_attribute ( - WEBKIT_DOM_ELEMENT (node), "style"); - - if ((css_align = strstr (style, "text-align: "))) { + class = webkit_dom_element_get_class_name (WEBKIT_DOM_ELEMENT (node)); + if ((css_align = strstr (class, "-x-evo-align-"))) { gchar *align; gchar *content_with_align; gint length; @@ -5645,12 +5643,15 @@ process_elements (EHTMLEditorView *view, e_html_editor_selection_get_word_wrap_length ( e_html_editor_view_get_selection (view)); - if (!g_str_has_prefix (css_align + 12, "left")) { - if (g_str_has_prefix (css_align + 12, "center")) + if (!g_str_has_prefix (css_align + 13, "left")) { + if (g_str_has_prefix (css_align + 13, "center")) length = (word_wrap_length - g_utf8_strlen (content, -1)) / 2; else length = word_wrap_length - g_utf8_strlen (content, -1); + if (length < 0) + length = 0; + if (g_str_has_suffix (content, " ")) { char *tmp; @@ -5675,7 +5676,7 @@ process_elements (EHTMLEditorView *view, } } - g_free (style); + g_free (class); } if (to_plain_text || changing_mode) @@ -5776,6 +5777,10 @@ process_elements (EHTMLEditorView *view, } } + if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) && + element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented")) + process_blockquote (WEBKIT_DOM_ELEMENT (child)); + if (WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (child) || WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (child)) { if (to_plain_text) { @@ -6426,7 +6431,7 @@ process_content_for_plain_text (EHTMLEditorView *view) } paragraphs = webkit_dom_element_query_selector_all ( - WEBKIT_DOM_ELEMENT (source), "body > .-x-evo-paragraph", NULL); + WEBKIT_DOM_ELEMENT (source), ".-x-evo-paragraph", NULL); length = webkit_dom_node_list_get_length (paragraphs); for (ii = 0; ii < length; ii++) { @@ -7287,7 +7292,28 @@ e_html_editor_view_update_fonts (EHTMLEditorView *view) g_string_append ( stylesheet, - ".-x-evo-list-item-alignt-left " + ".-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, + ".-x-evo-list-item-align-left " "{\n" " text-align: left; \n" "}\n"); |