[evolution/wip/webkit-composer] EEditorWidget: Refactor the function to process the composer's content
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit-composer] EEditorWidget: Refactor the function to process the composer's content
- Date: Thu, 6 Feb 2014 09:33:33 +0000 (UTC)
commit e380a517c69224089c9406877aaa97f85218e0aa
Author: Tomas Popela <tpopela redhat com>
Date: Thu Feb 6 10:25:48 2014 +0100
EEditorWidget: Refactor the function to process the composer's content
Also fix some minor bugs i.e. hiding the caret position when saving
message as draft. Also the GRegexes used there were created and afterwards leaked
on every level of DOM tree.
composer/e-msg-composer.c | 2 +-
e-util/e-editor-widget.c | 296 ++++++++++++++++++++++++++++++++-------------
e-util/e-editor-widget.h | 2 +
3 files changed, 212 insertions(+), 88 deletions(-)
---
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 6bf17c4..93d766f 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -1221,7 +1221,7 @@ composer_build_message (EMsgComposer *composer,
e_editor_widget_embed_styles (editor_widget);
e_editor_selection_save_caret_position (selection);
- text = e_editor_widget_get_text_html (editor_widget);
+ text = e_editor_widget_get_text_html_for_drafts (editor_widget);
e_editor_widget_remove_embed_styles (editor_widget);
e_editor_selection_restore_caret_position (selection);
diff --git a/e-util/e-editor-widget.c b/e-util/e-editor-widget.c
index 488dea9..06d0f22 100644
--- a/e-util/e-editor-widget.c
+++ b/e-util/e-editor-widget.c
@@ -2621,28 +2621,44 @@ process_blockquote (WebKitDOMElement *blockquote)
}
static void
+remove_attributes (WebKitDOMElement *element)
+{
+ webkit_dom_element_remove_attribute (element, "class");
+ webkit_dom_element_remove_attribute (element, "id");
+ webkit_dom_element_remove_attribute (element, "name");
+ webkit_dom_element_remove_attribute (element, "x-evo-smiley");
+ webkit_dom_element_remove_attribute (element, "data-name");
+ webkit_dom_element_remove_attribute (element, "data-inline");
+}
+
+static void
process_elements (WebKitDOMNode *node,
- GString *buffer,
- gboolean process_nodes)
+ gboolean to_html,
+ gboolean changing_mode,
+ gboolean to_plain_text,
+ GString *buffer)
{
WebKitDOMNodeList *nodes;
gulong ii, length;
- GRegex *regex, *regex_hidden_space;
gchar *content;
+ g_warning ("%d%d%d", to_plain_text, to_html, changing_mode);
+
+ if (to_plain_text && !buffer)
+ return;
+
/* Skip signature */
if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evolution-signature")) {
- if (process_nodes) {
+ if (to_plain_text && !changing_mode)
g_string_append (buffer, "\n");
- element_remove_class (WEBKIT_DOM_ELEMENT (node), "-x-evolution-signature");
- } else
+ if (to_html)
+ remove_attributes (WEBKIT_DOM_ELEMENT (node));
+ if (changing_mode)
return;
}
nodes = webkit_dom_node_get_child_nodes (node);
length = webkit_dom_node_list_get_length (nodes);
- regex = g_regex_new ("\x9", 0, 0, NULL);
- regex_hidden_space = g_regex_new (UNICODE_ZERO_WIDTH_SPACE, 0, 0, NULL);
for (ii = 0; ii < length; ii++) {
WebKitDOMNode *child;
@@ -2651,37 +2667,58 @@ process_elements (WebKitDOMNode *node,
child = webkit_dom_node_list_item (nodes, ii);
if (WEBKIT_DOM_IS_TEXT (child)) {
gchar *content, *tmp;
+ GRegex *regex;
content = webkit_dom_node_get_text_content (child);
-
/* Replace tabs with 4 whitespaces, otherwise they got
* replaced by single whitespace */
- tmp = g_regex_replace (
- regex, content, -1, 0, " ",
- 0, NULL);
+ if (strstr (content, "\x9")) {
+ regex = g_regex_new ("\x9", 0, 0, NULL);
+ tmp = g_regex_replace (
+ regex, content, -1, 0, " ", 0, NULL);
+ webkit_dom_node_set_text_content (child, tmp, NULL);
+ g_free (content);
+ g_free (tmp);
+ content = webkit_dom_node_get_text_content (child);
+ g_regex_unref (regex);
+ }
- g_free (content);
+ if (strstr (content, UNICODE_ZERO_WIDTH_SPACE)) {
+ regex = g_regex_new (UNICODE_ZERO_WIDTH_SPACE, 0, 0, NULL);
+ tmp = g_regex_replace (
+ regex, content, -1, 0, "", 0, NULL);
+ g_free (content);
+ g_free (tmp);
+ content = webkit_dom_node_get_text_content (child);
+ g_regex_unref (regex);
+ }
- content = g_regex_replace (
- regex_hidden_space, tmp, -1, 0, "", 0, NULL);
+ if (to_plain_text || changing_mode)
+ g_string_append (buffer, content);
- g_string_append (buffer, content);
- g_free (tmp);
g_free (content);
} else if (!WEBKIT_DOM_IS_COMMENT (child)) {
/* Leave caret position untouched */
if (element_has_id (WEBKIT_DOM_ELEMENT (child), "-x-evo-caret-position")) {
- if (!process_nodes) {
- content = webkit_dom_html_element_get_outer_html
(WEBKIT_DOM_HTML_ELEMENT (child));
+ if (changing_mode && to_plain_text) {
+ content = webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (child));
g_string_append (buffer, content);
g_free (content);
}
+ if (to_html) {
+ webkit_dom_node_remove_child (
+ webkit_dom_node_get_parent_node (child),
+ child,
+ NULL);
+ }
+
skip_node = TRUE;
}
/* Leave blockquotes as they are */
if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (child)) {
- if (!process_nodes) {
+ if (changing_mode && to_plain_text) {
content = webkit_dom_html_element_get_outer_html
(WEBKIT_DOM_HTML_ELEMENT (child));
g_string_append (buffer, content);
g_free (content);
@@ -2690,49 +2727,83 @@ process_elements (WebKitDOMNode *node,
process_blockquote (WEBKIT_DOM_ELEMENT (child));
}
- /* Leave wrapped paragraphs as they are */
+ if (WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (child)) {
+ if (to_html)
+ remove_attributes (WEBKIT_DOM_ELEMENT (child));
+ }
+
+ /* Leave paragraphs as they are */
if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-paragraph")) {
- if (!process_nodes) {
+ if (changing_mode && to_plain_text) {
content = webkit_dom_html_element_get_outer_html
(WEBKIT_DOM_HTML_ELEMENT (child));
g_string_append (buffer, content);
g_free (content);
skip_node = TRUE;
}
+ if (to_html)
+ remove_attributes (WEBKIT_DOM_ELEMENT (node));
}
/* Replace smileys with their text representation */
if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
- if (!process_nodes) {
+ if (to_plain_text && !changing_mode) {
WebKitDOMNode *text_version;
text_version = webkit_dom_node_get_last_child (child);
- content = webkit_dom_html_element_get_inner_text
(WEBKIT_DOM_HTML_ELEMENT (text_version));
+ content = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (text_version));
g_string_append (buffer, content);
g_free (content);
skip_node = TRUE;
}
+ if (to_html) {
+ WebKitDOMElement *img;
+
+ img = WEBKIT_DOM_ELEMENT (
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (child)));
+
+ remove_attributes (img);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (
+ child),
+ WEBKIT_DOM_NODE (img),
+ child,
+ NULL);
+ webkit_dom_node_remove_child (
+ webkit_dom_node_get_parent_node (
+ child),
+ child,
+ NULL);
+ skip_node = TRUE;
+ }
}
/* Leave PRE elements untouched */
if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (child)) {
- if (!process_nodes) {
+ if (changing_mode && to_plain_text) {
content = webkit_dom_html_element_get_outer_html
(WEBKIT_DOM_HTML_ELEMENT (child));
g_string_append (buffer, content);
g_free (content);
skip_node = TRUE;
}
+ if (to_html)
+ remove_attributes (WEBKIT_DOM_ELEMENT (child));
}
- /* Insert new line when we hit BR element */
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
- g_string_append (buffer, process_nodes ? "\n" : "<br>");
+ if (to_plain_text) {
+ /* Insert new line when we hit BR element */
+ if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
+ g_string_append (buffer, changing_mode ? "<br>" : "\n");
+ }
}
if (webkit_dom_node_has_child_nodes (child) && !skip_node)
- process_elements (child, buffer, process_nodes);
+ process_elements (child, to_html, changing_mode, to_plain_text, buffer);
}
- if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) || WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (node)) {
+ if (to_plain_text && (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) || WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT
(node))) {
gboolean add_br = TRUE;
WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
@@ -2750,31 +2821,12 @@ process_elements (WebKitDOMNode *node,
}
content = webkit_dom_node_get_text_content (node);
- if (add_br && g_utf8_strlen (content, -1) > 0) {
- g_string_append (buffer, process_nodes ? "\n" : "<br>");
- }
+ if (add_br && g_utf8_strlen (content, -1) > 0)
+ g_string_append (buffer, changing_mode ? "<br>" : "\n");
+
g_free (content);
}
- g_regex_unref (regex);
- g_regex_unref (regex_hidden_space);
-}
-
-static gchar *
-changing_composer_mode_get_text_plain (EEditorWidget *widget)
-{
- WebKitDOMDocument *document;
- WebKitDOMNode *body;
- GString *plain_text;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
- body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
-
- plain_text = g_string_sized_new (1024);
- process_elements (body, plain_text, FALSE);
-
- /* Return text content between <body> and </body> */
- return g_string_free (plain_text, FALSE);
}
static void
@@ -2848,6 +2900,87 @@ toggle_paragraphs_style (EEditorWidget *widget)
}
}
+static gchar *
+process_dom_document_for_saving_as_draft (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-caret-position");
+
+ if (element)
+ webkit_dom_element_set_attribute (
+ element, "style", "display: none; color: red;", NULL);
+
+ element = webkit_dom_document_get_document_element (document);
+ return webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+}
+
+static gchar *
+process_dom_document_for_mode_change (WebKitDOMDocument *document)
+{
+ WebKitDOMNode *body;
+ GString *plain_text;
+
+ body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+
+ plain_text = g_string_sized_new (1024);
+ process_elements (body, FALSE, TRUE, TRUE, plain_text);
+
+ return g_string_free (plain_text, FALSE);
+}
+
+static gchar *
+process_dom_document_for_plain_text (EEditorWidget *widget,
+ WebKitDOMDocument *document)
+{
+ WebKitDOMNode *body;
+ WebKitDOMNode *body_clone;
+ WebKitDOMNodeList *paragraphs;
+ gint length, ii;
+ GString *plain_text;
+
+ plain_text = g_string_sized_new (1024);
+
+ body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+ body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+ paragraphs = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (body_clone),
+ ".-x-evo-paragraph",
+ NULL);
+
+ length = webkit_dom_node_list_get_length (paragraphs);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *paragraph;
+
+ paragraph = webkit_dom_node_list_item (paragraphs, ii);
+
+ e_editor_selection_wrap_paragraph (
+ e_editor_widget_get_selection (widget),
+ WEBKIT_DOM_ELEMENT (paragraph));
+ }
+
+ process_elements (body_clone, FALSE, FALSE, TRUE, plain_text);
+
+ /* Return text content between <body> and </body> */
+ return g_string_free (plain_text, FALSE);
+}
+
+static gchar *
+process_dom_document_for_html (WebKitDOMDocument *document)
+{
+ WebKitDOMNode *body;
+ WebKitDOMElement *element;
+
+ body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+ process_elements (body, TRUE, FALSE, FALSE, NULL);
+ element = webkit_dom_document_get_document_element (document);
+ return webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+}
+
/**
* e_editor_widget_set_html_mode:
* @widget: an #EEditorWidget
@@ -2933,7 +3066,7 @@ e_editor_widget_set_html_mode (EEditorWidget *widget,
toggle_paragraphs_style (widget);
toggle_smileys (widget);
- plain = changing_composer_mode_get_text_plain (widget);
+ plain = process_dom_document_for_mode_change (document);
if (*plain)
webkit_web_view_load_string (
@@ -3079,7 +3212,8 @@ e_editor_widget_get_spell_checker (EEditorWidget *widget)
* e_editor_widget_get_text_html:
* @widget: an #EEditorWidget:
*
- * Returns HTML content of the editor document.
+ * Returns processed HTML content of the editor document (with elements attributes
+ * used in Evolution composer)
*
* Returns: A newly allocated string
*/
@@ -3087,12 +3221,28 @@ gchar *
e_editor_widget_get_text_html (EEditorWidget *widget)
{
WebKitDOMDocument *document;
- WebKitDOMElement *element;
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
- element = webkit_dom_document_get_document_element (document);
- return webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (element));
+ change_images_http_src_to_evo_http (widget, FALSE);
+ return process_dom_document_for_html (document);
+}
+
+/**
+ * e_editor_widget_get_text_html_for_drafts:
+ * @widget: an #EEditorWidget:
+ *
+ * Returns HTML content of the editor document (without elements attributes
+ * used in Evolution composer)
+ *
+ * Returns: A newly allocated string
+ */
+gchar *
+e_editor_widget_get_text_html_for_drafts (EEditorWidget *widget)
+{
+ WebKitDOMDocument *document;
+
+ document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
+ return process_dom_document_for_saving_as_draft (document);
}
/**
@@ -3109,38 +3259,10 @@ gchar *
e_editor_widget_get_text_plain (EEditorWidget *widget)
{
WebKitDOMDocument *document;
- WebKitDOMNode *body;
- WebKitDOMNode *body_clone;
- WebKitDOMNodeList *paragraphs;
- gint length, ii;
- GString *plain_text;
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (widget));
- body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
- body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
- plain_text = g_string_sized_new (1024);
-
- paragraphs = webkit_dom_element_query_selector_all (
- WEBKIT_DOM_ELEMENT (body_clone),
- ".-x-evo-paragraph",
- NULL);
-
- length = webkit_dom_node_list_get_length (paragraphs);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *paragraph;
- paragraph = webkit_dom_node_list_item (paragraphs, ii);
-
- e_editor_selection_wrap_paragraph (
- e_editor_widget_get_selection (widget),
- WEBKIT_DOM_ELEMENT (paragraph));
- }
-
- process_elements (body_clone, plain_text, TRUE);
-
- /* Return text content between <body> and </body> */
- return g_string_free (plain_text, FALSE);
+ return process_dom_document_for_plain_text (widget, document);
}
static void
diff --git a/e-util/e-editor-widget.h b/e-util/e-editor-widget.h
index 2b1a603..7f4769a 100644
--- a/e-util/e-editor-widget.h
+++ b/e-util/e-editor-widget.h
@@ -104,6 +104,8 @@ void e_editor_widget_set_magic_smileys
ESpellChecker * e_editor_widget_get_spell_checker
(EEditorWidget *widget);
gchar * e_editor_widget_get_text_html (EEditorWidget *widget);
+gchar * e_editor_widget_get_text_html_for_drafts
+ (EEditorWidget *widget);
gchar * e_editor_widget_get_text_plain (EEditorWidget *widget);
void e_editor_widget_set_text_html (EEditorWidget *widget,
const gchar *text);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]