[evolution/wip/webkit2] Commit the word before sync with master
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Commit the word before sync with master
- Date: Thu, 27 Nov 2014 17:05:53 +0000 (UTC)
commit f966e1e0f6365074406ca1fb7bbd6f3fffb639d2
Author: Tomas Popela <tpopela redhat com>
Date: Thu Nov 27 16:10:30 2014 +0100
Commit the word before sync with master
e-util/e-dom-utils.c | 14 +-
e-util/e-html-editor-selection-dom-functions.c | 441 +-
e-util/e-html-editor-selection-dom-functions.h | 66 +-
e-util/e-html-editor-selection.c | 14 +-
e-util/e-html-editor-view-dom-functions.c | 4934 ++++++++++++++++++
e-util/e-html-editor-view-dom-functions.h | 16 +
e-util/e-html-editor-view.c | 5244 ++------------------
e-util/e-html-editor.c | 12 +-
e-util/e-html-editor.h | 2 +-
e-util/web-extensions/Makefile.am | 3 +-
.../e-html-editor-web-extension-main.c | 51 +
.../e-html-editor-web-extension-names.h | 14 +-
.../web-extensions/e-html-editor-web-extension.c | 625 ++-
.../web-extensions/e-html-editor-web-extension.h | 104 +-
.../module-itip-formatter-web-extension.c | 8 +-
.../mail/web-extension/module-mail-web-extension.c | 4 +-
.../module-prefer-plain-web-extension.c | 4 +-
.../module-text-highlight-web-extension.c | 4 +-
web-extensions/Makefile.am | 5 +-
web-extensions/e-web-extension-main.c | 51 +
...evolution-web-extension.c => e-web-extension.c} | 564 ++-
web-extensions/e-web-extension.h | 76 +
22 files changed, 6664 insertions(+), 5592 deletions(-)
---
diff --git a/e-util/e-dom-utils.c b/e-util/e-dom-utils.c
index 6981d05..871aab5 100644
--- a/e-util/e-dom-utils.c
+++ b/e-util/e-dom-utils.c
@@ -23,7 +23,7 @@
#include <webkitdom/WebKitDOMDOMWindowUnstable.h>
#include <webkitdom/WebKitDOMHTMLElementUnstable.h>
-#include "../web-extensions/evolution-web-extension.h"
+#include "../web-extensions/e-web-extension.h"
#include "e-misc-utils.h"
@@ -626,8 +626,8 @@ toggle_address_visibility (WebKitDOMElement *button,
g_dbus_connection_emit_signal (
connection,
NULL,
- EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
- EVOLUTION_WEB_EXTENSION_INTERFACE,
+ E_WEB_EXTENSION_OBJECT_PATH,
+ E_WEB_EXTENSION_INTERFACE,
"HeadersCollapsed",
g_variant_new ("(b)", expanded),
&error);
@@ -1190,8 +1190,8 @@ display_mode_toggle_button_cb (WebKitDOMElement *button,
g_dbus_connection_emit_signal (
connection,
NULL,
- EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
- EVOLUTION_WEB_EXTENSION_INTERFACE,
+ E_WEB_EXTENSION_OBJECT_PATH,
+ E_WEB_EXTENSION_INTERFACE,
"VCardInlineDisplayModeToggled",
g_variant_new ("(s)", element_id),
&error);
@@ -1218,8 +1218,8 @@ save_vcard_button_cb (WebKitDOMElement *button,
g_dbus_connection_emit_signal (
connection,
NULL,
- EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
- EVOLUTION_WEB_EXTENSION_INTERFACE,
+ E_WEB_EXTENSION_OBJECT_PATH,
+ E_WEB_EXTENSION_INTERFACE,
"VCardInlineSaveButtonPressed",
g_variant_new ("(s)", button_value),
&error);
diff --git a/e-util/e-html-editor-selection-dom-functions.c b/e-util/e-html-editor-selection-dom-functions.c
index 13359f9..d08f4c8 100644
--- a/e-util/e-html-editor-selection-dom-functions.c
+++ b/e-util/e-html-editor-selection-dom-functions.c
@@ -37,7 +37,6 @@
#define SPACES_PER_INDENTATION 4
#define SPACES_PER_LIST_LEVEL 8
#define MINIMAL_PARAGRAPH_WIDTH 5
-#define WORD_WRAP_LENGTH 71
static const GdkRGBA black = { 0, 0, 0, 1 };
@@ -131,17 +130,16 @@ dom_get_current_range (WebKitDOMDocument *document)
* #EHTMLEditorSelection and should not be free'd.
*/
gchar *
-dom_selection_get_string (WebKitDOMDocument *document)
+dom_selection_get_string (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
+ gchar *text;
WebKitDOMRange *range;
range = dom_get_current_range (document);
if (!range)
return NULL;
-/* FIXME WK2
- g_free (selection->priv->text);
- selection->priv->text = webkit_dom_range_get_text (range);
-*/
+
return webkit_dom_range_get_text (range);
}
@@ -496,32 +494,6 @@ get_list_format_from_node (WebKitDOMNode *node)
}
static gboolean
-is_in_html_mode (WebKitDOMDocument *document)
-{
- WebKitDOMElement *document_element;
-
- document_element = webkit_dom_document_get_document_element (document);
-
- return webkit_dom_element_has_attribute (document_element, "data-html-mode");
-
- /* FIXME WK2 we have to probably add a body attribute that shows,
- * whether the composer is in HTML mode */
- /*
- EHTMLEditorView *view = e_html_editor_selection_ref_html_editor_view (selection);
- gboolean ret_val;
-
- g_return_val_if_fail (view != NULL, FALSE);
-
- ret_val = e_html_editor_view_get_html_mode (view);
-
- g_object_unref (view);
-
- return ret_val;
- */
- return FALSE;
-}
-
-static gboolean
node_is_list_or_item (WebKitDOMNode *node)
{
return node && (
@@ -631,8 +603,17 @@ dom_get_alignment (WebKitDOMDocument *document)
return alignment;
}
+static gint
+set_word_wrap_length (EHTMLEditorWebExtension *extension,
+ gint user_word_wrap_length)
+{
+ return (user_word_wrap_length == -1) ?
+ e_html_editor_web_extension_get_word_wrap_length (extension) : user_word_wrap_length;
+}
+
static void
-dom_set_paragraph_style (WebKitDOMDocument *document,
+dom_set_paragraph_style (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMElement *element,
gint width,
gint offset,
@@ -640,13 +621,13 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
{
EHTMLEditorSelectionAlignment alignment;
char *style = NULL;
- gint word_wrap_length = (width == -1) ? WORD_WRAP_LENGTH : width;
+ gint word_wrap_length = set_word_wrap_length (extension, width);
alignment = dom_get_alignment (document);
element_add_class (element, "-x-evo-paragraph");
element_add_class (element, get_css_alignment_value_class (alignment));
- if (!is_in_html_mode (document)) {
+ if (!e_html_editor_web_extension_get_html_mode (extension)) {
style = g_strdup_printf (
"width: %dch; word-wrap: normal; %s",
(word_wrap_length + offset), style_to_add);
@@ -661,7 +642,8 @@ dom_set_paragraph_style (WebKitDOMDocument *document,
}
static WebKitDOMElement *
-create_list_element (WebKitDOMDocument *document,
+create_list_element (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
EHTMLEditorSelectionBlockFormat format,
gint level,
gboolean html_mode)
@@ -680,8 +662,7 @@ create_list_element (WebKitDOMDocument *document,
offset = (level + 1) * -SPACES_PER_LIST_LEVEL;
if (!html_mode)
- dom_set_paragraph_style (
- document, list, -1, offset, "");
+ dom_set_paragraph_style (extension, document, list, -1, offset, "");
return list;
}
@@ -751,7 +732,8 @@ merge_lists_if_possible (WebKitDOMNode *list)
}
static void
-indent_list (WebKitDOMDocument *document)
+indent_list (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
{
WebKitDOMElement *selection_start_marker, *selection_end_marker;
WebKitDOMNode *item, *next_item;
@@ -767,7 +749,7 @@ indent_list (WebKitDOMDocument *document)
WEBKIT_DOM_NODE (selection_start_marker));
if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
- gboolean html_mode = is_in_html_mode (document);
+ gboolean html_mode = e_html_editor_web_extension_get_html_mode (extension);
WebKitDOMElement *list;
WebKitDOMNode *source_list = webkit_dom_node_get_parent_node (item);
EHTMLEditorSelectionBlockFormat format;
@@ -775,7 +757,7 @@ indent_list (WebKitDOMDocument *document)
format = get_list_format_from_node (source_list);
list = create_list_element (
- document, format, get_list_level (item), html_mode);
+ extension, document, format, get_list_level (item), html_mode);
element_add_class (list, "-x-evo-indented");
@@ -799,16 +781,17 @@ indent_list (WebKitDOMDocument *document)
}
static void
-dom_set_indented_style (WebKitDOMDocument *document,
+dom_set_indented_style (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMElement *element,
gint width)
{
gchar *style;
- gint word_wrap_length = (width == -1) ? WORD_WRAP_LENGTH : width;
+ gint word_wrap_length = set_word_wrap_length (extension, width);
webkit_dom_element_set_class_name (element, "-x-evo-indented");
- if (is_in_html_mode (document))
+ if (e_html_editor_web_extension_get_html_mode (extension))
style = g_strdup_printf ("margin-left: %dch;", SPACES_PER_INDENTATION);
else
style = g_strdup_printf (
@@ -820,25 +803,27 @@ dom_set_indented_style (WebKitDOMDocument *document,
}
static WebKitDOMElement *
-dom_get_indented_element (WebKitDOMDocument *document,
+dom_get_indented_element (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
gint width)
{
WebKitDOMElement *element;
element = webkit_dom_document_create_element (document, "DIV", NULL);
- dom_set_indented_style (document, element, width);
+ dom_set_indented_style (extension, document, element, width);
return element;
}
static void
-indent_block (WebKitDOMDocument *document,
+indent_block (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMNode *block,
gint width)
{
WebKitDOMElement *element;
- element = dom_get_indented_element (document, width);
+ element = dom_get_indented_element (extension, document, width);
webkit_dom_node_insert_before (
webkit_dom_node_get_parent_node (block),
@@ -991,7 +976,8 @@ add_selection_markers_into_element_start (WebKitDOMDocument *document,
* Indents current paragraph by one level.
*/
static void
-dom_indent (WebKitDOMDocument *document)
+dom_indent (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
{
gboolean after_selection_start = FALSE, after_selection_end = FALSE;
WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -1027,11 +1013,12 @@ dom_indent (WebKitDOMDocument *document)
WEBKIT_DOM_NODE (selection_start_marker));
while (block && !after_selection_end) {
- gint ii, length, level, final_width = 0;
- gint word_wrap_length = WORD_WRAP_LENGTH;
+ gint ii, length, level, word_wrap_length, final_width = 0;
WebKitDOMNode *next_block;
WebKitDOMNodeList *list;
+ word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
next_block = webkit_dom_node_get_next_sibling (block);
list = webkit_dom_element_query_selector_all (
@@ -1044,7 +1031,7 @@ dom_indent (WebKitDOMDocument *document)
length = webkit_dom_node_list_get_length (list);
if (length == 0 && node_is_list_or_item (block)) {
- indent_list (document);
+ indent_list (extension, document);
goto next;
}
@@ -1060,10 +1047,10 @@ dom_indent (WebKitDOMDocument *document)
final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
if (final_width < MINIMAL_PARAGRAPH_WIDTH &&
- !is_in_html_mode (document))
+ !e_html_editor_web_extension_get_html_mode (extension))
goto next;
- indent_block (document, block, final_width);
+ indent_block (extension, document, block, final_width);
if (after_selection_end)
goto next;
@@ -1090,10 +1077,10 @@ dom_indent (WebKitDOMDocument *document)
final_width = word_wrap_length - SPACES_PER_INDENTATION * (level + 1);
if (final_width < MINIMAL_PARAGRAPH_WIDTH &&
- !is_in_html_mode (document))
+ !e_html_editor_web_extension_get_html_mode (extension))
continue;
- indent_block (document, block_to_process, final_width);
+ indent_block (extension, document, block_to_process, final_width);
if (after_selection_end)
break;
@@ -1107,9 +1094,9 @@ dom_indent (WebKitDOMDocument *document)
}
dom_selection_restore (document);
- /* FIXME WK2
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
+ dom_force_spell_check_for_current_paragraph (document);
+ /* FIXME WK2
g_object_notify (G_OBJECT (selection), "indented"); */
}
@@ -1183,12 +1170,12 @@ unindent_list (WebKitDOMDocument *document)
}
static void
-unindent_block (WebKitDOMDocument *document,
+unindent_block (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMNode *block)
{
gboolean before_node = TRUE;
- gint word_wrap_length = WORD_WRAP_LENGTH;
- gint level, width;
+ gint word_wrap_length, level, width;
EHTMLEditorSelectionAlignment alignment;
WebKitDOMElement *element;
WebKitDOMElement *prev_blockquote = NULL, *next_blockquote = NULL;
@@ -1207,19 +1194,18 @@ unindent_block (WebKitDOMDocument *document,
element_add_class (WEBKIT_DOM_ELEMENT (block_to_process), "-x-evo-to-unindent");
level = get_indentation_level (element);
+ word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
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 = dom_get_indented_element (
- document, width);
+ prev_blockquote = dom_get_indented_element (extension, 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 = dom_get_indented_element (
- document, width);
+ next_blockquote = dom_get_indented_element (extension, 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)))) {
@@ -1253,7 +1239,7 @@ unindent_block (WebKitDOMDocument *document,
if (level == 1 && element_has_class (WEBKIT_DOM_ELEMENT (node_clone), "-x-evo-paragraph")) {
dom_set_paragraph_style (
- document, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, "");
+ extension, document, WEBKIT_DOM_ELEMENT (node_clone), word_wrap_length, 0, "");
element_add_class (
WEBKIT_DOM_ELEMENT (node_clone),
get_css_alignment_value_class (alignment));
@@ -1288,7 +1274,8 @@ unindent_block (WebKitDOMDocument *document,
* Unindents current paragraph by one level.
*/
static void
-dom_unindent (WebKitDOMDocument *document)
+dom_unindent (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
{
gboolean after_selection_start = FALSE, after_selection_end = FALSE;
WebKitDOMElement *selection_start_marker, *selection_end_marker;
@@ -1365,7 +1352,7 @@ dom_unindent (WebKitDOMDocument *document)
goto next;
}
- unindent_block (document, block);
+ unindent_block (extension, document, block);
if (after_selection_end)
goto next;
@@ -1388,7 +1375,7 @@ dom_unindent (WebKitDOMDocument *document)
continue;
}
- unindent_block (document, block_to_process);
+ unindent_block (extension, document, block_to_process);
if (after_selection_end)
break;
@@ -1399,10 +1386,11 @@ dom_unindent (WebKitDOMDocument *document)
}
dom_selection_restore (document);
-/* FIXME WK2
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
- g_object_notify (G_OBJECT (selection), "indented"); */
+ dom_force_spell_check_for_current_paragraph (document);
+
+ /* FIXME XXX - Check if the block is still indented */
+ set_dbus_property_boolean (extension, "Indented", TRUE);
}
static WebKitDOMNode *
@@ -1909,30 +1897,28 @@ dom_scroll_to_caret (WebKitDOMDocument *document)
* is selected, it will be replaced by @html_text.
*/
static void
-dom_insert_html (WebKitDOMDocument *document,
+dom_insert_html (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
const gchar *html_text)
{
g_return_if_fail (html_text != NULL);
- if (is_in_html_mode (document)) {
+ if (e_html_editor_web_extension_get_html_mode (extension)) {
dom_exec_command (
document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html_text);
/* FIXME WK2
e_html_editor_view_check_magic_links (view, FALSE);
- e_html_editor_view_force_spell_check (view);
*/
+ dom_force_spell_check (document);
dom_scroll_to_caret (document);
- }
-/* FIXME WK2
- else
- e_html_editor_view_convert_and_insert_html_to_plain_text (
- view, html_text);
-*/
+ } else
+ dom_convert_and_insert_html_into_selection (document, extension, html_text, TRUE);
}
static WebKitDOMElement *
-wrap_lines (WebKitDOMNode *paragraph,
- WebKitDOMDocument *document,
+wrap_lines (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
+ WebKitDOMNode *paragraph,
gboolean remove_all_br,
gint word_wrap_length)
{
@@ -1950,11 +1936,10 @@ wrap_lines (WebKitDOMNode *paragraph,
has_selection = !dom_selection_is_collapsed (document);
if (has_selection) {
- gchar *text_content;
+ const gchar *selection_content;
- text_content = dom_selection_get_string (document);
- paragraph_char_count = g_utf8_strlen (text_content, -1);
- g_free (text_content);
+ selection_content = e_html_editor_web_extension_get_selection_text (extension);
+ paragraph_char_count = g_utf8_strlen (selection_content, -1);
fragment = webkit_dom_range_clone_contents (
dom_get_current_range (document), NULL);
@@ -2303,7 +2288,7 @@ wrap_lines (WebKitDOMNode *paragraph,
html = webkit_dom_html_element_get_inner_html (WEBKIT_DOM_HTML_ELEMENT (element));
/* Overwrite the current selection be the processed content */
- dom_insert_html (document, html);
+ dom_insert_html (extension, document, html);
g_free (html);
@@ -2323,20 +2308,22 @@ wrap_lines (WebKitDOMNode *paragraph,
}
static WebKitDOMElement *
-dom_get_paragraph_element (WebKitDOMDocument *document,
+dom_get_paragraph_element (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
gint width,
gint offset)
{
WebKitDOMElement *element;
element = webkit_dom_document_create_element (document, "DIV", NULL);
- dom_set_paragraph_style (document, element, width, offset, "");
+ dom_set_paragraph_style (extension, document, element, width, offset, "");
return element;
}
static WebKitDOMElement *
-dom_put_node_into_paragraph (WebKitDOMDocument *document,
+dom_put_node_into_paragraph (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMNode *node,
WebKitDOMNode *caret_position)
{
@@ -2344,7 +2331,7 @@ dom_put_node_into_paragraph (WebKitDOMDocument *document,
WebKitDOMElement *container;
range = webkit_dom_document_create_range (document);
- container = dom_get_paragraph_element (document, -1, 0);
+ container = dom_get_paragraph_element (extension, document, -1, 0);
webkit_dom_range_select_node (range, node, NULL);
webkit_dom_range_surround_contents (range, WEBKIT_DOM_NODE (container), NULL);
/* We have to move caret position inside this container */
@@ -2359,13 +2346,17 @@ dom_put_node_into_paragraph (WebKitDOMDocument *document,
*
* Wraps all lines in current selection to be 71 characters long.
*/
-#if 0
-void
-dom_wrap_lines (WebKitDOMDocument *document)
+
+static void
+dom_wrap_lines (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
{
+ gint word_wrap_length;
WebKitDOMRange *range;
WebKitDOMElement *active_paragraph, *caret;
+ word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
caret = dom_save_caret_position (document);
if (dom_selection_is_collapsed (document)) {
WebKitDOMNode *end_container;
@@ -2408,7 +2399,9 @@ dom_wrap_lines (WebKitDOMDocument *document)
if (WEBKIT_DOM_IS_TEXT (paragraph))
paragraph = WEBKIT_DOM_NODE (
dom_put_node_into_paragraph (
- selection, document, paragraph,
+ extension,
+ document,
+ paragraph,
WEBKIT_DOM_NODE (caret)));
} else {
/* When some weird element is selected, return */
@@ -2455,16 +2448,13 @@ dom_wrap_lines (WebKitDOMDocument *document)
g_free (text_content);
wrap_lines (
- NULL, paragraph, document, FALSE,
- selection->priv->word_wrap_length);
+ extension, document, paragraph, FALSE, word_wrap_length);
} else {
dom_save_caret_position (document);
/* If we have selection -> wrap it */
wrap_lines (
- selection, NULL, document, FALSE,
- selection->priv->word_wrap_length);
- }
+ extension, document, NULL, FALSE, word_wrap_length); }
active_paragraph = webkit_dom_document_get_element_by_id (
document, "-x-evo-active-paragraph");
@@ -2476,16 +2466,17 @@ dom_wrap_lines (WebKitDOMDocument *document)
webkit_dom_element_remove_attribute (
WEBKIT_DOM_ELEMENT (active_paragraph), "id");
}
-#endif
+
static WebKitDOMElement *
-dom_wrap_paragraph_length (WebKitDOMDocument *document,
+dom_wrap_paragraph_length (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMElement *paragraph,
gint length)
{
g_return_val_if_fail (WEBKIT_DOM_IS_ELEMENT (paragraph), NULL);
g_return_val_if_fail (length >= MINIMAL_PARAGRAPH_WIDTH, NULL);
- return wrap_lines (WEBKIT_DOM_NODE (paragraph), document, FALSE, length);
+ return wrap_lines (extension, document, WEBKIT_DOM_NODE (paragraph), FALSE, length);
}
static gint
@@ -2506,7 +2497,8 @@ get_citation_level (WebKitDOMNode *node)
}
static void
-dom_wrap_paragraphs_in_document (WebKitDOMDocument *document)
+dom_wrap_paragraphs_in_document (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
{
WebKitDOMNodeList *list;
gint ii, length;
@@ -2517,34 +2509,36 @@ dom_wrap_paragraphs_in_document (WebKitDOMDocument *document)
length = webkit_dom_node_list_get_length (list);
for (ii = 0; ii < length; ii++) {
- gint quote, citation_level;
+ gint word_wrap_length, quote, citation_level;
WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
citation_level = get_citation_level (node);
quote = citation_level ? citation_level * 2 : 0;
+ word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
if (node_is_list (node)) {
WebKitDOMNode *item = webkit_dom_node_get_first_child (node);
while (item && WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
dom_wrap_paragraph_length (
- document, WEBKIT_DOM_ELEMENT (item), WORD_WRAP_LENGTH - quote);
+ extension, document, WEBKIT_DOM_ELEMENT (item), word_wrap_length -
quote);
item = webkit_dom_node_get_next_sibling (item);
}
} else {
dom_wrap_paragraph_length (
- document, WEBKIT_DOM_ELEMENT (node), WORD_WRAP_LENGTH - quote);
+ extension, document, WEBKIT_DOM_ELEMENT (node), word_wrap_length - quote);
}
}
g_object_unref (list);
}
static WebKitDOMElement *
-dom_wrap_paragraph (WebKitDOMDocument *document,
+dom_wrap_paragraph (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
WebKitDOMElement *paragraph)
{
gint indentation_level, citation_level, quote;
- gint final_width, offset = 0;
+ gint word_wrap_length, final_width, offset = 0;
g_return_val_if_fail (WEBKIT_DOM_IS_ELEMENT (paragraph), NULL);
@@ -2563,11 +2557,12 @@ dom_wrap_paragraph (WebKitDOMDocument *document,
quote = citation_level ? citation_level * 2 : 0;
- final_width = WORD_WRAP_LENGTH - quote + offset;
+ word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+ final_width = word_wrap_length - quote + offset;
final_width -= SPACES_PER_INDENTATION * indentation_level;
return dom_wrap_paragraph_length (
- document, WEBKIT_DOM_ELEMENT (paragraph), final_width);
+ extension, document, WEBKIT_DOM_ELEMENT (paragraph), final_width);
}
static void
@@ -2676,7 +2671,8 @@ get_has_style (WebKitDOMDocument *document,
* Returns @TRUE when selection is underlined, @FALSE otherwise.
*/
gboolean
-dom_selection_is_underline (WebKitDOMDocument *document)
+dom_selection_is_underline (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gboolean ret_val;
gchar *value, *text_content;
@@ -2698,9 +2694,7 @@ dom_selection_is_underline (WebKitDOMDocument *document)
text_content = webkit_dom_node_get_text_content (node);
if (g_strcmp0 (text_content, "") == 0) {
g_free (text_content);
- return FALSE;
-/* FIXME WK2
- return selection->priv->is_underline;*/
+ return e_html_editor_web_extension_get_underline (extension);
}
g_free (text_content);
@@ -2731,17 +2725,15 @@ dom_selection_is_underline (WebKitDOMDocument *document)
*/
void
dom_selection_set_underline (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean underline)
{
- if (dom_selection_is_underline (document) == underline)
+ if (dom_selection_is_underline (document, extension) == underline)
return;
-// selection->priv->is_underline = underline;
-
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_UNDERLINE, NULL);
-/* FIXME WK2
- g_object_notify (G_OBJECT (selection), "underline"); */
+ set_dbus_property_boolean (extension, "Underline", underline);
}
/**
@@ -2754,7 +2746,8 @@ dom_selection_set_underline (WebKitDOMDocument *document,
* Returns @TRUE when selection is in subscript, @FALSE otherwise.
*/
gboolean
-dom_selection_is_subscript (WebKitDOMDocument *document)
+dom_selection_is_subscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
WebKitDOMNode *node;
WebKitDOMRange *range;
@@ -2789,9 +2782,10 @@ dom_selection_is_subscript (WebKitDOMDocument *document)
*/
void
dom_selection_set_subscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean subscript)
{
- if (dom_selection_is_subscript (document) == subscript)
+ if (dom_selection_is_subscript (document, extension) == subscript)
return;
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_SUBSCRIPT, NULL);
@@ -2811,7 +2805,8 @@ dom_selection_set_subscript (WebKitDOMDocument *document,
* Returns @TRUE when selection is in superscript, @FALSE otherwise.
*/
gboolean
-dom_selection_is_superscript (WebKitDOMDocument *document)
+dom_selection_is_superscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
WebKitDOMNode *node;
WebKitDOMRange *range;
@@ -2846,9 +2841,10 @@ dom_selection_is_superscript (WebKitDOMDocument *document)
*/
void
dom_selection_set_superscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean superscript)
{
- if (dom_selection_is_superscript (document) == superscript)
+ if (dom_selection_is_superscript (document, extension) == superscript)
return;
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_SUPERSCRIPT, NULL);
@@ -2868,7 +2864,8 @@ dom_selection_set_superscript (WebKitDOMDocument *document,
* Returns @TRUE when selection is striked through, @FALSE otherwise.
*/
gboolean
-dom_selection_is_strikethrough (WebKitDOMDocument *document)
+dom_selection_is_strikethrough (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gboolean ret_val;
gchar *value, *text_content;
@@ -2889,9 +2886,7 @@ dom_selection_is_strikethrough (WebKitDOMDocument *document)
text_content = webkit_dom_node_get_text_content (node);
if (g_strcmp0 (text_content, "") == 0) {
g_free (text_content);
- return FALSE;
-/* FIXME WK2
- return selection->priv->is_strikethrough; */
+ return e_html_editor_web_extension_get_strikethrough (extension);
}
g_free (text_content);
@@ -2922,9 +2917,10 @@ dom_selection_is_strikethrough (WebKitDOMDocument *document)
*/
void
dom_selection_set_strikethrough (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean strikethrough)
{
- if (dom_selection_is_strikethrough (document) == strikethrough)
+ if (dom_selection_is_strikethrough (document, extension) == strikethrough)
return;
/* FIXME WK2
selection->priv->is_strikethrough = strikethrough;
@@ -2968,7 +2964,8 @@ is_monospaced_element (WebKitDOMElement *element)
* Returns @TRUE when selection is monospaced, @FALSE otherwise.
*/
gboolean
-dom_selection_is_monospaced (WebKitDOMDocument *document)
+dom_selection_is_monospaced (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gboolean ret_val;
gchar *value, *text_content;
@@ -3022,13 +3019,15 @@ dom_selection_is_monospaced (WebKitDOMDocument *document)
*/
void
dom_selection_set_monospaced (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean monospaced)
{
+ guint font_size = 0;
WebKitDOMRange *range;
WebKitDOMDOMWindow *window;
WebKitDOMDOMSelection *window_selection;
- if (dom_selection_is_monospaced (document) == monospaced)
+ if (dom_selection_is_monospaced (document, extension) == monospaced)
return;
/* FIXME WK2
selection->priv->is_monospaced = monospaced;
@@ -3037,22 +3036,21 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
if (!range)
return;
+ font_size = e_html_editor_web_extension_get_font_size (extension);
+ if (font_size == 0)
+ font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+
window = webkit_dom_document_get_default_view (document);
window_selection = webkit_dom_dom_window_get_selection (window);
if (monospaced) {
gchar *font_size_str;
- guint font_size = 0;
WebKitDOMElement *monospace;
monospace = webkit_dom_document_create_element (
document, "font", NULL);
webkit_dom_element_set_attribute (
monospace, "face", "monospace", NULL);
-/* FIXME WK2
- font_size = selection->priv->font_size; */
- if (font_size == 0)
- font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
font_size_str = g_strdup_printf ("%d", font_size);
webkit_dom_element_set_attribute (
monospace, "size", font_size_str, NULL);
@@ -3078,7 +3076,7 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
"<span id=\"-x-evo-selection-end-marker\"></span>",
NULL),
- dom_insert_html (document, html);
+ dom_insert_html (extension, document, html);
dom_selection_restore (document);
@@ -3114,14 +3112,10 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
}
/* Save current formatting */
-/* FIXME WK2
- is_bold = selection->priv->is_bold;
- is_italic = selection->priv->is_italic;
- is_underline = selection->priv->is_underline;
- is_strikethrough = selection->priv->is_strikethrough;
- font_size = selection->priv->font_size;*/
- if (font_size == 0)
- font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+ is_bold = e_html_editor_web_extension_get_bold (extension);
+ is_italic = e_html_editor_web_extension_get_italic (extension);
+ is_underline = e_html_editor_web_extension_get_underline (extension);
+ is_strikethrough = e_html_editor_web_extension_get_strikethrough (extension);
if (!dom_selection_is_collapsed (document)) {
gchar *html, *outer_html, *inner_html, *beginning, *end;
@@ -3221,22 +3215,21 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
g_free (outer_html);
g_free (tmp);
-/* FIXME WK2
- e_html_editor_view_force_spell_check_for_current_paragraph (
- view);*/
+
+ dom_force_spell_check_for_current_paragraph (document);
}
/* Re-set formatting */
if (is_bold)
- dom_selection_set_bold (document, TRUE);
+ dom_selection_set_bold (document, extension, TRUE);
if (is_italic)
- dom_selection_set_italic (document, TRUE);
+ dom_selection_set_italic (document, extension, TRUE);
if (is_underline)
- dom_selection_set_underline (document, TRUE);
+ dom_selection_set_underline (document, extension, TRUE);
if (is_strikethrough)
- dom_selection_set_strikethrough (document, TRUE);
+ dom_selection_set_strikethrough (document, extension, TRUE);
- dom_selection_set_font_size (document, font_size);
+ dom_selection_set_font_size (document, extension, font_size);
}
/* FIXME WK2
g_object_notify (G_OBJECT (selection), "monospaced");*/
@@ -3252,7 +3245,8 @@ dom_selection_set_monospaced (WebKitDOMDocument *document,
* Returns @TRUE when selection is bold, @FALSE otherwise.
*/
gboolean
-dom_selection_is_bold (WebKitDOMDocument *document)
+dom_selection_is_bold (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gboolean ret_val;
gchar *value, *text_content;
@@ -3274,9 +3268,7 @@ dom_selection_is_bold (WebKitDOMDocument *document)
text_content = webkit_dom_node_get_text_content (node);
if (g_strcmp0 (text_content, "") == 0) {
g_free (text_content);
- return FALSE;
-/* FIXME WK2
- return selection->priv->is_bold;*/
+ return e_html_editor_web_extension_get_bold (extension);
}
g_free (text_content);
@@ -3307,9 +3299,10 @@ dom_selection_is_bold (WebKitDOMDocument *document)
*/
void
dom_selection_set_bold (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean bold)
{
- if (dom_selection_is_bold (document) == bold)
+ if (dom_selection_is_bold (document, extension) == bold)
return;
/* FIXME WK2
selection->priv->is_bold = bold; */
@@ -3329,7 +3322,8 @@ dom_selection_set_bold (WebKitDOMDocument *document,
* Returns @TRUE when selection is italic, @FALSE otherwise.
*/
gboolean
-dom_selection_is_italic (WebKitDOMDocument *document)
+dom_selection_is_italic (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gboolean ret_val;
gchar *value, *text_content;
@@ -3351,9 +3345,7 @@ dom_selection_is_italic (WebKitDOMDocument *document)
text_content = webkit_dom_node_get_text_content (node);
if (g_strcmp0 (text_content, "") == 0) {
g_free (text_content);
- return FALSE;
-/* FIXME WK2
- return selection->priv->is_italic;*/
+ return e_html_editor_web_extension_get_italic (extension);
}
g_free (text_content);
@@ -3384,9 +3376,10 @@ dom_selection_is_italic (WebKitDOMDocument *document)
*/
void
dom_selection_set_italic (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean italic)
{
- if (dom_selection_is_italic (document) == italic)
+ if (dom_selection_is_italic (document, extension) == italic)
return;
/* FIXME WK2
selection->priv->is_italic = italic;*/
@@ -3520,8 +3513,9 @@ get_font_property (WebKitDOMDocument *document,
*
* Returns point size of current selection or of letter at current cursor position.
*/
- guint
-dom_selection_get_font_size (WebKitDOMDocument *document)
+guint
+dom_selection_get_font_size (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gchar *size;
guint size_int;
@@ -3549,6 +3543,7 @@ dom_selection_get_font_size (WebKitDOMDocument *document)
*/
void
dom_selection_set_font_size (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
guint font_size)
{
gchar *size_str;
@@ -3572,6 +3567,7 @@ dom_selection_set_font_size (WebKitDOMDocument *document,
*/
void
dom_selection_set_font_name (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *font_name)
{
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_FONT_NAME, font_name);
@@ -3589,7 +3585,8 @@ dom_selection_set_font_name (WebKitDOMDocument *document,
* Returns: A string with font name. [transfer-none]
*/
gchar *
-dom_selection_get_font_name (WebKitDOMDocument *document)
+dom_selection_get_font_name (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
WebKitDOMNode *node;
WebKitDOMRange *range;
@@ -3618,6 +3615,7 @@ dom_selection_get_font_name (WebKitDOMDocument *document)
*/
void
dom_selection_set_font_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *color)
{
/* FIXME WK2
@@ -3637,7 +3635,8 @@ dom_selection_set_font_color (WebKitDOMDocument *document,
* cursor position.
*/
gchar *
-dom_selection_get_font_color (WebKitDOMDocument *document)
+dom_selection_get_font_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
gchar *color;
@@ -3673,7 +3672,8 @@ get_block_node (WebKitDOMRange *range)
* Returns: #EHTMLEditorSelectionBlockFormat
*/
EHTMLEditorSelectionBlockFormat
-dom_selection_get_block_format (WebKitDOMDocument *document)
+dom_selection_get_block_format (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
WebKitDOMNode *node;
WebKitDOMRange *range;
@@ -3814,6 +3814,7 @@ is_citation_node (WebKitDOMNode *node)
static gboolean
process_block_to_block (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format,
const gchar *value,
WebKitDOMNode *block,
@@ -3836,6 +3837,7 @@ process_block_to_block (WebKitDOMDocument *document,
next_block = webkit_dom_node_get_next_sibling (block);
finished = process_block_to_block (
document,
+ extension,
format,
value,
webkit_dom_node_get_first_child (block),
@@ -3864,7 +3866,7 @@ process_block_to_block (WebKitDOMDocument *document,
next_block = webkit_dom_node_get_next_sibling (block);
if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH)
- element = dom_get_paragraph_element (document, -1, 0);
+ element = dom_get_paragraph_element (extension, document, -1, 0);
else
element = webkit_dom_document_create_element (
document, value, NULL);
@@ -3913,18 +3915,25 @@ process_block_to_block (WebKitDOMDocument *document,
block = next_block;
if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH && !html_mode) {
- gint citation_level, quote;
+ gint citation_level;
citation_level = get_citation_level (WEBKIT_DOM_NODE (element));
- quote = citation_level ? citation_level * 2 : 0;
- if (citation_level > 0)
+ if (citation_level > 0) {
+ gint quote, word_wrap_length;
+
+ word_wrap_length =
+ e_html_editor_web_extension_get_word_wrap_length (extension);
+ quote = citation_level ? citation_level * 2 : 0;
+
element = dom_wrap_paragraph_length (
- document, element, WORD_WRAP_LENGTH - quote);
+ extension, document, element, word_wrap_length - quote);
+
+ }
}
-/* FIXME WK2
+
if (quoted)
- e_html_editor_view_quote_plain_text_element (view, element);*/
+ dom_quote_plain_text_element (document, element);
}
return after_selection_end;
@@ -3932,6 +3941,7 @@ process_block_to_block (WebKitDOMDocument *document,
static void
format_change_block_to_block (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format,
const gchar *value)
{
@@ -3966,18 +3976,18 @@ format_change_block_to_block (WebKitDOMDocument *document,
end_block = get_parent_block_node_from_child (
WEBKIT_DOM_NODE (selection_end_marker));
-/* FIXME WK2
- html_mode = e_html_editor_view_get_html_mode (view);
-*/
+ html_mode = e_html_editor_web_extension_get_html_mode (extension);
+
/* Process all blocks that are in the selection one by one */
process_block_to_block (
- document, format, value, block, end_block, html_mode);
+ document, extension, format, value, block, end_block, html_mode);
dom_selection_restore (document);
}
static void
format_change_block_to_list (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format)
{
gboolean after_selection_end = FALSE, in_quote = FALSE;
@@ -4012,7 +4022,7 @@ format_change_block_to_list (WebKitDOMDocument *document,
block = get_parent_block_node_from_child (
WEBKIT_DOM_NODE (selection_start_marker));
- list = create_list_element (document, format, 0, html_mode);
+ list = create_list_element (extension, document, format, 0, html_mode);
if (webkit_dom_element_query_selector (
WEBKIT_DOM_ELEMENT (block), "span.-x-evo-quoted", NULL)) {
@@ -4139,6 +4149,7 @@ get_list_node_from_child (WebKitDOMNode *child)
static void
format_change_list_from_list (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat to,
gboolean html_mode)
{
@@ -4154,7 +4165,7 @@ format_change_list_from_list (WebKitDOMDocument *document,
if (!selection_start_marker || !selection_end_marker)
return;
- new_list = create_list_element (document, to, 0, html_mode);
+ new_list = create_list_element (extension, document, to, 0, html_mode);
/* Copy elements from previous block to list */
item = get_list_item_node_from_child (
@@ -4208,6 +4219,7 @@ format_change_list_from_list (WebKitDOMDocument *document,
static void
format_change_list_to_list (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format,
gboolean html_mode)
{
@@ -4246,7 +4258,7 @@ format_change_list_to_list (WebKitDOMDocument *document,
indented = element_has_class (WEBKIT_DOM_ELEMENT (current_list), "-x-evo-indented");
if (!prev_list || !next_list || indented) {
- format_change_list_from_list (document, format, html_mode);
+ format_change_list_from_list (document, extension, format, html_mode);
goto out;
}
@@ -4260,7 +4272,7 @@ format_change_list_to_list (WebKitDOMDocument *document,
webkit_dom_node_get_parent_node (
WEBKIT_DOM_NODE (selection_end_marker))));
if (!prev_list || !next_list) {
- format_change_list_from_list (document, format, html_mode);
+ format_change_list_from_list (document, extension, format, html_mode);
goto out;
}
}
@@ -4285,13 +4297,14 @@ format_change_list_to_list (WebKitDOMDocument *document,
if (done)
goto out;
- format_change_list_from_list (document, format, html_mode);
+ format_change_list_from_list (document, extension, format, html_mode);
out:
dom_selection_restore (document);
}
static void
format_change_list_to_block (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format,
const gchar *value)
{
@@ -4327,7 +4340,7 @@ format_change_list_to_block (WebKitDOMDocument *document,
if (!after_end) {
if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH)
- element = dom_get_paragraph_element (document, -1, 0);
+ element = dom_get_paragraph_element (extension, document, -1, 0);
else
element = webkit_dom_document_create_element (
document, value, NULL);
@@ -4373,6 +4386,7 @@ format_change_list_to_block (WebKitDOMDocument *document,
*/
void
dom_selection_set_block_format (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format)
{
EHTMLEditorSelectionBlockFormat current_format;
@@ -4380,7 +4394,7 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
gboolean from_list = FALSE, to_list = FALSE, html_mode = FALSE;
WebKitDOMRange *range;
- current_format = dom_selection_get_block_format (document);
+ current_format = dom_selection_get_block_format (document, extension);
if (current_format == format) {
return;
}
@@ -4433,12 +4447,11 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
}
/* H1 - H6 have bold font by default */
-/* FIXME WK2
if (format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1 &&
format <= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6)
- selection->priv->is_bold = TRUE;*/
-/* FIXME WK2
- html_mode = e_html_editor_view_get_html_mode (view);*/
+ set_dbus_property_boolean (extension, "Bold", TRUE);
+
+ html_mode = e_html_editor_web_extension_get_html_mode (extension);
from_list =
current_format >= E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
@@ -4448,26 +4461,25 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
return;
if (from_list && to_list)
- format_change_list_to_list (document, format, html_mode);
+ format_change_list_to_list (document, extension, format, html_mode);
if (!from_list && !to_list)
- format_change_block_to_block (document, format, value);
+ format_change_block_to_block (document, extension, format, value);
if (from_list && !to_list)
- format_change_list_to_block (document, format, value);
+ format_change_list_to_block (document, extension, format, value);
if (!from_list && to_list)
- format_change_block_to_list (document, format);
-/* FIXME WK2
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
-*/
+ format_change_block_to_list (document, extension, format);
- /* When changing the format we need to re-set the alignment */
-/* FIXME WK2
- dom_selection_set_alignment (document, selection->priv->alignment);
+ dom_force_spell_check_for_current_paragraph (document);
- e_html_editor_view_set_changed (view, TRUE);
+ /* When changing the format we need to re-set the alignment */
+ dom_selection_set_alignment (
+ document, extension, e_html_editor_web_extension_get_alignment (extension));
+ e_html_editor_web_extension_set_content_changed (extension);
+/*
g_object_notify (G_OBJECT (selection), "block-format");*/
}
@@ -4481,7 +4493,8 @@ dom_selection_set_block_format (WebKitDOMDocument *document,
* Returns: A string with code of current background color.
*/
gchar *
-dom_selection_get_background_color (WebKitDOMDocument *document)
+dom_selection_get_background_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
WebKitDOMNode *ancestor;
WebKitDOMRange *range;
@@ -4511,6 +4524,7 @@ dom_selection_get_background_color (WebKitDOMDocument *document)
*/
void
dom_selection_set_background_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *color)
{
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_BACKGROUND_COLOR, color);
@@ -4527,7 +4541,8 @@ dom_selection_set_background_color (WebKitDOMDocument *document,
* Returns: #EHTMLEditorSelectionAlignment
*/
EHTMLEditorSelectionAlignment
-dom_selection_get_alignment (WebKitDOMDocument *document)
+dom_selection_get_alignment (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension)
{
EHTMLEditorSelectionAlignment alignment;
gchar *value;
@@ -4597,6 +4612,7 @@ set_block_alignment (WebKitDOMElement *element,
*/
void
dom_selection_set_alignment (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionAlignment alignment)
{
gboolean after_selection_end = FALSE;
@@ -4604,7 +4620,7 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
WebKitDOMElement *selection_start_marker, *selection_end_marker;
WebKitDOMNode *block;
- if (dom_selection_get_alignment (document) == alignment)
+ if (dom_selection_get_alignment (document, extension) == alignment)
return;
switch (alignment) {
@@ -4695,9 +4711,10 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
}
dom_selection_restore (document);
-/* FIXME WK2
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
+ dom_force_spell_check_for_current_paragraph (document);
+
+/* FIXME WK2
g_object_notify (G_OBJECT (selection), "alignment");*/
}
@@ -4709,9 +4726,11 @@ dom_selection_set_alignment (WebKitDOMDocument *document,
* Replaces currently selected text with @replacement.
*/
void
-dom_selection_replace (WebKitDOMDocument *document,
+dom_selection_replace (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
const gchar *replacement)
{
+ e_html_editor_web_extension_set_content_changed (extension);
dom_exec_command (document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_TEXT, replacement);
}
@@ -4723,7 +4742,8 @@ dom_selection_replace (WebKitDOMDocument *document,
* Replaces current word under cursor with @replacement.
*/
void
-dom_replace_caret_word (WebKitDOMDocument *document,
+dom_replace_caret_word (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
const gchar *replacement)
{
WebKitDOMDOMWindow *window;
@@ -4733,11 +4753,12 @@ dom_replace_caret_word (WebKitDOMDocument *document,
window = webkit_dom_document_get_default_view (document);
dom_selection = webkit_dom_dom_window_get_selection (window);
+ e_html_editor_web_extension_set_content_changed (extension);
range = dom_get_current_range (document);
webkit_dom_range_expand (range, "word", NULL);
webkit_dom_dom_selection_add_range (dom_selection, range);
- dom_insert_html (document, replacement);
+ dom_insert_html (extension, document, replacement);
}
/**
diff --git a/e-util/e-html-editor-selection-dom-functions.h b/e-util/e-html-editor-selection-dom-functions.h
index 945f20b..b513f92 100644
--- a/e-util/e-html-editor-selection-dom-functions.h
+++ b/e-util/e-html-editor-selection-dom-functions.h
@@ -21,6 +21,8 @@
#include <webkitdom/webkitdom.h>
+#include "web-extensions/e-html-editor-web-extension.h"
+
#include "e-util-enums.h"
G_BEGIN_DECLS
@@ -31,8 +33,7 @@ void dom_replace_base64_image_src (WebKitDOMDocument *document,
const gchar *filename,
const gchar *uri);
-void dom_clear_caret_position_marker
- (WebKitDOMDocument *document);
+void dom_clear_caret_position_marker (WebKitDOMDocument *document);
WebKitDOMNode *
dom_create_caret_position_node (WebKitDOMDocument *document);
@@ -40,7 +41,8 @@ WebKitDOMNode *
WebKitDOMRange *
dom_get_current_range (WebKitDOMDocument *document);
*/
-gchar * dom_selection_get_string (WebKitDOMDocument *document);
+gchar * dom_selection_get_string (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
WebKitDOMElement *
dom_save_caret_position (WebKitDOMDocument *document);
@@ -59,83 +61,111 @@ void dom_selection_save (WebKitDOMDocument *document);
void dom_selection_restore (WebKitDOMDocument *document);
-gboolean dom_selection_is_underline (WebKitDOMDocument *document);
+gboolean dom_selection_is_underline (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_underline (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean underline);
-gboolean dom_selection_is_subscript (WebKitDOMDocument *document);
+gboolean dom_selection_is_subscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_subscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean subscript);
-gboolean dom_selection_is_superscript (WebKitDOMDocument *document);
+gboolean dom_selection_is_superscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_superscript (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean superscript);
-gboolean dom_selection_is_strikethrough (WebKitDOMDocument *document);
+gboolean dom_selection_is_strikethrough (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_strikethrough (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean strikethrough);
-gboolean dom_selection_is_monospaced (WebKitDOMDocument *document);
+gboolean dom_selection_is_monospaced (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_monospaced (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean monospaced);
-gboolean dom_selection_is_bold (WebKitDOMDocument *document);
+gboolean dom_selection_is_bold (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_bold (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean bold);
-gboolean dom_selection_is_italic (WebKitDOMDocument *document);
+gboolean dom_selection_is_italic (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_italic (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
gboolean italic);
gboolean dom_selection_is_indented (WebKitDOMDocument *document);
gboolean dom_selection_is_citation (WebKitDOMDocument *document);
-guint dom_selection_get_font_size (WebKitDOMDocument *document);
+guint dom_selection_get_font_size (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_font_size (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
guint font_size);
-gchar * dom_selection_get_font_name (WebKitDOMDocument *document);
+gchar * dom_selection_get_font_name (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_font_name (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *font_size);
-gchar * dom_selection_get_font_color (WebKitDOMDocument *document);
+gchar * dom_selection_get_font_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_font_color (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *font_color);
gchar * dom_selection_get_background_color
- (WebKitDOMDocument *document);
+ (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_background_color
(WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
const gchar *font_color);
EHTMLEditorSelectionBlockFormat
- dom_selection_get_block_format (WebKitDOMDocument *document);
+ dom_selection_get_block_format (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_block_format (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionBlockFormat format);
EHTMLEditorSelectionAlignment
- dom_selection_get_alignment (WebKitDOMDocument *document);
+ dom_selection_get_alignment (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension);
void dom_selection_set_alignment (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
EHTMLEditorSelectionAlignment alignment);
-void dom_selection_replace (WebKitDOMDocument *document,
+void dom_selection_replace (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
const gchar *replacement);
-void dom_replace_caret_word (WebKitDOMDocument *document,
+void dom_replace_caret_word (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
const gchar *replacement);
gchar * dom_get_caret_word (WebKitDOMDocument *document);
diff --git a/e-util/e-html-editor-selection.c b/e-util/e-html-editor-selection.c
index b5f9250..d9bb798 100644
--- a/e-util/e-html-editor-selection.c
+++ b/e-util/e-html-editor-selection.c
@@ -718,14 +718,6 @@ e_html_editor_selection_init (EHTMLEditorSelection *selection)
g_object_unref (g_settings);
}
-gint
-e_html_editor_selection_get_word_wrap_length (EHTMLEditorSelection *selection)
-{
- g_return_val_if_fail (E_IS_HTML_EDITOR_SELECTION (selection), 72);
-
- return selection->priv->word_wrap_length;
-}
-
/**
* e_html_editor_selection_ref_html_editor_view:
* @selection: an #EHTMLEditorSelection
@@ -854,7 +846,6 @@ e_html_editor_selection_replace_caret_word (EHTMLEditorSelection *selection,
view = e_html_editor_selection_ref_html_editor_view (selection);
g_return_if_fail (view != NULL);
- e_html_editor_view_set_changed (view, TRUE);
web_extension = e_html_editor_view_get_web_extension_proxy (view);
if (!web_extension)
goto out;
@@ -894,7 +885,6 @@ e_html_editor_selection_replace (EHTMLEditorSelection *selection,
view = e_html_editor_selection_ref_html_editor_view (selection);
g_return_if_fail (view != NULL);
- e_html_editor_view_set_changed (view, TRUE);
web_extension = e_html_editor_view_get_web_extension_proxy (view);
if (!web_extension)
goto out;
@@ -1261,7 +1251,7 @@ e_html_editor_selection_get_background_color (EHTMLEditorSelection *selection)
g_free (selection->priv->background_color);
selection->priv->background_color = g_strdup (
- (html_editor_selection_get_format_string (selection, "font-family"));
+ html_editor_selection_get_format_string (selection, "font-family"));
return selection->priv->background_color;
}
@@ -1305,7 +1295,7 @@ e_html_editor_selection_get_font_name (EHTMLEditorSelection *selection)
g_free (selection->priv->font_name);
selection->priv->font_name = g_strdup (
- html_editor_selection_get_format_string (selection, "font-family")_;
+ html_editor_selection_get_format_string (selection, "font-family"));
return selection->priv->font_name;
}
diff --git a/e-util/e-html-editor-view-dom-functions.c b/e-util/e-html-editor-view-dom-functions.c
index 4fcb4ad..f164c80 100644
--- a/e-util/e-html-editor-view-dom-functions.c
+++ b/e-util/e-html-editor-view-dom-functions.c
@@ -18,6 +18,9 @@
#include "e-html-editor-view-dom-functions.h"
+#include "e-dom-utils.h"
+#include "e-html-editor-selection-dom-functions.h"
+
/**
* e_html_editor_view_dom_exec_command:
* @document: a #WebKitDOMDocument
@@ -101,3 +104,4934 @@ dom_exec_command (WebKitDOMDocument *document,
return webkit_dom_document_exec_command (
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)
+{
+ WebKitDOMDOMSelection *dom_selection;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMElement *parent, *element;
+ WebKitDOMRange *end_range, *actual;
+ WebKitDOMText *text;
+
+ window = webkit_dom_document_get_default_view (document);
+ dom_selection = webkit_dom_dom_window_get_selection (window);
+
+ element = webkit_dom_document_query_selector (
+ document, "body[spellcheck=true]", NULL);
+
+ if (!element)
+ return;
+
+ dom_selection_save (document);
+
+ 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 || !selection_end_marker)
+ return;
+
+ /* Block callbacks of selection-changed signal as we don't want to
+ * recount all the block format things in EHTMLEditorSelection and here as well
+ * when we are moving with caret */
+/* FIXME WK2
+ g_signal_handlers_block_by_func (
+ view, html_editor_view_selection_changed_cb, NULL);
+ e_html_editor_selection_block_selection_changed (selection);
+*/
+ parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_end_marker));
+
+ /* Append some text on the end of the element */
+ text = webkit_dom_document_create_text_node (document, "-x-evo-end");
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (parent),
+ WEBKIT_DOM_NODE (text),
+ NULL);
+
+ parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start_marker));
+
+ /* Create range that's pointing on the end of this text */
+ end_range = webkit_dom_document_create_range (document);
+ webkit_dom_range_select_node_contents (
+ end_range, WEBKIT_DOM_NODE (text), NULL);
+ webkit_dom_range_collapse (end_range, FALSE, NULL);
+
+ /* Move on the beginning of the paragraph */
+ actual = webkit_dom_document_create_range (document);
+ webkit_dom_range_select_node_contents (
+ actual, WEBKIT_DOM_NODE (parent), NULL);
+ webkit_dom_range_collapse (actual, TRUE, NULL);
+ webkit_dom_dom_selection_remove_all_ranges (dom_selection);
+ webkit_dom_dom_selection_add_range (dom_selection, actual);
+
+ /* Go through all words to spellcheck them. To avoid this we have to wait for
+ * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
+ actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+ /* We are moving forward word by word until we hit the text on the end of
+ * the paragraph that we previously inserted there */
+ while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
+ webkit_dom_dom_selection_modify (
+ dom_selection, "move", "forward", "word");
+ actual = webkit_dom_dom_selection_get_range_at (
+ dom_selection, 0, NULL);
+ }
+
+ /* Remove the text that we inserted on the end of the paragraph */
+ remove_node (WEBKIT_DOM_NODE (text));
+
+ /* Unblock the callbacks */
+/* FIXME WK2
+ g_signal_handlers_unblock_by_func (
+ view, html_editor_view_selection_changed_cb, NULL);
+ e_html_editor_selection_unblock_selection_changed (selection);
+*/
+ do_selection_restore (document);
+}
+
+static WebKitDOMElement *
+create_selection_marker (WebKitDOMDocument *document,
+ gboolean start)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_create_element (
+ document, "SPAN", NULL);
+ webkit_dom_element_set_id (
+ element,
+ start ? "-x-evo-selection-start-marker" :
+ "-x-evo-selection-end-marker");
+
+ return element;
+}
+
+static void
+add_selection_markers_into_element_start (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ marker = create_selection_marker (document, FALSE);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (marker),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+ NULL);
+ if (selection_end_marker)
+ *selection_end_marker = marker;
+
+ marker = create_selection_marker (document, TRUE);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ WEBKIT_DOM_NODE (marker),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+ NULL);
+ if (selection_start_marker)
+ *selection_start_marker = marker;
+}
+
+static void
+add_selection_markers_into_element_end (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ marker = create_selection_marker (document, TRUE);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+ if (selection_start_marker)
+ *selection_start_marker = marker;
+
+ marker = create_selection_marker (document, FALSE);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
+ if (selection_end_marker)
+ *selection_end_marker = marker;
+}
+
+static void
+refresh_spell_check (WebKitDOMDocument *document,
+ gboolean enable_spell_check)
+{
+ WebKitDOMDOMSelection *dom_selection;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMHTMLElement *body;
+ WebKitDOMRange *end_range, *actual;
+ WebKitDOMText *text;
+
+ window = webkit_dom_document_get_default_view (document);
+ dom_selection = webkit_dom_dom_window_get_selection (window);
+
+ /* Enable/Disable spellcheck in composer */
+ body = webkit_dom_document_get_body (document);
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (body),
+ "spellcheck",
+ enable_spell_check ? "true" : "false",
+ NULL);
+
+ dom_selection_save (document);
+
+ 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);
+
+ /* Sometimes the web view is not focused, so we have to save the selection
+ * manually into the body */
+ if (!selection_start_marker || !selection_end_marker) {
+ WebKitDOMNode *child;
+
+ child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+ if (!child)
+ return;
+
+ add_selection_markers_into_element_start (
+ document,
+ WEBKIT_DOM_ELEMENT (child),
+ &selection_start_marker,
+ &selection_end_marker);
+ }
+
+ /* Block callbacks of selection-changed signal as we don't want to
+ * recount all the block format things in EHTMLEditorSelection and here as well
+ * when we are moving with caret */
+/* FIXME WK2
+ g_signal_handlers_block_by_func (
+ view, html_editor_view_selection_changed_cb, NULL);
+ e_html_editor_selection_block_selection_changed (selection);
+*/
+ /* Append some text on the end of the body */
+ text = webkit_dom_document_create_text_node (document, "-x-evo-end");
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (text), NULL);
+
+ /* Create range that's pointing on the end of this text */
+ end_range = webkit_dom_document_create_range (document);
+ webkit_dom_range_select_node_contents (
+ end_range, WEBKIT_DOM_NODE (text), NULL);
+ webkit_dom_range_collapse (end_range, FALSE, NULL);
+
+ /* Move on the beginning of the document */
+ webkit_dom_dom_selection_modify (
+ dom_selection, "move", "backward", "documentboundary");
+
+ /* Go through all words to spellcheck them. To avoid this we have to wait for
+ * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
+ actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
+ /* We are moving forward word by word until we hit the text on the end of
+ * the body that we previously inserted there */
+ while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
+ webkit_dom_dom_selection_modify (
+ dom_selection, "move", "forward", "word");
+ actual = webkit_dom_dom_selection_get_range_at (
+ dom_selection, 0, NULL);
+ }
+
+ /* Remove the text that we inserted on the end of the body */
+ remove_node (WEBKIT_DOM_NODE (text));
+
+ /* Unblock the callbacks */
+/* FIXME WK2
+ g_signal_handlers_unblock_by_func (
+ view, html_editor_view_selection_changed_cb, NULL);
+ e_html_editor_selection_unblock_selection_changed (selection);
+*/
+ dom_selection_restore (document);
+}
+
+void
+dom_turn_spell_check_off (WebKitDOMDocument *document)
+{
+ refresh_spell_check (document, FALSE);
+}
+
+void
+dom_force_spell_check (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ if (extension->priv->inline_spelling)
+ refresh_spell_check (document, TRUE);
+}
+
+static gint
+get_citation_level (WebKitDOMNode *node,
+ gboolean set_plaintext_quoted)
+{
+ WebKitDOMNode *parent = node;
+ gint level = 0;
+
+ while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+ webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (parent), "type")) {
+ level++;
+
+ if (set_plaintext_quoted) {
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (parent),
+ "-x-evo-plaintext-quoted");
+ }
+ }
+
+ parent = webkit_dom_node_get_parent_node (parent);
+ }
+
+ return level;
+}
+
+static gchar *
+get_quotation_for_level (gint quote_level)
+{
+ gint ii;
+ GString *output = g_string_new ("");
+
+ for (ii = 0; ii < quote_level; ii++) {
+ g_string_append (output, "<span class=\"-x-evo-quote-character\">");
+ g_string_append (output, QUOTE_SYMBOL);
+ g_string_append (output, " ");
+ g_string_append (output, "</span>");
+ }
+
+ return g_string_free (output, FALSE);
+}
+
+static void
+quote_plain_text_element_after_wrapping (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ gint quote_level)
+{
+ WebKitDOMNodeList *list;
+ WebKitDOMNode *quoted_node;
+ gint length, ii;
+ gchar *quotation;
+
+ quoted_node = WEBKIT_DOM_NODE (
+ webkit_dom_document_create_element (document, "SPAN", NULL));
+ webkit_dom_element_set_class_name (
+ WEBKIT_DOM_ELEMENT (quoted_node), "-x-evo-quoted");
+ quotation = get_quotation_for_level (quote_level);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (quoted_node), quotation, NULL);
+
+ list = webkit_dom_element_query_selector_all (
+ element, "br.-x-evo-wrap-br", NULL);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ quoted_node,
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
+ NULL);
+
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *br = webkit_dom_node_list_item (list, ii);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (br),
+ webkit_dom_node_clone_node (quoted_node, TRUE),
+ webkit_dom_node_get_next_sibling (br),
+ NULL);
+ }
+
+ g_object_unref (list);
+ g_free (quotation);
+}
+
+static gboolean
+is_citation_node (WebKitDOMNode *node)
+{
+ char *value;
+
+ if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
+ return FALSE;
+
+ value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
+
+ /* citation == <blockquote type='cite'> */
+ if (g_strcmp0 (value, "cite") == 0) {
+ g_free (value);
+ return TRUE;
+ } else {
+ g_free (value);
+ return FALSE;
+ }
+}
+
+static gboolean
+return_pressed_in_empty_line (WebKitDOMDocument *document)
+{
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+
+ range = dom_get_current_range (document);
+ if (!range)
+ return FALSE;
+
+ node = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_TEXT (node)) {
+ WebKitDOMNode *first_child;
+
+ first_child = webkit_dom_node_get_first_child (node);
+ if (first_child && WEBKIT_DOM_IS_ELEMENT (first_child) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (first_child), "-x-evo-quoted")) {
+ WebKitDOMNode *prev_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+ if (!prev_sibling)
+ return webkit_dom_range_get_collapsed (range, NULL);
+ }
+ }
+
+ return FALSE;
+}
+
+static WebKitDOMNode *
+get_parent_block_node_from_child (WebKitDOMNode *node)
+{
+ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+ if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") ||
+ WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u"))
+ parent = webkit_dom_node_get_parent_node (parent);
+
+ return parent;
+}
+
+static WebKitDOMElement *
+prepare_paragraph (WebKitDOMDocument *document,
+ gboolean with_selection)
+{
+ WebKitDOMElement *element, *paragraph;
+
+ paragraph = dom_get_paragraph_element (document, -1, 0);
+
+ if (with_selection)
+ add_selection_markers_into_element_start (
+ document, paragraph, NULL, NULL);
+
+ element = webkit_dom_document_create_element (document, "BR", NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (paragraph), WEBKIT_DOM_NODE (element), NULL);
+
+ return paragraph;
+}
+
+static WebKitDOMElement *
+insert_new_line_into_citation (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
+ const gchar *html_to_insert)
+{
+ gboolean html_mode = FALSE, ret_val, avoid_editor_call;
+ WebKitDOMElement *element, *paragraph = NULL;
+
+ html_mode = is_in_html_mode (extension);
+
+ avoid_editor_call = return_pressed_in_empty_line (document);
+
+ if (avoid_editor_call) {
+ WebKitDOMElement *selection_start_marker;
+ WebKitDOMNode *current_block, *parent, *parent_block, *block_clone;
+
+ dom_selection_save (document);
+
+ selection_start_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+
+ current_block = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ block_clone = webkit_dom_node_clone_node (current_block, TRUE);
+ /* Find selection start marker and restore it after the new line
+ * is inserted */
+ selection_start_marker = webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (block_clone), "#-x-evo-selection-start-marker", NULL);
+
+ /* Find parent node that is immediate child of the BODY */
+ /* Build the same structure of parent nodes of the current block */
+ parent_block = current_block;
+ parent = webkit_dom_node_get_parent_node (parent_block);
+ while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ WebKitDOMNode *node;
+
+ parent_block = parent;
+ node = webkit_dom_node_clone_node (parent_block, FALSE);
+ webkit_dom_node_append_child (node, block_clone, NULL);
+ block_clone = node;
+ parent = webkit_dom_node_get_parent_node (parent_block);
+ }
+
+ paragraph = dom_get_paragraph_element (document, -1, 0);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (paragraph),
+ WEBKIT_DOM_NODE (
+ webkit_dom_document_create_element (document, "BR", NULL)),
+ NULL);
+
+ /* Insert the selection markers to right place */
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (paragraph),
+ webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_start_marker)),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
+ NULL);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (paragraph),
+ WEBKIT_DOM_NODE (selection_start_marker),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
+ NULL);
+
+ /* Insert the cloned nodes before the BODY parent node */
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent_block),
+ block_clone,
+ parent_block,
+ NULL);
+
+ /* Insert the new empty paragraph before the BODY parent node */
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent_block),
+ WEBKIT_DOM_NODE (paragraph),
+ parent_block,
+ NULL);
+
+ /* Remove the old block (its copy was moved to the right place) */
+ remove_node (current_block);
+
+ dom_selection_restore (document);
+
+ return NULL;
+ } else {
+ ret_val = dom_exec_command (
+ document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, NULL);
+
+ if (!ret_val)
+ return NULL;
+
+ element = webkit_dom_document_query_selector (
+ document, "body>br", NULL);
+
+ if (!element)
+ return NULL;
+ }
+
+ if (!html_mode) {
+ WebKitDOMNode *next_sibling;
+
+ next_sibling = webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (element));
+
+ if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling)) {
+ gint citation_level, length;
+ gint word_wrap_length = extension->priv->word_wrap_length;
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_get_first_child (next_sibling);
+ while (node && is_citation_node (node))
+ node = webkit_dom_node_get_first_child (node);
+
+ citation_level = get_citation_level (node, FALSE);
+ length = word_wrap_length - 2 * citation_level;
+
+ /* Rewrap and requote first block after the newly inserted line */
+ if (node && WEBKIT_DOM_IS_ELEMENT (node)) {
+ remove_quoting_from_element (WEBKIT_DOM_ELEMENT (node));
+ remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (node));
+ node = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+ document, WEBKIT_DOM_ELEMENT (node), length));
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (node), citation_level);
+ }
+
+ dom_force_spell_check (document);
+ }
+ }
+
+ if (html_to_insert && *html_to_insert) {
+ paragraph = prepare_paragraph (document, FALSE);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (paragraph),
+ html_to_insert,
+ NULL);
+ add_selection_markers_into_element_end (
+ document, paragraph, NULL, NULL);
+ } else
+ paragraph = prepare_paragraph (document, TRUE);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+ WEBKIT_DOM_NODE (paragraph),
+ WEBKIT_DOM_NODE (element),
+ NULL);
+
+ remove_node (WEBKIT_DOM_NODE (element));
+
+ dom_selection_restore (document);
+
+ return paragraph;
+}
+
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+put_body_in_citation (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *cite_body = webkit_dom_document_query_selector (
+ document, "span.-x-evo-cite-body", NULL);
+
+ if (cite_body) {
+ WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+ WebKitDOMNode *citation;
+ WebKitDOMNode *sibling;
+
+ citation = WEBKIT_DOM_NODE (
+ webkit_dom_document_create_element (document, "blockquote", NULL));
+ webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (citation), "-x-evo-main-cite");
+ webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (citation), "type", "cite", NULL);
+
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (body),
+ citation,
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+ NULL);
+
+ while ((sibling = webkit_dom_node_get_next_sibling (citation)))
+ webkit_dom_node_append_child (citation, sibling, NULL);
+ }
+}
+
+/* For purpose of this function see e-mail-formatter-quote.c */
+static void
+move_elements_to_body (WebKitDOMDocument *document)
+{
+ WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+ WebKitDOMNodeList *list;
+ gint ii;
+
+ list = webkit_dom_document_query_selector_all (
+ document, "span.-x-evo-to-body[data-headers]", NULL);
+ for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
+ WebKitDOMNode *child;
+ WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+ while ((child = webkit_dom_node_get_first_child (node))) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (body),
+ child,
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (body)),
+ NULL);
+ }
+
+ remove_node (node);
+ }
+ g_object_unref (list);
+
+ list = webkit_dom_document_query_selector_all (
+ document, "span.-x-evo-to-body[data-credits]", NULL);
+ for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
+ WebKitDOMNode *child;
+ WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+ while ((child = webkit_dom_node_get_first_child (node))) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (body),
+ child,
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (body)),
+ NULL);
+ }
+
+ remove_node (node);
+ }
+ g_object_unref (list);
+}
+
+static void
+repair_gmail_blockquotes (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *list;
+ gint ii, length;
+
+ list = webkit_dom_document_query_selector_all (
+ document, "blockquote.gmail_quote", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
+
+ webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "class");
+ webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "style");
+ webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (node), "type", "cite", NULL);
+ }
+ g_object_unref (list);
+}
+
+/* FIXME WK2 */
+static void
+dom_check_magic_links (WebKitDOMDocument *document,
+ WebKitDOMRange *range,
+ gboolean include_space_by_user,
+ gboolean return_pressed,
+ gboolean space_pressed)
+{
+ gchar *node_text;
+ gchar **urls;
+ GRegex *regex = NULL;
+ GMatchInfo *match_info;
+ gint start_pos_url, end_pos_url;
+ WebKitDOMNode *node;
+ gboolean include_space = FALSE;
+ gboolean return_pressed = FALSE;
+
+ if (event != NULL) {
+ return_pressed = is_return_key (event);
+ include_space = (event->keyval == GDK_KEY_space);
+ } else {
+ include_space = include_space_by_user;
+ }
+
+ node = webkit_dom_range_get_end_container (range, NULL);
+
+ if (return_pressed)
+ node = webkit_dom_node_get_previous_sibling (node);
+
+ if (!node)
+ return;
+
+ if (!WEBKIT_DOM_IS_TEXT (node)) {
+ if (webkit_dom_node_has_child_nodes (node))
+ node = webkit_dom_node_get_first_child (node);
+ if (!WEBKIT_DOM_IS_TEXT (node))
+ return;
+ }
+
+ node_text = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (node));
+ if (!node_text || !(*node_text) || !g_utf8_validate (node_text, -1, NULL))
+ return;
+
+ regex = g_regex_new (include_space ? URL_PATTERN_SPACE : URL_PATTERN, 0, 0, NULL);
+
+ if (!regex) {
+ g_free (node_text);
+ return;
+ }
+
+ g_regex_match_all (regex, node_text, G_REGEX_MATCH_NOTEMPTY, &match_info);
+ urls = g_match_info_fetch_all (match_info);
+
+ if (urls) {
+ gchar *final_url, *url_end_raw;
+ glong url_start, url_end, url_length;
+ WebKitDOMNode *url_text_node_clone;
+ WebKitDOMText *url_text_node;
+ WebKitDOMElement *anchor;
+ const gchar* url_text;
+
+ if (!return_pressed)
+ dom_save_caret_position (document);
+
+ g_match_info_fetch_pos (match_info, 0, &start_pos_url, &end_pos_url);
+
+ /* Get start and end position of url in node's text because positions
+ * that we get from g_match_info_fetch_pos are not UTF-8 aware */
+ url_end_raw = g_strndup(node_text, end_pos_url);
+ url_end = g_utf8_strlen (url_end_raw, -1);
+
+ url_length = g_utf8_strlen (urls[0], -1);
+ url_start = url_end - url_length;
+
+ webkit_dom_text_split_text (
+ WEBKIT_DOM_TEXT (node),
+ include_space ? url_end - 1 : url_end,
+ NULL);
+
+ url_text_node = webkit_dom_text_split_text (
+ WEBKIT_DOM_TEXT (node), url_start, NULL);
+ url_text_node_clone = webkit_dom_node_clone_node (
+ WEBKIT_DOM_NODE (url_text_node), TRUE);
+ url_text = webkit_dom_text_get_whole_text (
+ WEBKIT_DOM_TEXT (url_text_node_clone));
+
+ final_url = g_strconcat (
+ g_str_has_prefix (url_text, "www") ? "http://" : "", url_text, NULL);
+
+ /* Create and prepare new anchor element */
+ anchor = webkit_dom_document_create_element (document, "A", NULL);
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (anchor),
+ url_text,
+ NULL);
+
+ webkit_dom_html_anchor_element_set_href (
+ WEBKIT_DOM_HTML_ANCHOR_ELEMENT (anchor),
+ final_url);
+
+ /* Insert new anchor element into document */
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (anchor),
+ WEBKIT_DOM_NODE (url_text_node),
+ NULL);
+
+ if (!return_pressed)
+ dom_restore_caret_position (document);
+
+ g_free (url_end_raw);
+ g_free (final_url);
+ } else {
+ WebKitDOMElement *parent;
+ WebKitDOMNode *prev_sibling;
+ gchar *href, *text, *url;
+ gint diff;
+ const char* text_to_append;
+ gboolean appending_to_link = FALSE;
+
+ parent = webkit_dom_node_get_parent_element (node);
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+
+ /* If previous sibling is ANCHOR and actual text node is not beginning with
+ * space => we're appending to link */
+ if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
+ text_to_append = webkit_dom_node_get_text_content (node);
+ if (g_strcmp0 (text_to_append, "") != 0 &&
+ !g_unichar_isspace (g_utf8_get_char (text_to_append))) {
+
+ appending_to_link = TRUE;
+ parent = WEBKIT_DOM_ELEMENT (prev_sibling);
+ }
+ }
+
+ /* If parent is ANCHOR => we're editing the link */
+ if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) && !appending_to_link) {
+ g_match_info_free (match_info);
+ g_regex_unref (regex);
+ g_free (node_text);
+ return;
+ }
+
+ /* edit only if href and description are the same */
+ href = webkit_dom_html_anchor_element_get_href (
+ WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent));
+
+ if (appending_to_link) {
+ gchar *inner_text;
+
+ inner_text =
+ webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (parent)),
+
+ text = g_strconcat (inner_text, text_to_append, NULL);
+ g_free (inner_text);
+ } else
+ text = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (parent));
+
+ if (strstr (href, "://") && !strstr (text, "://")) {
+ url = strstr (href, "://") + 3;
+ diff = strlen (text) - strlen (url);
+
+ if (text [strlen (text) - 1] != '/')
+ diff++;
+
+ if ((g_strcmp0 (url, text) != 0 && ABS (diff) == 1) || appending_to_link) {
+ gchar *inner_html, *protocol, *new_href;
+
+ protocol = g_strndup (href, strstr (href, "://") - href + 3);
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (parent));
+ new_href = g_strconcat (
+ protocol, inner_html, appending_to_link ? text_to_append : "", NULL);
+
+ webkit_dom_html_anchor_element_set_href (
+ WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent),
+ new_href);
+
+ if (appending_to_link) {
+ gchar *tmp;
+
+ tmp = g_strconcat (inner_html, text_to_append, NULL);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (parent),
+ tmp,
+ NULL);
+
+ remove_node (node);
+
+ g_free (tmp);
+ }
+
+ g_free (new_href);
+ g_free (protocol);
+ g_free (inner_html);
+ }
+ } else {
+ diff = strlen (text) - strlen (href);
+ if (text [strlen (text) - 1] != '/')
+ diff++;
+
+ if ((g_strcmp0 (href, text) != 0 && ABS (diff) == 1) || appending_to_link) {
+ gchar *inner_html;
+ gchar *new_href;
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (parent));
+ new_href = g_strconcat (
+ inner_html,
+ appending_to_link ? text_to_append : "",
+ NULL);
+
+ webkit_dom_html_anchor_element_set_href (
+ WEBKIT_DOM_HTML_ANCHOR_ELEMENT (parent),
+ new_href);
+
+ if (appending_to_link) {
+ gchar *tmp;
+
+ tmp = g_strconcat (inner_html, text_to_append, NULL);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (parent),
+ tmp,
+ NULL);
+
+ remove_node (node);
+
+ g_free (tmp);
+ }
+
+ g_free (new_href);
+ g_free (inner_html);
+ }
+
+ }
+ g_free (text);
+ g_free (href);
+ }
+
+ g_match_info_free (match_info);
+ g_regex_unref (regex);
+ g_free (node_text);
+}
+
+void
+dom_embed_style_sheet (WebKitDOMDocument *document,
+ const gchar *style_sheet_content)
+{
+ WebKitDOMElement *sheet;
+
+ e_web_view_create_and_add_css_style_sheet (document, "-x-evo-composer-sheet");
+
+ sheet = webkit_dom_document_get_element_by_id (document, "-x-evo-composer-sheet");
+ webkit_dom_element_set_attribute (
+ sheet,
+ "type",
+ "text/css",
+ NULL);
+
+ webkit_dom_html_element_set_inner_html (WEBKIT_DOM_HTML_ELEMENT (sheet), stylesheet_content, NULL);
+}
+
+void
+dom_remove_embed_style_sheet (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *sheet;
+
+ sheet = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-composer-sheet");
+
+ remove_node (WEBKIT_DOM_NODE (sheet));
+}
+
+void
+dom_set_links_active (WebKitDOMDocument *document,
+ gboolean active)
+{
+ WebKitDOMElement *style;
+
+ if (active) {
+ style = webkit_dom_document_get_element_by_id (
+ document, "--evolution-editor-style-a");
+ if (style)
+ remove_node (WEBKIT_DOM_NODE (style));
+ } else {
+ WebKitDOMHTMLHeadElement *head;
+ head = webkit_dom_document_get_head (document);
+
+ style = webkit_dom_document_create_element (document, "STYLE", NULL);
+ webkit_dom_element_set_id (style, "--evolution-editor-style-a");
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (style), "a { cursor: text; }", NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (head), WEBKIT_DOM_NODE (style), NULL);
+ }
+}
+
+static void
+fix_paragraph_structure_after_pressing_enter_after_smiley (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_query_selector (
+ document, "span.-x-evo-smiley-wrapper > br", NULL);
+
+ if (element) {
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element));
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (
+ webkit_dom_node_get_parent_node (parent)),
+ UNICODE_ZERO_WIDTH_SPACE,
+ NULL);
+ }
+}
+
+static void
+mark_node_as_paragraph_after_ending_list (WebKitDOMDocument *document)
+{
+ gint ii, length;
+ WebKitDOMNodeList *list;
+
+ /* When pressing Enter on empty line in the list WebKit will end that
+ * list and inserts <div><br></div> so mark it for wrapping */
+ list = webkit_dom_document_query_selector_all (
+ document, "body > div:not(.-x-evo-paragraph) > br", NULL);
+
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node = webkit_dom_node_get_parent_node (
+ webkit_dom_node_list_item (list, ii));
+
+ dom_set_paragraph_style (WEBKIT_DOM_ELEMENT (node), -1, 0, "");
+ }
+ g_object_unref (list);
+}
+
+static gboolean
+surround_text_with_paragraph_if_needed (WebKitDOMDocument *document,
+ WebKitDOMNode *node)
+{
+ WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
+ WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (node);
+ WebKitDOMElement *element;
+
+ /* All text in composer has to be written in div elements, so if
+ * we are writing something straight to the body, surround it with
+ * paragraph */
+ if (WEBKIT_DOM_IS_TEXT (node) &&
+ WEBKIT_DOM_IS_HTML_BODY_ELEMENT (webkit_dom_node_get_parent_node (node))) {
+ element = dom_put_node_into_paragraph (
+ document, node, dom_caret_position_node (document));
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (next_sibling))
+ remove_node (next_sibling);
+
+ /* Tab character */
+ if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "Apple-tab-span")) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ prev_sibling,
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (element)),
+ NULL);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+body_input_event_cb (WebKitDOMElement *element,
+ WebKitDOMEvent *event,
+ EHTMLEditorWebExtension *extension)
+{
+ gboolean html_mode;
+ WebKitDOMDocument *document;
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+
+ document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
+ range = dom_get_range (document);
+
+ html_mode = is_in_html_mode (extension)
+ set_content_changed (extension);
+
+ if (extension->priv->magic_smileys && html_mode)
+ html_editor_view_check_magic_smileys (view, range);
+
+ if (is_return_key (key_event) || (key_event->keyval == GDK_KEY_space)) {
+ html_editor_view_check_magic_links (view, range, FALSE, key_event);
+ mark_node_as_paragraph_after_ending_list (document);
+ if (html_mode)
+ fix_paragraph_structure_after_pressing_enter_after_smiley (document);
+ } else {
+ WebKitDOMNode *node;
+
+ node = webkit_dom_range_get_end_container (range, NULL);
+
+ if (surround_text_with_paragraph_if_needed (document, node)) {
+ dom_restore_caret_position (document);
+ node = webkit_dom_range_get_end_container (range, NULL);
+ range = dom_get_range (document);
+ }
+
+ if (WEBKIT_DOM_IS_TEXT (node)) {
+ gchar *text;
+
+ text = webkit_dom_node_get_text_content (node);
+
+ if (g_strcmp0 (text, "") != 0 && !g_unichar_isspace (g_utf8_get_char (text))) {
+ WebKitDOMNode *prev_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+
+ if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling))
+ html_editor_view_check_magic_links (view, range, FALSE, key_event);
+ }
+ g_free (text);
+ }
+ }
+
+ node = webkit_dom_range_get_end_container (range, NULL);
+
+ /* After toggling monospaced format, we are using UNICODE_ZERO_WIDTH_SPACE
+ * to move caret into right space. When this callback is called it is not
+ * necassary anymore so remove it */
+ if (html_mode) {
+ WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
+
+ if (parent) {
+ WebKitDOMNode *prev_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (
+ WEBKIT_DOM_NODE (parent));
+
+ if (prev_sibling && WEBKIT_DOM_IS_TEXT (prev_sibling)) {
+ gchar *text = webkit_dom_node_get_text_content (
+ prev_sibling);
+
+ if (g_strcmp0 (text, UNICODE_ZERO_WIDTH_SPACE) == 0)
+ remove_node (prev_sibling);
+
+ g_free (text);
+ }
+
+ }
+ }
+
+ /* If text before caret includes UNICODE_ZERO_WIDTH_SPACE character, remove it */
+ if (WEBKIT_DOM_IS_TEXT (node)) {
+ gchar *text = webkit_dom_character_data_get_data (WEBKIT_DOM_CHARACTER_DATA (node));
+ glong length = g_utf8_strlen (text, -1);
+ WebKitDOMNode *parent;
+
+ /* We have to preserve empty paragraphs with just UNICODE_ZERO_WIDTH_SPACE
+ * character as when we will remove it it will collapse */
+ if (length > 1) {
+ if (g_str_has_prefix (text, UNICODE_ZERO_WIDTH_SPACE))
+ webkit_dom_character_data_replace_data (
+ WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
+ else if (g_str_has_suffix (text, UNICODE_ZERO_WIDTH_SPACE))
+ webkit_dom_character_data_replace_data (
+ WEBKIT_DOM_CHARACTER_DATA (node), length - 1, 1, "", NULL);
+ }
+ g_free (text);
+
+ parent = webkit_dom_node_get_parent_node (node);
+ if ((WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (parent) ||
+ WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) &&
+ !element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph")) {
+ if (html_mode)
+ element_add_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph");
+ else
+ dom_set_paragraph_style (
+ selection, WEBKIT_DOM_ELEMENT (parent), -1, 0, "");
+ }
+
+ /* When new smiley is added we have to use UNICODE_HIDDEN_SPACE to set the
+ * caret position to right place. It is removed when user starts typing. But
+ * when the user will press left arrow he will move the caret into
+ * smiley wrapper. If he will start to write there we have to move the written
+ * text out of the wrapper and move caret to right place */
+ if (WEBKIT_DOM_IS_ELEMENT (parent) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-smiley-wrapper")) {
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ dom_crate_caret_position_node (document),
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ node,
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+ dom_restore_caret_position (document);
+ }
+ }
+
+ /* Writing into quoted content */
+ if (html_mode) {
+ gint citation_level;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMNode *node, *parent;
+ WebKitDOMRange *range;
+
+ range = dom_get_range (document);
+ node = webkit_dom_range_get_end_container (range, NULL);
+
+ citation_level = get_citation_level (node, FALSE);
+ if (citation_level == 0)
+ return;
+
+ selection_start_marker = webkit_dom_document_query_selector (
+ document, "span#-x-evo-selection-start-marker", NULL);
+ if (selection_start_marker)
+ return;
+
+ dom_selection_save (document);
+
+ 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 the selection was not saved, move it into the first child of body */
+ if (!selection_start_marker || !selection_end_marker) {
+ WebKitDOMHTMLElement *body;
+ WebKitDOMNode *child;
+
+ body = webkit_dom_document_get_body (document);
+ child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+
+ add_selection_markers_into_element_start (
+ document,
+ WEBKIT_DOM_ELEMENT (child),
+ &selection_start_marker,
+ &selection_end_marker);
+ }
+
+ /* We have to process elements only inside normal block */
+ parent = WEBKIT_DOM_NODE (get_parent_block_element (
+ WEBKIT_DOM_NODE (selection_start_marker)));
+ if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent)) {
+ dom_selection_restore (document);
+ return;
+ }
+
+ if (selection_start_marker) {
+ gchar *content;
+ gint text_length, word_wrap_length, length;
+ WebKitDOMElement *block;
+ gboolean remove_quoting = FALSE;
+
+ word_wrap_length = extension->priv->word_wrap_length;
+ length = word_wrap_length - 2 * citation_level;
+
+ block = WEBKIT_DOM_ELEMENT (parent);
+ if (webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
+ WebKitDOMNode *prev_sibling;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (
+ WEBKIT_DOM_NODE (selection_end_marker));
+
+ if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
+ remove_quoting = element_has_class (
+ WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
+ }
+
+ content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (block));
+ text_length = g_utf8_strlen (content, -1);
+ g_free (content);
+
+ /* Wrap and quote the line */
+ if (!remove_quoting && text_length >= word_wrap_length) {
+ remove_quoting_from_element (block);
+
+ block = dom_wrap_paragraph_length (document, block, length);
+ webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (block), citation_level);
+ selection_start_marker = webkit_dom_document_query_selector (
+ document, "span#-x-evo-selection-start-marker", NULL);
+ if (!selection_start_marker)
+ add_selection_markers_into_element_end (
+ document,
+ WEBKIT_DOM_ELEMENT (block),
+ NULL,
+ NULL);
+
+ dom_selection_restore (document);
+ dom_force_spell_check_for_current_paragraph (document);
+ return;
+ }
+ }
+ dom_selection_restore (document);
+ }
+}
+
+static void
+remove_input_event_listener_from_body (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ if (!extension->priv->body_input_event_removed) {
+ webkit_dom_event_target_remove_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (
+ webkit_dom_document_get_body (document)),
+ "input",
+ G_CALLBACK (body_input_event_cb),
+ FALSE);
+
+ extension->priv->body_input_event_removed = TRUE;
+ }
+}
+
+static void
+register_input_event_listener_on_body (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ if (extension->priv->body_input_event_removed) {
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (
+ webkit_dom_document_get_body (document)),
+ "input",
+ G_CALLBACK (body_input_event_cb),
+ FALSE,
+ extension);
+
+ extension->priv->body_input_event_removed = FALSE;
+ }
+}
+
+static void
+fix_structure_after_pasting_multiline_content (WebKitDOMNode *node)
+{
+ WebKitDOMNode *first_child, *parent;
+
+ /* When pasting content that does not contain just the
+ * one line text WebKit inserts all the content after the
+ * first line into one element. So we have to take it out
+ * of this element and insert it after that element. */
+ parent = webkit_dom_node_get_parent_node (node);
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent))
+ return;
+ first_child = webkit_dom_node_get_first_child (parent);
+ while (first_child) {
+ WebKitDOMNode *next_child =
+ webkit_dom_node_get_next_sibling (first_child);
+ if (webkit_dom_node_has_child_nodes (first_child))
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ first_child,
+ parent,
+ NULL);
+ first_child = next_child;
+ }
+ remove_node (parent);
+}
+
+static void
+dom_convert_and_insert_html_into_selection (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
+ const gchar *html,
+ gboolean is_html)
+{
+ gboolean has_selection;
+ gchar *inner_html;
+ gint citation_level;
+ WebKitDOMElement *element;
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+
+ remove_input_event_listener_from_body (document);
+
+ element = webkit_dom_document_create_element (document, "div", NULL);
+ if (is_html) {
+ gchar *inner_text;
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
+ inner_text = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (element), inner_text, NULL);
+
+ g_free (inner_text);
+ } else
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+ parse_html_into_paragraphs (document, element, inner_html);
+
+ g_free (inner_html);
+
+ has_selection = !dom_selection_is_collapsed (document);
+
+ range = dom_get_range (document);
+ node = webkit_dom_range_get_end_container (range, NULL);
+ citation_level = get_citation_level (node, FALSE);
+ /* Pasting into the citation */
+ if (citation_level > 0) {
+ gint length;
+ gint word_wrap_length = extension->priv->word_wrap_length;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMElement *br;
+ WebKitDOMNode *first_paragraph, *last_paragraph;
+ WebKitDOMNode *child, *parent;
+
+ dom_selection_save (selection);
+ selection_start_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+ selection_end_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-end-marker");
+
+ first_paragraph = webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (element));
+ last_paragraph = webkit_dom_node_get_last_child (
+ WEBKIT_DOM_NODE (element));
+
+ length = word_wrap_length - 2 * citation_level;
+
+ /* Pasting text that was parsed just into one paragraph */
+ if (webkit_dom_node_is_same_node (first_paragraph, last_paragraph)) {
+ WebKitDOMNode *child, *parent;
+
+ parent = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+ remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+ while ((child = webkit_dom_node_get_first_child (first_paragraph)))
+ webkit_dom_node_insert_before (
+ parent,
+ child,
+ WEBKIT_DOM_NODE (selection_start_marker),
+ NULL);
+
+ parent = WEBKIT_DOM_NODE (
+ dom_wrap_paragraph_length (
+ document, WEBKIT_DOM_ELEMENT (parent), length));
+ webkit_dom_node_normalize (parent);
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (parent), citation_level);
+
+ goto delete;
+ }
+
+ /* Pasting content parsed into the multiple paragraphs */
+ parent = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+ remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+ /* Move the elements from the first paragraph before the selection start element */
+ while ((child = webkit_dom_node_get_first_child (first_paragraph)))
+ webkit_dom_node_insert_before (
+ parent,
+ child,
+ WEBKIT_DOM_NODE (selection_start_marker),
+ NULL);
+
+ remove_node (first_paragraph);
+
+ /* If the BR element is on the last position, remove it as we don't need it */
+ child = webkit_dom_node_get_last_child (parent);
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child))
+ remove_node (child);
+
+ parent = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_end_marker)),
+
+ child = webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (selection_end_marker));
+ /* Move the elements that are in the same paragraph as the selection end
+ * on the end of pasted text, but avoid BR on the end of paragraph */
+ while (child) {
+ WebKitDOMNode *next_child =
+ webkit_dom_node_get_next_sibling (child);
+ if (!(!next_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)))
+ webkit_dom_node_append_child (last_paragraph, child, NULL);
+ child = next_child;
+ }
+
+ /* Caret will be restored on the end of pasted text */
+ webkit_dom_node_append_child (
+ last_paragraph,
+ dom_create_caret_position_node (document),
+ NULL);
+
+ /* Insert the paragraph with the end of the pasted text after
+ * the paragraph that contains the selection end */
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ last_paragraph,
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+
+ /* Wrap, quote and move all paragraphs from pasted text into the body */
+ while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
+ child = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+ document, WEBKIT_DOM_ELEMENT (child), length));
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (child), citation_level);
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (last_paragraph),
+ child,
+ last_paragraph,
+ NULL);
+ }
+
+ webkit_dom_node_normalize (last_paragraph);
+
+ last_paragraph = WEBKIT_DOM_NODE (
+ dom_wrap_paragraph_length (
+ document, WEBKIT_DOM_ELEMENT (last_paragraph), length));
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (last_paragraph), citation_level);
+
+ remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
+ remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
+
+ parent = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+ parent = WEBKIT_DOM_NODE (dom_wrap_paragraph_length (
+ document, WEBKIT_DOM_ELEMENT (parent), length));
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (parent), citation_level);
+
+ /* If the pasted text begun or ended with a new line we have to
+ * quote these paragraphs as well */
+ br = webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (last_paragraph), "br.-x-evo-last-br", NULL);
+ if (br) {
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
+ quote_plain_text_recursive (document, parent, parent, citation_level);
+ webkit_dom_element_remove_attribute (br, "class");
+ }
+
+ br = webkit_dom_document_query_selector (
+ document, "* > br.-x-evo-first-br", NULL);
+ if (br) {
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
+ quote_plain_text_recursive (document, parent, parent, citation_level);
+ webkit_dom_element_remove_attribute (br, "class");
+ }
+ delete:
+ dom_selection_restore (document);
+ /* Remove the text that was meant to be replaced by the pasted text */
+ if (has_selection)
+ dom_exec_command (
+ document, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
+
+ dom_restore_caret_position (document);
+ goto out;
+ }
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+ dom_exec_command (
+ document, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
+ g_free (inner_html);
+
+ dom_selection_save (document);
+
+ element = webkit_dom_document_query_selector (
+ document, "* > br.-x-evo-first-br", NULL);
+ if (element) {
+ WebKitDOMNode *next_sibling;
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (element));
+
+ next_sibling = webkit_dom_node_get_next_sibling (parent);
+ if (next_sibling)
+ remove_node (WEBKIT_DOM_NODE (parent));
+ else
+ webkit_dom_element_remove_attribute (element, "class");
+ }
+
+ element = webkit_dom_document_query_selector (
+ document, "* > br.-x-evo-last-br", NULL);
+ if (element) {
+ WebKitDOMNode *parent;
+ WebKitDOMNode *child;
+ WebKitDOMElement *selection_marker;
+
+ parent = webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (element));
+
+ node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent));
+ if (node) {
+ node = webkit_dom_node_get_first_child (node);
+ if (node) {
+ inner_html = webkit_dom_node_get_text_content (node);
+ if (g_str_has_prefix (inner_html, UNICODE_NBSP))
+ webkit_dom_character_data_replace_data (
+ WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
+ g_free (inner_html);
+ }
+ }
+
+ selection_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-end-marker");
+
+ if (has_selection) {
+ /* Everything after the selection end marker have to be in separate
+ * paragraph */
+ child = webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (selection_marker));
+ /* Move the elements that are in the same paragraph as the selection end
+ * on the end of pasted text, but avoid BR on the end of paragraph */
+ while (child) {
+ WebKitDOMNode *next_child =
+ webkit_dom_node_get_next_sibling (child);
+ if (!(!next_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)))
+ webkit_dom_node_append_child (parent, child, NULL);
+ child = next_child;
+ }
+
+ remove_node (WEBKIT_DOM_NODE (element));
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (
+ webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (selection_marker))),
+ parent,
+ webkit_dom_node_get_next_sibling (
+ webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (selection_marker))),
+ NULL);
+ node = parent;
+ } else {
+ node = webkit_dom_node_get_next_sibling (parent);
+ if (!node)
+ fix_structure_after_pasting_multiline_content (parent);
+ }
+
+ if (node) {
+ /* Restore caret on the end of pasted text */
+ webkit_dom_node_insert_before (
+ node,
+ WEBKIT_DOM_NODE (selection_marker),
+ webkit_dom_node_get_first_child (node),
+ NULL);
+
+ selection_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+ webkit_dom_node_insert_before (
+ node,
+ WEBKIT_DOM_NODE (selection_marker),
+ webkit_dom_node_get_first_child (node),
+ NULL);
+ }
+
+ if (element)
+ webkit_dom_element_remove_attribute (element, "class");
+
+ if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)) && !has_selection)
+ remove_node (parent);
+ } else {
+ /* When pasting the content that was copied from the composer, WebKit
+ * restores the selection wrongly, thus is saved wrongly and we have
+ * to fix it */
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMNode *paragraph, *parent;
+
+ selection_start_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+ selection_end_marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-end-marker");
+
+ paragraph = get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker));
+ parent = webkit_dom_node_get_parent_node (paragraph);
+ if (element_has_class (WEBKIT_DOM_ELEMENT (paragraph), "-x-evo-paragraph") &&
+ element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph"))
+ fix_structure_after_pasting_multiline_content (paragraph);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (selection_start_marker)),
+ WEBKIT_DOM_NODE (selection_end_marker),
+ webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (selection_start_marker)),
+ NULL);
+ }
+
+ dom_selection_restore (document);
+ out:
+ dom_force_spell_check (document);
+ dom_scroll_to_caret (document);
+
+ register_input_event_listener_on_body (document);
+}
+
+void
+dom_quote_and_insert_text_into_selection (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
+ const gchar *text)
+{
+ gchar *escaped_text;
+ WebKitDOMElement *blockquote, *element;
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+
+ if (!text || !*text)
+ return;
+
+ /* This is a trick to escape any HTML characters (like <, > or &).
+ * <textarea> automatically replaces all these unsafe characters
+ * by <, > etc. */
+ element = webkit_dom_document_create_element (document, "textarea", NULL);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element), text, NULL);
+ escaped_text = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element));
+
+ element = webkit_dom_document_create_element (document, "pre", NULL);
+
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (element), escaped_text, NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element),
+ dom_create_caret_position_node (document),
+ NULL);
+
+ blockquote = webkit_dom_document_create_element (document, "blockquote", NULL);
+ webkit_dom_element_set_attribute (blockquote, "type", "cite", NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (blockquote), WEBKIT_DOM_NODE (element), NULL);
+
+ if (!is_in_html_mode (extension))
+ dom_quote_plain_text_element (document, element);
+
+ range = dom_get_range (document);
+ node = webkit_dom_range_get_end_container (range, NULL);
+
+ webkit_dom_node_append_child (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (blockquote),
+ NULL);
+
+ dom_restore_caret_position (document);
+
+ dom_force_spell_check_for_current_paragraph (document);
+
+ g_free (escaped_text);
+}
+
+gboolean
+dom_change_quoted_block_to_normal (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ gboolean html_mode;
+ gint citation_level, success = FALSE;
+ WebKitDOMElement *selection_start_marker, *selection_end_marker, *block;
+
+ html_mode = is_in_html_mode (extension);
+
+ 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 || !selection_end_marker)
+ return FALSE;
+
+ block = WEBKIT_DOM_ELEMENT (get_parent_block_node_from_child (
+ WEBKIT_DOM_NODE (selection_start_marker)));
+
+ citation_level = get_citation_level (
+ WEBKIT_DOM_NODE (selection_start_marker), FALSE);
+
+ if (selection_start_marker && citation_level > 0) {
+ if (webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
+
+ WebKitDOMNode *prev_sibling;
+
+ webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (
+ WEBKIT_DOM_NODE (selection_start_marker));
+
+ if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
+ success = element_has_class (
+ WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
+ /* We really have to be in the beginning of paragraph and
+ * not on the beginning of some line in the paragraph */
+ if (success && webkit_dom_node_get_previous_sibling (prev_sibling))
+ success = FALSE;
+ }
+
+ if (html_mode)
+ success = WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (
+ webkit_dom_node_get_parent_element (
+ WEBKIT_DOM_NODE (block)));
+ }
+
+ if (!success)
+ return FALSE;
+
+ if (citation_level == 1) {
+ gchar *inner_html;
+ WebKitDOMElement *paragraph;
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (block));
+ webkit_dom_element_set_id (
+ WEBKIT_DOM_ELEMENT (block), "-x-evo-to-remove");
+
+ paragraph = insert_new_line_into_citation (document, inner_html);
+ g_free (inner_html);
+
+ if (paragraph) {
+ if (html_mode) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (paragraph),
+ WEBKIT_DOM_NODE (selection_start_marker),
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (paragraph)),
+ NULL);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (paragraph),
+ WEBKIT_DOM_NODE (selection_end_marker),
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (paragraph)),
+ NULL);
+
+ }
+
+ remove_quoting_from_element (paragraph);
+ remove_wrapping_from_element (paragraph);
+ }
+
+ if (block)
+ remove_node (WEBKIT_DOM_NODE (block));
+ block = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-to-remove");
+ if (block)
+ remove_node (WEBKIT_DOM_NODE (block));
+
+ if (paragraph)
+ remove_node_if_empty (
+ webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (paragraph)));
+ }
+
+ if (citation_level > 1) {
+ gint length, word_wrap_length;
+ WebKitDOMNode *parent;
+
+ word_wrap_length = extension->priv->word_wrap_length;
+ length = word_wrap_length - 2 * (citation_level - 1);
+
+ if (html_mode) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (block),
+ WEBKIT_DOM_NODE (selection_start_marker),
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (block)),
+ NULL);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (block),
+ WEBKIT_DOM_NODE (selection_end_marker),
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (block)),
+ NULL);
+
+ }
+
+ remove_quoting_from_element (block);
+ remove_wrapping_from_element (block);
+
+ block = dom_wrap_paragraph_length (document, block, length);
+ webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
+ quote_plain_text_element_after_wrapping (document, block, citation_level - 1);
+
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (block));
+
+ if (!webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (block))) {
+ /* Currect block is in the beginning of citation, just move it
+ * before the citation where already is */
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ WEBKIT_DOM_NODE (block),
+ parent,
+ NULL);
+ } else if (!webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block))) {
+ /* Currect block is at the end of the citation, just move it
+ * after the citation where already is */
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ WEBKIT_DOM_NODE (block),
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+ } else {
+ /* Current block is somewhere in the middle of the citation
+ * so we need to split the citation and insert the block into
+ * the citation that is one level lower */
+ WebKitDOMNode *clone, *child;
+
+ clone = webkit_dom_node_clone_node (parent, FALSE);
+
+ /* Move nodes that are after the currect block into the
+ * new blockquote */
+ child = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block));
+ while (child) {
+ WebKitDOMNode *next = webkit_dom_node_get_next_sibling (child);
+ webkit_dom_node_append_child (clone, child, NULL);
+ child = next;
+ }
+
+ clone = webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ clone,
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ WEBKIT_DOM_NODE (block),
+ clone,
+ NULL);
+ }
+ }
+
+ return success;
+}
+
+static gboolean
+prevent_from_deleting_last_element_in_body (WebKitDOMDocument *document)
+{
+ gboolean ret_val = FALSE;
+ WebKitDOMHTMLElement *body;
+ WebKitDOMNodeList *list;
+
+ body = webkit_dom_document_get_body (document);
+
+ list = webkit_dom_node_get_child_nodes (WEBKIT_DOM_NODE (body));
+
+ if (webkit_dom_node_list_get_length (list) <= 1) {
+ gchar *content;
+
+ content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (body));
+
+ if (!*content)
+ ret_val = TRUE;
+
+ g_free (content);
+
+ if (webkit_dom_element_query_selector (WEBKIT_DOM_ELEMENT (body), "img", NULL))
+ ret_val = FALSE;
+ }
+ g_object_unref (list);
+
+ return ret_val;
+}
+
+static void
+insert_quote_symbols (WebKitDOMHTMLElement *element,
+ gint quote_level,
+ gboolean skip_first,
+ gboolean insert_newline)
+{
+ gchar *text;
+ gint ii;
+ GString *output;
+ gchar *quotation;
+
+ if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
+ return;
+
+ text = webkit_dom_html_element_get_inner_html (element);
+ output = g_string_new ("");
+ quotation = get_quotation_for_level (quote_level);
+
+ if (g_strcmp0 (text, "\n") == 0) {
+ g_string_append (output, "<span class=\"-x-evo-quoted\">");
+ g_string_append (output, quotation);
+ g_string_append (output, "</span>");
+ g_string_append (output, "\n");
+ } else {
+ gchar **lines;
+
+ lines = g_strsplit (text, "\n", 0);
+
+ for (ii = 0; lines[ii]; ii++) {
+ if (ii == 0 && skip_first) {
+ if (g_strv_length (lines) == 1) {
+ g_strfreev (lines);
+ goto exit;
+ }
+ g_string_append (output, lines[ii]);
+ g_string_append (output, "\n");
+ }
+
+ g_string_append (output, "<span class=\"-x-evo-quoted\">");
+ g_string_append (output, quotation);
+ g_string_append (output, "</span>");
+
+ /* Insert line of text */
+ g_string_append (output, lines[ii]);
+ if ((ii == g_strv_length (lines) - 1) &&
+ !g_str_has_suffix (text, "\n") && !insert_newline) {
+ /* If we are on last line and node's text doesn't
+ * end with \n, don't insert it */
+ break;
+ }
+ g_string_append (output, "\n");
+ }
+
+ g_strfreev (lines);
+ }
+
+ webkit_dom_html_element_set_inner_html (element, output->str, NULL);
+ exit:
+ g_free (quotation);
+ g_free (text);
+ g_string_free (output, TRUE);
+}
+
+static void
+quote_node (WebKitDOMDocument *document,
+ WebKitDOMNode *node,
+ gint quote_level)
+{
+ gboolean skip_first = FALSE;
+ gboolean insert_newline = FALSE;
+ gboolean is_html_node = FALSE;
+ WebKitDOMElement *wrapper;
+ WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
+
+ /* Don't quote when we are not in citation */
+ if (quote_level == 0)
+ return;
+
+ if (WEBKIT_DOM_IS_COMMENT (node))
+ return;
+
+ if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
+ insert_quote_symbols (
+ WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
+ return;
+ }
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+ next_sibling = webkit_dom_node_get_next_sibling (node);
+
+ is_html_node =
+ !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
+ !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
+ WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling) ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "b") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "i") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "u"));
+
+ if (prev_sibling && is_html_node)
+ skip_first = TRUE;
+
+ /* Skip the BR between first blockquote and pre */
+ if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
+ return;
+
+ /* Do temporary wrapper */
+ wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
+ webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
+
+ node_clone = webkit_dom_node_clone_node (node, TRUE);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (wrapper),
+ node_clone,
+ NULL);
+
+ insert_quote_symbols (
+ WEBKIT_DOM_HTML_ELEMENT (wrapper),
+ quote_level,
+ skip_first,
+ insert_newline);
+
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (wrapper),
+ node,
+ NULL);
+}
+
+static void
+insert_quote_symbols_before_node (WebKitDOMDocument *document,
+ WebKitDOMNode *node,
+ gint quote_level,
+ gboolean is_html_node)
+{
+ gboolean skip, wrap_br;
+ gchar *quotation;
+ WebKitDOMElement *element;
+
+ quotation = get_quotation_for_level (quote_level);
+ element = webkit_dom_document_create_element (document, "SPAN", NULL);
+ element_add_class (element, "-x-evo-quoted");
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (element), quotation, NULL);
+
+ /* Don't insert temporary BR before BR that is used for wrapping */
+ skip = WEBKIT_DOM_IS_HTML_BR_ELEMENT (node);
+ wrap_br = element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br");
+ skip = skip && wrap_br;
+
+ if (is_html_node && !skip) {
+ WebKitDOMElement *new_br;
+
+ new_br = webkit_dom_document_create_element (document, "br", NULL);
+ element_add_class (new_br, "-x-evo-temp-br");
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (new_br),
+ node,
+ NULL);
+ }
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (node),
+ WEBKIT_DOM_NODE (element),
+ node,
+ NULL);
+
+ if (is_html_node && !wrap_br)
+ remove_node (node);
+
+ g_free (quotation);
+}
+
+static gboolean
+element_is_selection_marker (WebKitDOMElement *element)
+{
+ gboolean is_marker = FALSE;
+
+ is_marker =
+ element_has_id (element, "-x-evo-selection-start-marker") ||
+ element_has_id (element, "-x-evo-selection-end-marker");
+
+ return is_marker;
+}
+
+static gboolean
+check_if_suppress_next_node (WebKitDOMNode *node)
+{
+ if (!node)
+ return FALSE;
+
+ if (node && WEBKIT_DOM_IS_ELEMENT (node))
+ if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
+ if (!webkit_dom_node_get_previous_sibling (node))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+quote_br_node (WebKitDOMNode *node,
+ gint quote_level)
+{
+ gchar *quotation, *content;
+
+ quotation = get_quotation_for_level (quote_level);
+
+ content = g_strconcat (
+ "<span class=\"-x-evo-quoted\">",
+ quotation,
+ "</span><br class=\"-x-evo-temp-br\">",
+ NULL);
+
+ webkit_dom_html_element_set_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (node),
+ content,
+ NULL);
+
+ g_free (content);
+ g_free (quotation);
+}
+
+static void
+quote_plain_text_recursive (WebKitDOMDocument *document,
+ WebKitDOMNode *node,
+ WebKitDOMNode *start_node,
+ gint quote_level)
+{
+ gboolean skip_node = FALSE;
+ gboolean move_next = FALSE;
+ gboolean suppress_next = FALSE;
+ gboolean is_html_node = FALSE;
+ gboolean next = FALSE;
+ WebKitDOMNode *next_sibling, *prev_sibling;
+
+ node = webkit_dom_node_get_first_child (node);
+
+ while (node) {
+ gchar *text_content;
+
+ skip_node = FALSE;
+ move_next = FALSE;
+ is_html_node = FALSE;
+
+ if (WEBKIT_DOM_IS_COMMENT (node) ||
+ WEBKIT_DOM_IS_HTML_META_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
+
+ move_next = TRUE;
+ goto next_node;
+ }
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (node);
+ next_sibling = webkit_dom_node_get_next_sibling (node);
+
+ if (WEBKIT_DOM_IS_TEXT (node)) {
+ /* Start quoting after we are in blockquote */
+ if (quote_level > 0 && !suppress_next) {
+ /* When quoting text node, we are wrappering it and
+ * afterwards replacing it with that wrapper, thus asking
+ * for next_sibling after quoting will return NULL bacause
+ * that node don't exist anymore */
+ quote_node (document, node, quote_level);
+ node = next_sibling;
+ skip_node = TRUE;
+ }
+
+ goto next_node;
+ }
+
+ if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
+ goto next_node;
+
+ if (element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-position")) {
+ if (quote_level > 0)
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-quoting");
+
+ move_next = TRUE;
+ suppress_next = TRUE;
+ next = FALSE;
+ goto next_node;
+ }
+
+ if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
+ /* If there is collapsed selection in the beginning of line
+ * we cannot suppress first text that is after the end of
+ * selection */
+ suppress_next = check_if_suppress_next_node (prev_sibling);
+ if (suppress_next)
+ next = FALSE;
+ move_next = TRUE;
+ goto next_node;
+ }
+
+ if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) &&
+ webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
+ goto with_children;
+
+ /* Even in plain text mode we can have some basic html element
+ * like anchor and others. When Forwaring e-mail as Quoted EMFormat
+ * generates header that contatains <b> tags (bold font).
+ * We have to treat these elements separately to avoid
+ * modifications of theirs inner texts */
+ is_html_node =
+ WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (node), "b") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (node), "i") ||
+ element_has_tag (WEBKIT_DOM_ELEMENT (node), "u");
+
+ if (is_html_node) {
+ gboolean wrap_br;
+
+ wrap_br =
+ prev_sibling &&
+ WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling) &&
+ element_has_class (
+ WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-wrap-br");
+
+ if (!prev_sibling || wrap_br)
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling) && !wrap_br)
+ insert_quote_symbols_before_node (
+ document, prev_sibling, quote_level, TRUE);
+
+ move_next = TRUE;
+ goto next_node;
+ }
+
+ /* If element doesn't have children, we can quote it */
+ if (is_citation_node (node)) {
+ /* Citation with just text inside */
+ quote_node (document, node, quote_level + 1);
+ /* Set citation as quoted */
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (node),
+ "-x-evo-plaintext-quoted");
+
+ move_next = TRUE;
+ goto next_node;
+ }
+
+ if (!WEBKIT_DOM_IS_HTML_BR_ELEMENT (node)) {
+ if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
+ move_next = TRUE;
+ goto next_node;
+ }
+ goto not_br;
+ } else if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-first-br") ||
+ element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-last-br")) {
+ quote_br_node (node, quote_level);
+ node = next_sibling;
+ skip_node = TRUE;
+ goto next_node;
+ }
+
+ if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+ WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+ /* Situation when anchors are alone on line */
+ text_content = webkit_dom_node_get_text_content (prev_sibling);
+
+ if (g_str_has_suffix (text_content, "\n")) {
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+ remove_node (node);
+ g_free (text_content);
+ node = next_sibling;
+ skip_node = TRUE;
+ goto next_node;
+ }
+ g_free (text_content);
+ }
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling)) {
+ quote_br_node (prev_sibling, quote_level);
+ node = next_sibling;
+ skip_node = TRUE;
+ goto next_node;
+ }
+
+ if (!prev_sibling && !next_sibling) {
+ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+ if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) ||
+ WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) ||
+ (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
+ !is_citation_node (parent))) {
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+
+ goto next_node;
+ }
+ }
+
+ if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
+ text_content = webkit_dom_node_get_text_content (prev_sibling);
+ if (text_content && !*text_content) {
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+
+ g_free (text_content);
+ goto next_node;
+
+ }
+
+ g_free (text_content);
+ }
+
+ if (is_citation_node (prev_sibling)) {
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+ goto next_node;
+ }
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node) &&
+ !next_sibling &&
+ element_is_selection_marker (WEBKIT_DOM_ELEMENT (prev_sibling))) {
+ insert_quote_symbols_before_node (
+ document, node, quote_level, FALSE);
+ goto next_node;
+ }
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node)) {
+ move_next = TRUE;
+ goto next_node;
+ }
+
+ not_br:
+ text_content = webkit_dom_node_get_text_content (node);
+ if (text_content && !*text_content) {
+ g_free (text_content);
+ move_next = TRUE;
+ goto next_node;
+ }
+ g_free (text_content);
+
+ quote_node (document, node, quote_level);
+
+ move_next = TRUE;
+ goto next_node;
+
+ with_children:
+ if (is_citation_node (node)) {
+ /* Go deeper and increase level */
+ quote_plain_text_recursive (
+ document, node, start_node, quote_level + 1);
+ /* set citation as quoted */
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (node),
+ "-x-evo-plaintext-quoted");
+ move_next = TRUE;
+ } else {
+ quote_plain_text_recursive (
+ document, node, start_node, quote_level);
+ move_next = TRUE;
+ }
+ next_node:
+ if (next) {
+ suppress_next = FALSE;
+ next = FALSE;
+ }
+
+ if (suppress_next)
+ next = TRUE;
+
+ if (!skip_node) {
+ /* Move to next node */
+ if (!move_next && webkit_dom_node_has_child_nodes (node)) {
+ node = webkit_dom_node_get_first_child (node);
+ } else if (webkit_dom_node_get_next_sibling (node)) {
+ node = webkit_dom_node_get_next_sibling (node);
+ } else {
+ return;
+ }
+ }
+ }
+}
+
+WebKitDOMElement *
+dom_quote_plain_text_element (WebKitDOMDocument *document,
+ WebKitDOMElement *element)
+{
+ WebKitDOMNode *element_clone;
+ WebKitDOMNodeList *list;
+ gint ii, length, level;
+
+ element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
+ level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
+
+ /* Remove old quote characters if the exists */
+ list = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++)
+ remove_node (webkit_dom_node_list_item (list, ii));
+
+ webkit_dom_node_normalize (element_clone);
+ quote_plain_text_recursive (
+ document, element_clone, element_clone, level);
+
+ /* Set citation as quoted */
+ if (is_citation_node (element_clone))
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (element_clone),
+ "-x-evo-plaintext-quoted");
+
+ /* Replace old element with one, that is quoted */
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
+ element_clone,
+ WEBKIT_DOM_NODE (element),
+ NULL);
+
+ g_object_unref (list);
+ return WEBKIT_DOM_ELEMENT (element_clone);
+}
+
+/**
+ * e_html_editor_view_quote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Quote text inside citation blockquotes in plain text mode.
+ *
+ * As this function is cloning and replacing all citation blockquotes keep on
+ * mind that any pointers to nodes inside these blockquotes will be invalidated.
+ */
+WebKitDOMElement *
+dom_quote_plain_text (WebKitDOMDocument *document)
+{
+ WebKitDOMHTMLElement *body;
+ WebKitDOMNode *body_clone;
+ WebKitDOMNamedNodeMap *attributes;
+ WebKitDOMNodeList *list;
+ WebKitDOMElement *element;
+ gint ii, length;
+ gulong attributes_length;
+
+ /* Check if the document is already quoted */
+ element = webkit_dom_document_query_selector (
+ document, ".-x-evo-plaintext-quoted", NULL);
+ if (element)
+ return NULL;
+
+ body = webkit_dom_document_get_body (document);
+ body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+ /* Clean unwanted spaces before and after blockquotes */
+ list = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
+ WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
+ WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
+
+ if (prev_sibling && WEBKIT_DOM_IS_HTML_BR_ELEMENT (prev_sibling))
+ remove_node (prev_sibling);
+
+ if (next_sibling && WEBKIT_DOM_IS_HTML_BR_ELEMENT (next_sibling))
+ remove_node (next_sibling);
+
+ if (webkit_dom_node_has_child_nodes (blockquote)) {
+ WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child))
+ remove_node (child);
+ }
+ }
+ g_object_unref (list);
+
+ webkit_dom_node_normalize (body_clone);
+ quote_plain_text_recursive (document, body_clone, body_clone, 0);
+
+ /* Copy attributes */
+ attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
+ attributes_length = webkit_dom_named_node_map_get_length (attributes);
+ for (ii = 0; ii < attributes_length; ii++) {
+ gchar *name, *value;
+ WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+ name = webkit_dom_node_get_local_name (node);
+ value = webkit_dom_node_get_node_value (node);
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
+
+ g_free (name);
+ g_free (value);
+ }
+ g_object_unref (attributes);
+
+ /* Replace old BODY with one, that is quoted */
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
+ body_clone,
+ WEBKIT_DOM_NODE (body),
+ NULL);
+
+ return WEBKIT_DOM_ELEMENT (body_clone);
+}
+
+/**
+ * e_html_editor_view_dequote_plain_text:
+ * @view: an #EHTMLEditorView
+ *
+ * Dequote already quoted plain text in editor.
+ * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
+ * it's not working.
+ */
+void
+dom_dequote_plain_text (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *paragraphs;
+ gint length, ii;
+
+ paragraphs = webkit_dom_document_query_selector_all (
+ document, "blockquote.-x-evo-plaintext-quoted", NULL);
+ length = webkit_dom_node_list_get_length (paragraphs);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMElement *element;
+
+ element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
+
+ if (is_citation_node (WEBKIT_DOM_NODE (element))) {
+ element_remove_class (element, "-x-evo-plaintext-quoted");
+ remove_quoting_from_element (element);
+ }
+ }
+ g_object_unref (paragraphs);
+}
+
+static gboolean
+create_anchor_for_link (const GMatchInfo *info,
+ GString *res,
+ gpointer data)
+{
+ gint offset = 0;
+ gchar *match;
+ gboolean address_surrounded;
+
+ match = g_match_info_fetch (info, 0);
+
+ address_surrounded =
+ strstr (match, "@") &&
+ g_str_has_prefix (match, "<") &&
+ g_str_has_suffix (match, ">");
+
+ if (address_surrounded)
+ offset += 4;
+
+ if (g_str_has_prefix (match, " "))
+ offset += 6;
+
+ if (address_surrounded)
+ g_string_append (res, "<");
+
+ g_string_append (res, "<a href=\"");
+ if (strstr (match, "@")) {
+ g_string_append (res, "mailto:");
+ g_string_append (res, match + offset);
+ if (address_surrounded)
+ g_string_truncate (res, res->len - 4);
+
+ g_string_append (res, "\">");
+ g_string_append (res, match + offset);
+ if (address_surrounded)
+ g_string_truncate (res, res->len - 4);
+ } else {
+ g_string_append (res, match + offset);
+ g_string_append (res, "\">");
+ g_string_append (res, match + offset);
+ }
+ g_string_append (res, "</a>");
+
+ if (address_surrounded)
+ g_string_append (res, ">");
+
+ g_free (match);
+
+ return FALSE;
+}
+
+static gboolean
+replace_to_nbsp (const GMatchInfo *info,
+ GString *res,
+ gboolean use_nbsp)
+{
+ gchar *match;
+ const gchar *string, *previous_tab;
+ gint ii, length = 0, start = 0;
+
+ match = g_match_info_fetch (info, 0);
+ g_match_info_fetch_pos (info, 0, &start, NULL);
+ string = g_match_info_get_string (info);
+
+ if (start > 0) {
+ previous_tab = g_strrstr_len (string, start, "\x9");
+ if (previous_tab && *previous_tab) {
+ const char *act_tab = NULL;
+ act_tab = strstr (previous_tab + 1, "\x9");
+
+ if (act_tab && *act_tab) {
+ length = act_tab - previous_tab - 1;
+ length = TAB_LENGTH - length;
+ }
+ }
+ }
+
+ if (length == 0) {
+ if (strstr (match, "\x9")) {
+ gint tab_count = strlen (match);
+ length = TAB_LENGTH - (start % TAB_LENGTH);
+ length += (tab_count - 1) * TAB_LENGTH;
+ } else
+ length = strlen (match);
+ }
+
+ for (ii = 0; ii < length; ii++)
+ g_string_append (res, " ");
+
+ g_free (match);
+
+ return FALSE;
+}
+
+static gboolean
+surround_links_with_anchor (const gchar *text)
+{
+ return (strstr (text, "http") || strstr (text, "ftp") ||
+ strstr (text, "www") || strstr (text, "@"));
+}
+
+static void
+append_new_paragraph (WebKitDOMElement *parent,
+ WebKitDOMElement **paragraph)
+{
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (parent),
+ WEBKIT_DOM_NODE (*paragraph),
+ NULL);
+
+ *paragraph = NULL;
+}
+
+static WebKitDOMElement *
+create_and_append_new_paragraph (WebKitDOMDocument *document,
+ WebKitDOMElement *parent,
+ const gchar *content)
+{
+ WebKitDOMElement *paragraph;
+
+ paragraph = dom_get_paragraph_element (document, -1, 0);
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (paragraph),
+ content,
+ NULL);
+
+ append_new_paragraph (parent, ¶graph);
+
+ return paragraph;
+}
+
+static void
+append_citation_mark (WebKitDOMDocument *document,
+ WebKitDOMElement *parent,
+ const gchar *citation_mark_text)
+{
+ WebKitDOMText *text;
+
+ text = webkit_dom_document_create_text_node (document, citation_mark_text);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (parent),
+ WEBKIT_DOM_NODE (text),
+ NULL);
+}
+
+static glong
+get_decoded_line_length (WebKitDOMDocument *document,
+ const gchar *line_text)
+{
+ gchar *decoded_text;
+ glong length = 0;
+ WebKitDOMElement *decode;
+
+ decode = webkit_dom_document_create_element (document, "DIV", NULL);
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (decode), line_text, NULL);
+
+ decoded_text = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (decode));
+ length = g_utf8_strlen (decoded_text, -1);
+
+ g_free (decoded_text);
+ g_object_unref (decode);
+
+ return length;
+}
+
+static gboolean
+check_if_end_paragraph (const gchar *input,
+ glong length)
+{
+ const gchar *next_space;
+
+ next_space = strstr (input, " ");
+ if (next_space) {
+ const gchar *next_br;
+ glong length_next_word =
+ next_space - input - 4;
+
+ if (g_str_has_prefix (input + 4, "<br>"))
+ length_next_word = 0;
+
+ if (length_next_word > 0)
+ next_br = strstr (input + 4, "<br>");
+
+ if (length_next_word > 0 && next_br < next_space)
+ length_next_word = 0;
+
+ if (length_next_word + length < 72)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* This parses the HTML code (that contains just text, and BR elements)
+ * into paragraphs.
+ * HTML code in that format we can get by taking innerText from some element,
+ * setting it to another one and finally getting innerHTML from it */
+static void
+parse_html_into_paragraphs (WebKitDOMDocument *document,
+ WebKitDOMElement *blockquote,
+ const gchar *html)
+{
+ gboolean ignore_next_br = FALSE;
+ gboolean first_element = TRUE;
+ gboolean citation_was_first_element = FALSE;
+ const gchar *prev_br, *next_br;
+ gchar *inner_html;
+ GRegex *regex_nbsp = NULL, *regex_links = NULL;
+ GString *start, *end;
+ WebKitDOMElement *paragraph = NULL;
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (blockquote), "", NULL);
+
+ prev_br = html;
+ next_br = strstr (prev_br, "<br>");
+
+ /* Replace single spaces on the beginning of line, 2+ spaces and
+ * tabulators with non breaking spaces */
+ regex_nbsp = g_regex_new ("^\\s{1}|\\s{2,}|\x9", 0, 0, NULL);
+ regex_links = g_regex_new (URL_PATTERN, 0, 0, NULL);
+
+ while (next_br) {
+ gboolean local_ignore_next_br = ignore_next_br;
+ gboolean prevent_block = TRUE;
+ const gchar *citation = NULL, *citation_end = NULL;
+ const gchar *rest = NULL, *with_br = NULL;
+ gchar *to_insert = NULL;
+
+ ignore_next_br = FALSE;
+
+ to_insert = g_utf8_substring (
+ prev_br, 0, g_utf8_pointer_to_offset (prev_br, next_br));
+
+ with_br = strstr (to_insert, "<br>");
+ citation = strstr (to_insert, "##CITATION_");
+ if (citation) {
+ gchar *citation_mark;
+
+ if (strstr (citation, "END##")) {
+ ignore_next_br = TRUE;
+ if (paragraph)
+ append_new_paragraph (blockquote, ¶graph);
+ }
+
+ citation_end = strstr (citation + 2, "##");
+ if (citation_end)
+ rest = citation_end + 2;
+
+ if (first_element)
+ citation_was_first_element = TRUE;
+
+ if (paragraph)
+ append_new_paragraph (blockquote, ¶graph);
+
+ citation_mark = g_utf8_substring (
+ citation, 0, g_utf8_pointer_to_offset (citation, rest));
+
+ append_citation_mark (document, blockquote, citation_mark);
+
+ g_free (citation_mark);
+ } else
+ rest = with_br ?
+ to_insert + 4 + (with_br - to_insert) : to_insert;
+
+ if (!rest)
+ goto next;
+
+ if (*rest) {
+ gboolean empty = FALSE;
+ gchar *truncated = g_strdup (rest);
+ gchar *rest_to_insert;
+
+ g_strchomp (truncated);
+ empty = !*truncated && strlen (rest) > 0;
+
+ if (strchr (" +- *=", *rest))
+ prevent_block = FALSE;
+
+ rest_to_insert = g_regex_replace_eval (
+ regex_nbsp,
+ empty ? rest : truncated,
+ -1,
+ 0,
+ 0,
+ (GRegexEvalCallback) replace_to_nbsp,
+ NULL,
+ NULL);
+ g_free (truncated);
+
+ if (surround_links_with_anchor (rest_to_insert)) {
+ truncated = g_regex_replace_eval (
+ regex_links,
+ rest_to_insert,
+ -1,
+ 0,
+ 0,
+ create_anchor_for_link,
+ NULL,
+ NULL);
+
+ g_free (rest_to_insert);
+ rest_to_insert = truncated;
+ }
+
+ if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0) {
+ paragraph = create_and_append_new_paragraph (
+ document, blockquote, "<br>");
+ } else if (prevent_block) {
+ gchar *html;
+ gchar *new_content;
+
+ if (!paragraph)
+ paragraph = dom_get_paragraph_element (
+ document, -1, 0);
+
+ html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (paragraph));
+
+ new_content = g_strconcat (
+ html && *html ? html : "",
+ html && *html ? " " : "",
+ rest_to_insert ? rest_to_insert : "<br>",
+ NULL),
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (paragraph),
+ new_content,
+ NULL);
+
+ g_free (html);
+ g_free (new_content);
+ } else
+ paragraph = create_and_append_new_paragraph (
+ document, blockquote, rest_to_insert);
+
+ if (rest_to_insert && *rest_to_insert && prevent_block && paragraph) {
+ glong length = 0;
+
+ if (strstr (rest, "&"))
+ length = get_decoded_line_length (document, rest);
+ else
+ length = g_utf8_strlen (rest, -1);
+
+ /* End the block if there is line with less that 62 characters. */
+ /* The shorter line can also mean that there is a long word on next
+ * line (and the line was wrapped). So look at it and decide what to do. */
+ if (length < 62 && check_if_end_paragraph (next_br, length))
+ append_new_paragraph (blockquote, ¶graph);
+
+ if (length > 72)
+ append_new_paragraph (blockquote, ¶graph);
+ }
+
+ citation_was_first_element = FALSE;
+
+ g_free (rest_to_insert);
+ } else if (with_br) {
+ if (!citation && (!local_ignore_next_br || citation_was_first_element)) {
+ if (paragraph)
+ append_new_paragraph (blockquote, ¶graph);
+
+ paragraph = create_and_append_new_paragraph (
+ document, blockquote, "<br>");
+
+ citation_was_first_element = FALSE;
+ } else if (first_element && !citation_was_first_element) {
+ paragraph = create_and_append_new_paragraph (
+ document,
+ blockquote,
+ "<br class=\"-x-evo-first-br\">");
+ }
+ }
+ next:
+ first_element = FALSE;
+ prev_br = next_br;
+ next_br = strstr (prev_br + 4, "<br>");
+ g_free (to_insert);
+ }
+
+ if (paragraph)
+ append_new_paragraph (blockquote, ¶graph);
+
+ if (g_utf8_strlen (prev_br, -1) > 0) {
+ gchar *rest_to_insert;
+ gchar *truncated = g_strdup (
+ g_str_has_prefix (prev_br, "<br>") ? prev_br + 4 : prev_br);
+
+ /* On the end on the HTML there is always an extra BR element,
+ * so skip it and if there was another BR element before it mark it. */
+ if (truncated && !*truncated) {
+ WebKitDOMNode *child;
+
+ child = webkit_dom_node_get_last_child (
+ WEBKIT_DOM_NODE (blockquote));
+ if (child) {
+ child = webkit_dom_node_get_first_child (child);
+ if (child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)) {
+ element_add_class (
+ WEBKIT_DOM_ELEMENT (child),
+ "-x-evo-last-br");
+ }
+ }
+ g_free (truncated);
+ goto end;
+ }
+
+ if (g_ascii_strncasecmp (truncated, "##CITATION_END##", 16) == 0) {
+ append_citation_mark (document, blockquote, truncated);
+ g_free (truncated);
+ goto end;
+ }
+
+ g_strchomp (truncated);
+
+ rest_to_insert = g_regex_replace_eval (
+ regex_nbsp,
+ truncated,
+ -1,
+ 0,
+ 0,
+ (GRegexEvalCallback) replace_to_nbsp,
+ NULL,
+ NULL);
+ g_free (truncated);
+
+ if (surround_links_with_anchor (rest_to_insert)) {
+ truncated = g_regex_replace_eval (
+ regex_links,
+ rest_to_insert,
+ -1,
+ 0,
+ 0,
+ create_anchor_for_link,
+ NULL,
+ NULL);
+
+ g_free (rest_to_insert);
+ rest_to_insert = truncated;
+ }
+
+ if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0)
+ create_and_append_new_paragraph (
+ document, blockquote, "<br>");
+ else
+ create_and_append_new_paragraph (
+ document, blockquote, rest_to_insert);
+
+ g_free (rest_to_insert);
+ }
+
+ end:
+ /* Replace text markers with actual HTML blockquotes */
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (blockquote));
+ start = e_str_replace_string (
+ inner_html, "##CITATION_START##","<blockquote type=\"cite\">");
+ end = e_str_replace_string (
+ start->str, "##CITATION_END##", "</blockquote>");
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (blockquote), end->str, NULL);
+
+ g_regex_unref (regex_nbsp);
+ g_regex_unref (regex_links);
+ g_free (inner_html);
+ g_string_free (start, TRUE);
+ g_string_free (end, TRUE);
+}
+
+static void
+mark_citation (WebKitDOMElement *citation)
+{
+ gchar *inner_html, *surrounded;
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (citation));
+
+ surrounded = g_strconcat (
+ "<span>##CITATION_START##</span>", inner_html,
+ "<span>##CITATION_END##</span>", NULL);
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (citation), surrounded, NULL);
+
+ element_add_class (citation, "marked");
+
+ g_free (inner_html);
+ g_free (surrounded);
+}
+
+static gint
+create_text_markers_for_citations_in_document (WebKitDOMDocument *document)
+{
+ gint count = 0;
+ WebKitDOMElement *citation;
+
+ citation = webkit_dom_document_query_selector (
+ document, "blockquote[type=cite]:not(.marked)", NULL);
+
+ while (citation) {
+ mark_citation (citation);
+ count ++;
+
+ citation = webkit_dom_document_query_selector (
+ document, "blockquote[type=cite]:not(.marked)", NULL);
+ }
+
+ return count;
+}
+
+static gint
+create_text_markers_for_citations_in_element (WebKitDOMElement *element)
+{
+ gint count = 0;
+ WebKitDOMElement *citation;
+
+ citation = webkit_dom_element_query_selector (
+ element, "blockquote[type=cite]:not(.marked)", NULL);
+
+ while (citation) {
+ mark_citation (citation);
+ count ++;
+
+ citation = webkit_dom_element_query_selector (
+ element, "blockquote[type=cite]:not(.marked)", NULL);
+ }
+
+ return count;
+}
+
+static void
+quote_plain_text_elements_after_wrapping_in_document (WebKitDOMDocument *document)
+{
+ gint length, ii;
+ WebKitDOMNodeList *list;
+
+ list = webkit_dom_document_query_selector_all (
+ document, "blockquote[type=cite] > div.-x-evo-paragraph", NULL);
+
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ gint citation_level;
+ WebKitDOMNode *child;
+
+ child = webkit_dom_node_list_item (list, ii);
+ citation_level = get_citation_level (child, TRUE);
+ quote_plain_text_element_after_wrapping (
+ document, WEBKIT_DOM_ELEMENT (child), citation_level);
+ }
+ g_object_unref (list);
+}
+
+static void
+html_editor_convert_view_content (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document,
+ const gchar *preferred_text)
+{
+ gboolean start_bottom, empty = FALSE;
+ gchar *inner_html;
+ gint ii, length;
+ GSettings *settings;
+ WebKitDOMElement *paragraph, *content_wrapper, *top_signature;
+ WebKitDOMElement *cite_body, *signature, *wrapper;
+ WebKitDOMHTMLElement *body;
+ WebKitDOMNodeList *list;
+ WebKitDOMNode *node;
+
+ settings = e_util_ref_settings ("org.gnome.evolution.mail");
+ start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
+ g_object_unref (settings);
+
+ body = webkit_dom_document_get_body (document);
+ /* Wrapper that will represent the new body. */
+ wrapper = webkit_dom_document_create_element (document, "div", NULL);
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
+
+ cite_body = webkit_dom_document_query_selector (
+ document, "span.-x-evo-cite-body", NULL);
+
+ /* content_wrapper when the processed text will be placed. */
+ content_wrapper = webkit_dom_document_create_element (
+ document, cite_body ? "blockquote" : "div", NULL);
+ if (cite_body) {
+ webkit_dom_element_set_attribute (content_wrapper, "type", "cite", NULL);
+ webkit_dom_element_set_attribute (content_wrapper, "id", "-x-evo-main-cite", NULL);
+ }
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (wrapper), WEBKIT_DOM_NODE (content_wrapper), NULL);
+
+ /* Remove all previously inserted paragraphs. */
+ list = webkit_dom_document_query_selector_all (
+ document, ".-x-evo-paragraph", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++)
+ remove_node (webkit_dom_node_list_item (list, ii));
+ g_object_unref (list);
+
+ /* Insert the paragraph where the caret will be. */
+ paragraph = prepare_paragraph (document, TRUE);
+ webkit_dom_element_set_id (paragraph, "-x-evo-input-start");
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ WEBKIT_DOM_NODE (paragraph),
+ start_bottom ?
+ webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (content_wrapper)) :
+ WEBKIT_DOM_NODE (content_wrapper),
+ NULL);
+
+ /* Insert signature (if presented) to the right position. */
+ top_signature = webkit_dom_document_query_selector (
+ document, ".-x-evo-top-signature", NULL);
+ signature = webkit_dom_document_query_selector (
+ document, ".-x-evo-signature-content_wrapper", NULL);
+ if (signature) {
+ if (top_signature) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ WEBKIT_DOM_NODE (signature),
+ start_bottom ?
+ WEBKIT_DOM_NODE (content_wrapper) :
+ webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (paragraph)),
+ NULL);
+ /* Insert NL after the signature */
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ WEBKIT_DOM_NODE (prepare_paragraph (
+ selection, document, FALSE)),
+ webkit_dom_node_get_next_sibling (
+ WEBKIT_DOM_NODE (signature)),
+ NULL);
+ } else {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ WEBKIT_DOM_NODE (signature),
+ webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (
+ start_bottom ? paragraph : content_wrapper)),
+ NULL);
+ }
+ }
+
+ /* Move credits to the body */
+ list = webkit_dom_document_query_selector_all (
+ document, "span.-x-evo-to-body[data-credits]", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node, *child;
+
+ node = webkit_dom_node_list_item (list, ii);
+ while ((child = webkit_dom_node_get_first_child (node))) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ child,
+ WEBKIT_DOM_NODE (content_wrapper),
+ NULL);
+ }
+
+ remove_node (node);
+ }
+ g_object_unref (list);
+
+ /* Move headers to body */
+ list = webkit_dom_document_query_selector_all (
+ document, "span.-x-evo-to-body[data-headers]", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node, *child;
+
+ node = webkit_dom_node_list_item (list, ii);
+ while ((child = webkit_dom_node_get_first_child (node))) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (wrapper),
+ child,
+ WEBKIT_DOM_NODE (content_wrapper),
+ NULL);
+ }
+
+ remove_node (node);
+ }
+ g_object_unref (list);
+
+ repair_gmail_blockquotes (document);
+ create_text_markers_for_citations_in_document (document);
+
+ if (preferred_text && *preferred_text)
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (content_wrapper), preferred_text, NULL);
+ else {
+ gchar *inner_text;
+
+ inner_text = webkit_dom_html_element_get_inner_text (body);
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (content_wrapper), inner_text, NULL);
+
+ g_free (inner_text);
+ }
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (content_wrapper));
+
+ /* Replace the old body with the new one. */
+ node = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), FALSE);
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
+ node,
+ WEBKIT_DOM_NODE (body),
+ NULL);
+ body = WEBKIT_DOM_HTML_ELEMENT (node);
+
+ /* Copy all to nodes to the new body. */
+ while ((node = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (wrapper)))) {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (body),
+ WEBKIT_DOM_NODE (node),
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
+ NULL);
+ }
+ remove_node (WEBKIT_DOM_NODE (wrapper));
+
+ /* FIXME XXX */
+ length = webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (body));
+ if (length <= 1) {
+ empty = TRUE;
+ if (length == 1) {
+ WebKitDOMNode *child;
+
+ child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+ empty = child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (child);
+ }
+ }
+
+ if (preferred_text && *preferred_text)
+ empty = FALSE;
+
+ if (!empty)
+ parse_html_into_paragraphs (document, content_wrapper, inner_html);
+
+ if (!cite_body) {
+ if (!empty) {
+ WebKitDOMNode *child;
+
+ while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (content_wrapper))))
{
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (content_wrapper)),
+ child,
+ WEBKIT_DOM_NODE (content_wrapper),
+ NULL);
+ }
+ }
+
+ remove_node (WEBKIT_DOM_NODE (content_wrapper));
+ }
+
+ if (e_html_editor_web_extension_is_message_from_edit_as_new (extension) ||
+ e_html_editor_web_extension_get_remove_initial_input_line (extension)) {
+ WebKitDOMNode *child;
+
+ remove_node (WEBKIT_DOM_NODE (paragraph));
+ child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
+ if (child)
+ add_selection_markers_into_element_start (
+ document, WEBKIT_DOM_ELEMENT (child), NULL, NULL);
+ }
+
+ paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-last-br", NULL);
+ if (paragraph)
+ webkit_dom_element_remove_attribute (paragraph, "class");
+ paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-first-br", NULL);
+ if (paragraph)
+ webkit_dom_element_remove_attribute (paragraph, "class");
+
+ if (!is_in_html_mode (extension)) {
+ dom_wrap_paragraphs_in_document (document);
+
+ quote_plain_text_elements_after_wrapping_in_document (document);
+ }
+
+ dom_selection_restore (selection);
+ dom_force_spell_check (document);
+
+ /* Register on input event that is called when the content (body) is modified */
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (body),
+ "input",
+ G_CALLBACK (body_input_event_cb),
+ FALSE,
+ document);
+
+ g_free (inner_html);
+}
+
+static gint
+get_indentation_level (WebKitDOMElement *element)
+{
+ WebKitDOMElement *parent;
+ gint level = 1;
+
+ parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element));
+ /* Count level of indentation */
+ while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ if (element_has_class (parent, "-x-evo-indented"))
+ level++;
+
+ parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
+ }
+
+ return level;
+}
+
+static void
+process_blockquote (WebKitDOMElement *blockquote)
+{
+ WebKitDOMNodeList *list;
+ int jj, length;
+
+ /* First replace wrappers */
+ list = webkit_dom_element_query_selector_all (
+ blockquote, "span.-x-evo-temp-text-wrapper", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (jj = 0; jj < length; jj++) {
+ WebKitDOMNode *quoted_node;
+ gchar *text_content;
+
+ quoted_node = webkit_dom_node_list_item (list, jj);
+ text_content = webkit_dom_node_get_text_content (quoted_node);
+ webkit_dom_html_element_set_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
+
+ g_free (text_content);
+ }
+ g_object_unref (list);
+
+ /* Afterwards replace quote nodes with symbols */
+ list = webkit_dom_element_query_selector_all (
+ blockquote, "span.-x-evo-quoted", NULL);
+ length = webkit_dom_node_list_get_length (list);
+ for (jj = 0; jj < length; jj++) {
+ WebKitDOMNode *quoted_node;
+ gchar *text_content;
+
+ quoted_node = webkit_dom_node_list_item (list, jj);
+ text_content = webkit_dom_node_get_text_content (quoted_node);
+ webkit_dom_html_element_set_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
+
+ g_free (text_content);
+ }
+ g_object_unref (list);
+
+ if (element_has_class (blockquote, "-x-evo-indented")) {
+ WebKitDOMNode *child;
+ gchar *spaces;
+
+ spaces = g_strnfill (4 * get_indentation_level (blockquote), ' ');
+
+ child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (blockquote));
+ while (child) {
+ /* If next sibling is indented blockqoute skip it,
+ * it will be processed afterwards */
+ if (WEBKIT_DOM_IS_ELEMENT (child) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
+ child = webkit_dom_node_get_next_sibling (child);
+
+ if (WEBKIT_DOM_IS_TEXT (child)) {
+ gchar *text_content;
+ gchar *indented_text;
+
+ text_content = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (child));
+ indented_text = g_strconcat (spaces, text_content, NULL);
+
+ webkit_dom_text_replace_whole_text (
+ WEBKIT_DOM_TEXT (child),
+ indented_text,
+ NULL);
+
+ g_free (text_content);
+ g_free (indented_text);
+ }
+
+ if (!child)
+ break;
+
+ /* Move to next node */
+ if (webkit_dom_node_has_child_nodes (child))
+ child = webkit_dom_node_get_first_child (child);
+ else if (webkit_dom_node_get_next_sibling (child))
+ child = webkit_dom_node_get_next_sibling (child);
+ else {
+ if (webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (blockquote), child))
+ break;
+
+ child = webkit_dom_node_get_parent_node (child);
+ if (child)
+ child = webkit_dom_node_get_next_sibling (child);
+ }
+ }
+ g_free (spaces);
+
+ webkit_dom_element_remove_attribute (blockquote, "style");
+ }
+}
+
+/* Taken from GtkHTML */
+static gchar *
+get_alpha_value (gint value,
+ gboolean lower)
+{
+ GString *str;
+ gchar *rv;
+ gint add = lower ? 'a' : 'A';
+
+ str = g_string_new (". ");
+
+ do {
+ g_string_prepend_c (str, ((value - 1) % 26) + add);
+ value = (value - 1) / 26;
+ } while (value);
+
+ rv = str->str;
+ g_string_free (str, FALSE);
+
+ return rv;
+}
+
+/* Taken from GtkHTML */
+static gchar *
+get_roman_value (gint value,
+ gboolean lower)
+{
+ GString *str;
+ const gchar *base = "IVXLCDM";
+ gchar *rv;
+ gint b, r, add = lower ? 'a' - 'A' : 0;
+
+ if (value > 3999)
+ return g_strdup ("?. ");
+
+ str = g_string_new (". ");
+
+ for (b = 0; value > 0 && b < 7 - 1; b += 2, value /= 10) {
+ r = value % 10;
+ if (r != 0) {
+ if (r < 4) {
+ for (; r; r--)
+ g_string_prepend_c (str, base[b] + add);
+ } else if (r == 4) {
+ g_string_prepend_c (str, base[b + 1] + add);
+ g_string_prepend_c (str, base[b] + add);
+ } else if (r == 5) {
+ g_string_prepend_c (str, base[b + 1] + add);
+ } else if (r < 9) {
+ for (; r > 5; r--)
+ g_string_prepend_c (str, base[b] + add);
+ g_string_prepend_c (str, base[b + 1] + add);
+ } else if (r == 9) {
+ g_string_prepend_c (str, base[b + 2] + add);
+ g_string_prepend_c (str, base[b] + add);
+ }
+ }
+ }
+
+ rv = str->str;
+ g_string_free (str, FALSE);
+
+ return rv;
+}
+
+static void
+process_list_to_plain_text (EHTMLEditorWebExtension *extension,
+ WebKitDOMElement *element,
+ gint level,
+ GString *output)
+{
+ EHTMLEditorSelectionBlockFormat format;
+ EHTMLEditorSelectionAlignment alignment;
+ gint counter = 1;
+ gchar *indent_per_level = g_strnfill (SPACES_PER_LIST_LEVEL, ' ');
+ WebKitDOMNode *item;
+ gint word_wrap_length = e_html_editor_web_extension_get_word_wrap_length (extension);
+
+ format = dom_get_list_format_from_node (
+ WEBKIT_DOM_NODE (element));
+
+ /* Process list items to plain text */
+ item = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element));
+ while (item) {
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (item))
+ g_string_append (output, "\n");
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
+ gchar *space, *item_str = NULL;
+ gint ii = 0;
+ WebKitDOMElement *wrapped;
+ GString *item_value = g_string_new ("");
+
+ alignment = dom_get_list_alignment_from_node (
+ WEBKIT_DOM_NODE (item));
+
+ wrapped = webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (item), ".-x-evo-wrap-br", NULL);
+ /* Wrapped text */
+ if (wrapped) {
+ WebKitDOMNode *node = webkit_dom_node_get_first_child (item);
+ GString *line = g_string_new ("");
+ while (node) {
+ if (WEBKIT_DOM_IS_TEXT (node)) {
+ /* append text from line */
+ gchar *text_content;
+ text_content = webkit_dom_node_get_text_content (node);
+ g_string_append (line, text_content);
+ g_free (text_content);
+ }
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (node) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br")) {
+ g_string_append (line, "\n");
+ /* put spaces before line characters -> wordwraplength -
indentation */
+ for (ii = 0; ii < level; ii++)
+ g_string_append (line, indent_per_level);
+ g_string_append (item_value, line->str);
+ g_string_erase (line, 0, -1);
+ }
+ node = webkit_dom_node_get_next_sibling (node);
+ }
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
+ g_string_append (item_value, line->str);
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+ gchar *fill = NULL;
+ gint fill_length;
+
+ fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
+ fill_length -= ii * SPACES_PER_LIST_LEVEL;
+ fill_length /= 2;
+
+ if (fill_length < 0)
+ fill_length = 0;
+
+ fill = g_strnfill (fill_length, ' ');
+
+ g_string_append (item_value, fill);
+ g_string_append (item_value, line->str);
+ g_free (fill);
+ }
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+ gchar *fill = NULL;
+ gint fill_length;
+
+ fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
+ fill_length -= ii * SPACES_PER_LIST_LEVEL;
+
+ if (fill_length < 0)
+ fill_length = 0;
+
+ fill = g_strnfill (fill_length, ' ');
+
+ g_string_append (item_value, fill);
+ g_string_append (item_value, line->str);
+ g_free (fill);
+ }
+ g_string_free (line, TRUE);
+ /* that same here */
+ } else {
+ gchar *text_content =
+ webkit_dom_node_get_text_content (item);
+ g_string_append (item_value, text_content);
+ g_free (text_content);
+ }
+
+ if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) {
+ space = g_strnfill (SPACES_PER_LIST_LEVEL - 2, ' ');
+ item_str = g_strdup_printf (
+ "%s* %s", space, item_value->str);
+ g_free (space);
+ }
+
+ if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+ gint length = 1, tmp = counter;
+
+ while ((tmp = tmp / 10) > 1)
+ length++;
+
+ if (tmp == 1)
+ length++;
+
+ space = g_strnfill (SPACES_PER_LIST_LEVEL - 2 - length, ' ');
+ item_str = g_strdup_printf (
+ "%s%d. %s", space, counter, item_value->str);
+ g_free (space);
+ }
+
+ if (format > E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
+ gchar *value;
+
+ if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
+ value = get_alpha_value (counter, FALSE);
+ else
+ value = get_roman_value (counter, FALSE);
+
+ /* Value already containes dot and space */
+ space = g_strnfill (SPACES_PER_LIST_LEVEL - strlen (value), ' ');
+ item_str = g_strdup_printf (
+ "%s%s%s", space, value, item_value->str);
+ g_free (space);
+ g_free (value);
+ }
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) {
+ for (ii = 0; ii < level - 1; ii++) {
+ g_string_append (output, indent_per_level);
+ }
+ g_string_append (output, item_str);
+ }
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
+ if (!wrapped) {
+ gchar *fill = NULL;
+ gint fill_length;
+
+ fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
+ fill_length -= ii * SPACES_PER_LIST_LEVEL;
+
+ if (fill_length < 0)
+ fill_length = 0;
+
+ if (g_str_has_suffix (item_str, " "))
+ fill_length++;
+
+ fill = g_strnfill (fill_length, ' ');
+
+ g_string_append (output, fill);
+ g_free (fill);
+ }
+ if (g_str_has_suffix (item_str, " "))
+ g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) -
1);
+ else
+ g_string_append (output, item_str);
+ }
+
+ if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
+ if (!wrapped) {
+ gchar *fill = NULL;
+ gint fill_length = 0;
+
+ for (ii = 0; ii < level - 1; ii++)
+ g_string_append (output, indent_per_level);
+
+ fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
+ fill_length -= ii * SPACES_PER_LIST_LEVEL;
+ fill_length /= 2;
+
+ if (fill_length < 0)
+ fill_length = 0;
+
+ if (g_str_has_suffix (item_str, " "))
+ fill_length++;
+
+ fill = g_strnfill (fill_length, ' ');
+
+ g_string_append (output, fill);
+ g_free (fill);
+ }
+ if (g_str_has_suffix (item_str, " "))
+ g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) -
1);
+ else
+ g_string_append (output, item_str);
+ }
+
+ counter++;
+ item = webkit_dom_node_get_next_sibling (item);
+ if (item)
+ g_string_append (output, "\n");
+
+ g_free (item_str);
+ g_string_free (item_value, TRUE);
+ } else if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (item) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (item)) {
+ process_list_to_plain_text (
+ extension, WEBKIT_DOM_ELEMENT (item), level + 1, output);
+ item = webkit_dom_node_get_next_sibling (item);
+ } else {
+ item = webkit_dom_node_get_next_sibling (item);
+ }
+ }
+
+ if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element)))
+ g_string_append (output, "\n");
+
+ g_free (indent_per_level);
+}
+
+static void
+remove_base_attributes (WebKitDOMElement *element)
+{
+ webkit_dom_element_remove_attribute (element, "class");
+ webkit_dom_element_remove_attribute (element, "id");
+ webkit_dom_element_remove_attribute (element, "name");
+}
+
+static void
+remove_evolution_attributes (WebKitDOMElement *element)
+{
+ webkit_dom_element_remove_attribute (element, "x-evo-smiley");
+ webkit_dom_element_remove_attribute (element, "data-converted");
+ webkit_dom_element_remove_attribute (element, "data-edit-as-new");
+ webkit_dom_element_remove_attribute (element, "data-evo-draft");
+ webkit_dom_element_remove_attribute (element, "data-inline");
+ webkit_dom_element_remove_attribute (element, "data-uri");
+ webkit_dom_element_remove_attribute (element, "data-message");
+ webkit_dom_element_remove_attribute (element, "data-name");
+ webkit_dom_element_remove_attribute (element, "data-new-message");
+ webkit_dom_element_remove_attribute (element, "spellcheck");
+}
+/*
+static void
+remove_style_attributes (WebKitDOMElement *element)
+{
+ webkit_dom_element_remove_attribute (element, "bgcolor");
+ webkit_dom_element_remove_attribute (element, "background");
+ webkit_dom_element_remove_attribute (element, "style");
+}
+*/
+static gboolean
+replace_to_whitespaces (const GMatchInfo *info,
+ GString *res,
+ gpointer data)
+{
+ gint ii, length = 0;
+ gint chars_count = GPOINTER_TO_INT (data);
+
+ length = TAB_LENGTH - (chars_count % TAB_LENGTH);
+
+ for (ii = 0; ii < length; ii++)
+ g_string_append (res, " ");
+
+ return FALSE;
+}
+
+static void
+process_elements (EHTMLEditorWebExtension *extension,
+ WebKitDOMNode *node,
+ gboolean to_html,
+ gboolean changing_mode,
+ gboolean to_plain_text,
+ GString *buffer)
+{
+ WebKitDOMNodeList *nodes;
+ gulong ii, length;
+ gchar *content;
+ gboolean skip_nl = FALSE;
+
+ if (to_plain_text && !buffer)
+ return;
+
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (node)) {
+ if (changing_mode && to_plain_text) {
+ WebKitDOMNamedNodeMap *attributes;
+ gulong attributes_length;
+
+ /* Copy attributes */
+ g_string_append (buffer, "<html><head></head><body ");
+ attributes = webkit_dom_element_get_attributes (
+ WEBKIT_DOM_ELEMENT (node));
+ attributes_length =
+ webkit_dom_named_node_map_get_length (attributes);
+
+ for (ii = 0; ii < attributes_length; ii++) {
+ gchar *name, *value;
+ WebKitDOMNode *node =
+ webkit_dom_named_node_map_item (
+ attributes, ii);
+
+ name = webkit_dom_node_get_local_name (node);
+ value = webkit_dom_node_get_node_value (node);
+
+ g_string_append (buffer, name);
+ g_string_append (buffer, "=\"");
+ g_string_append (buffer, value);
+ g_string_append (buffer, "\" ");
+
+ g_free (name);
+ g_free (value);
+ }
+ g_string_append (buffer, ">");
+ g_object_unref (attributes);
+ }
+ if (to_html)
+ remove_evolution_attributes (WEBKIT_DOM_ELEMENT (node));
+ }
+
+ nodes = webkit_dom_node_get_child_nodes (node);
+ length = webkit_dom_node_list_get_length (nodes);
+
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *child;
+ gboolean skip_node = FALSE;
+
+ child = webkit_dom_node_list_item (nodes, ii);
+
+ if (WEBKIT_DOM_IS_TEXT (child)) {
+ gchar *content, *tmp;
+ GRegex *regex;
+ gint char_count = 0;
+
+ content = webkit_dom_node_get_text_content (child);
+ if (!changing_mode && to_plain_text) {
+ /* Replace tabs with 8 whitespaces, otherwise they got
+ * replaced by single whitespace */
+ if (strstr (content, "\x9")) {
+ if (buffer->str && *buffer->str) {
+ gchar *start_of_line = g_strrstr_len (
+ buffer->str, -1, "\n") + 1;
+
+ if (start_of_line && *start_of_line)
+ char_count = strlen (start_of_line);
+ } else
+ char_count = 0;
+
+ regex = g_regex_new ("\x9", 0, 0, NULL);
+ tmp = g_regex_replace_eval (
+ regex,
+ content,
+ -1,
+ 0,
+ 0,
+ (GRegexEvalCallback) replace_to_whitespaces,
+ GINT_TO_POINTER (char_count),
+ NULL);
+
+ g_string_append (buffer, tmp);
+ g_free (tmp);
+ g_free (content);
+ content = webkit_dom_node_get_text_content (child);
+ g_regex_unref (regex);
+ }
+ }
+
+ 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);
+ webkit_dom_node_set_text_content (child, tmp, NULL);
+ g_free (tmp);
+ g_free (content);
+ content = webkit_dom_node_get_text_content (child);
+ g_regex_unref (regex);
+ }
+
+ if (to_plain_text && !changing_mode) {
+ gchar *class;
+ const gchar *css_align;
+
+ if (strstr (content, UNICODE_NBSP)) {
+ GString *nbsp_free;
+
+ nbsp_free = e_str_replace_string (
+ content, UNICODE_NBSP, " ");
+
+ g_free (content);
+ content = g_string_free (nbsp_free, FALSE);
+ }
+
+ 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;
+ gint word_wrap_length = extension->priv->word_wrap_length;
+
+ 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;
+
+ length++;
+ align = g_strnfill (length, ' ');
+
+ tmp = g_strndup (content, g_utf8_strlen (content, -1)
-1);
+
+ content_with_align = g_strconcat (
+ align, tmp, NULL);
+ g_free (tmp);
+ } else {
+ align = g_strnfill (length, ' ');
+
+ content_with_align = g_strconcat (
+ align, content, NULL);
+ }
+
+ g_free (content);
+ g_free (align);
+ content = content_with_align;
+ }
+ }
+
+ g_free (class);
+ }
+
+ if (to_plain_text || changing_mode)
+ g_string_append (buffer, content);
+
+ g_free (content);
+
+ goto next;
+ }
+
+ if (WEBKIT_DOM_IS_COMMENT (child) || !WEBKIT_DOM_IS_ELEMENT (child))
+ goto next;
+
+ /* Leave caret position untouched */
+ if (element_has_id (WEBKIT_DOM_ELEMENT (child), "-x-evo-caret-position")) {
+ 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)
+ remove_node (child);
+
+ skip_node = TRUE;
+ goto next;
+ }
+
+ if (element_has_class (WEBKIT_DOM_ELEMENT (child), "Apple-tab-span")) {
+ if (!changing_mode && to_plain_text) {
+ gchar *content, *tmp;
+ GRegex *regex;
+ gint char_count = 0;
+
+ content = webkit_dom_node_get_text_content (child);
+ /* Replace tabs with 8 whitespaces, otherwise they got
+ * replaced by single whitespace */
+ if (strstr (content, "\x9")) {
+ if (buffer->str && *buffer->str) {
+ gchar *start_of_line = g_strrstr_len (
+ buffer->str, -1, "\n") + 1;
+
+ if (start_of_line && *start_of_line)
+ char_count = strlen (start_of_line);
+ } else
+ char_count = 0;
+
+ regex = g_regex_new ("\x9", 0, 0, NULL);
+ tmp = g_regex_replace_eval (
+ regex,
+ content,
+ -1,
+ 0,
+ 0,
+ (GRegexEvalCallback) replace_to_whitespaces,
+ GINT_TO_POINTER (char_count),
+ NULL);
+
+ g_string_append (buffer, tmp);
+ g_free (tmp);
+ g_regex_unref (regex);
+ } else if (content && *content) {
+ /* Some it happens that some text is written inside
+ * the tab span element, so save it. */
+ g_string_append (buffer, content);
+ }
+ g_free (content);
+ }
+ if (to_html) {
+ element_remove_class (
+ WEBKIT_DOM_ELEMENT (child),
+ "Applet-tab-span");
+ }
+
+ skip_node = TRUE;
+ goto next;
+ }
+
+ /* Leave blockquotes as they are */
+ if (WEBKIT_DOM_IS_HTML_QUOTE_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);
+ skip_node = TRUE;
+ goto next;
+ } else {
+ if (!changing_mode && to_plain_text) {
+ if (get_citation_level (child, FALSE) == 0) {
+ gchar *value = webkit_dom_element_get_attribute (
+ WEBKIT_DOM_ELEMENT (child), "type");
+
+ if (value && g_strcmp0 (value, "cite") == 0)
+ g_string_append (buffer, "\n");
+ g_free (value);
+ }
+ }
+ process_blockquote (WEBKIT_DOM_ELEMENT (child));
+ if (to_html)
+ remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
+ }
+ }
+
+ 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_HTML_U_LIST_ELEMENT (child) ||
+ WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (child)) {
+ if (to_plain_text) {
+ if (changing_mode) {
+ content = webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (child));
+ g_string_append (buffer, content);
+ g_free (content);
+ } else {
+ process_list_to_plain_text (
+ extension, WEBKIT_DOM_ELEMENT (child), 1, buffer);
+ }
+ skip_node = TRUE;
+ goto next;
+ }
+ }
+
+ if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-resizable-wrapper") &&
+ !element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
+ WebKitDOMNode *image =
+ webkit_dom_node_get_first_child (child);
+
+ if (to_html && WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (image)) {
+ remove_evolution_attributes (
+ WEBKIT_DOM_ELEMENT (image));
+
+ webkit_dom_node_replace_child (
+ node, image, child, NULL);
+ }
+
+ skip_node = TRUE;
+ goto next;
+ }
+
+ /* Leave paragraphs as they are */
+ if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-paragraph")) {
+ 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;
+ goto next;
+ }
+ if (to_html) {
+ remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
+ remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
+ }
+ if (!changing_mode && to_plain_text)
+ if (!webkit_dom_node_has_child_nodes (child))
+ g_string_append (buffer, "\n");
+ }
+
+ /* Signature */
+ if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
+ element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-signature-wrapper")) {
+ WebKitDOMNode *first_child;
+
+ first_child = webkit_dom_node_get_first_child (child);
+
+ if (to_html) {
+ remove_base_attributes (
+ WEBKIT_DOM_ELEMENT (first_child));
+ remove_evolution_attributes (
+ WEBKIT_DOM_ELEMENT (first_child));
+ }
+ if (to_plain_text && !changing_mode) {
+ g_string_append (buffer, "\n");
+ content = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (first_child));
+ g_string_append (buffer, content);
+ g_free (content);
+ skip_nl = TRUE;
+ }
+ if (to_plain_text && changing_mode) {
+ content = webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (child));
+ g_string_append (buffer, content);
+ g_free (content);
+ skip_node = TRUE;
+ }
+ skip_node = TRUE;
+ goto next;
+ }
+
+ /* Replace smileys with their text representation */
+ if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
+ 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));
+ g_string_append (buffer, content);
+ g_free (content);
+ skip_node = TRUE;
+ goto next;
+ }
+ if (to_html) {
+ WebKitDOMElement *img;
+
+ img = WEBKIT_DOM_ELEMENT (
+ webkit_dom_node_get_first_child (child)),
+
+ remove_evolution_attributes (img);
+ remove_base_attributes (img);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (child),
+ WEBKIT_DOM_NODE (img),
+ child,
+ NULL);
+ remove_node (child);
+ skip_node = TRUE;
+ goto next;
+ }
+ }
+
+ /* Leave PRE elements untouched */
+ if (WEBKIT_DOM_IS_HTML_PRE_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);
+ skip_node = TRUE;
+ }
+ if (to_html)
+ remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
+ }
+
+ if (WEBKIT_DOM_IS_HTML_BR_ELEMENT (child)) {
+ if (to_plain_text) {
+ if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-wrap-br")) {
+ g_string_append (buffer, changing_mode ? "<br>" : "\n");
+ goto next;
+ }
+
+ /* Insert new line when we hit the BR element that is
+ * not the last element in the block */
+ if (!webkit_dom_node_is_same_node (
+ child, webkit_dom_node_get_last_child (node))) {
+ g_string_append (buffer, changing_mode ? "<br>" : "\n");
+ } else {
+ /* In citations in the empty lines the BR element
+ * is on the end and we have to put NL there */
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (child);
+ if (webkit_dom_node_get_next_sibling (parent)) {
+ parent = webkit_dom_node_get_parent_node (parent);
+
+ if (is_citation_node (parent))
+ g_string_append (buffer, changing_mode ? "<br>" :
"\n");
+ }
+ }
+ }
+ }
+
+ if (WEBKIT_DOM_IS_HTML_ANCHOR_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);
+ skip_node = TRUE;
+ }
+ if (!changing_mode && to_plain_text) {
+ content = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (child));
+ g_string_append (buffer, content);
+ g_free (content);
+ skip_node = TRUE;
+ }
+ }
+ next:
+ if (webkit_dom_node_has_child_nodes (child) && !skip_node)
+ process_elements (
+ extension, child, to_html, changing_mode, to_plain_text, buffer);
+ }
+
+ if (to_plain_text && (
+ WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_PRE_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))) {
+
+ gboolean add_br = TRUE;
+ WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
+ WebKitDOMNode *last_child = webkit_dom_node_get_last_child (node);
+
+ if (last_child && WEBKIT_DOM_IS_HTML_BR_ELEMENT (last_child))
+ if (webkit_dom_node_get_previous_sibling (last_child))
+ add_br = FALSE;
+
+ /* If we don't have next sibling (last element in body) or next element is
+ * signature we are not adding the BR element */
+ if (!next_sibling)
+ add_br = FALSE;
+ else if (next_sibling && WEBKIT_DOM_IS_HTML_DIV_ELEMENT (next_sibling)) {
+ if (webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (next_sibling),
+ "span.-x-evo-signature", NULL)) {
+
+ add_br = FALSE;
+ }
+ }
+
+ if (add_br && !skip_nl)
+ g_string_append (buffer, changing_mode ? "<br>" : "\n");
+ }
+
+ g_object_unref (nodes);
+}
+
+static void
+remove_wrapping_from_document (WebKitDOMDocument *document)
+{
+ gint length;
+ gint ii;
+ WebKitDOMNodeList *list;
+
+ list = webkit_dom_document_query_selector_all (document, "br.-x-evo-wrap-br", NULL);
+
+ length = webkit_dom_node_list_get_length (list);
+ for (ii = 0; ii < length; ii++)
+ remove_node (webkit_dom_node_list_item (list, ii));
+
+ g_object_unref (list);
+}
+
+static void
+remove_image_attributes_from_element (WebKitDOMElement *element)
+{
+ webkit_dom_element_remove_attribute (element, "background");
+ webkit_dom_element_remove_attribute (element, "data-uri");
+ webkit_dom_element_remove_attribute (element, "data-inline");
+ webkit_dom_element_remove_attribute (element, "data-name");
+}
+
+static void
+remove_background_images_in_document (WebKitDOMDocument *document)
+{
+ gint length, ii;
+ WebKitDOMNodeList *elements;
+
+ elements = webkit_dom_document_query_selector_all (
+ document, "[background][data-inline]", NULL);
+
+ length = webkit_dom_node_list_get_length (elements);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMElement *element = WEBKIT_DOM_ELEMENT (
+ webkit_dom_node_list_item (elements, ii));
+
+ remove_image_attributes_from_element (element);
+ }
+
+ g_object_unref (elements);
+}
+
+static void
+remove_images_in_element (WebKitDOMElement *element)
+{
+ gint length, ii;
+ WebKitDOMNodeList *images;
+
+ images = webkit_dom_element_query_selector_all (
+ element, "img:not(.-x-evo-smiley-img)", NULL);
+
+ length = webkit_dom_node_list_get_length (images);
+ for (ii = 0; ii < length; ii++)
+ remove_node (webkit_dom_node_list_item (images, ii));
+
+ g_object_unref (images);
+}
+
+static void
+remove_images (WebKitDOMDocument *document)
+{
+ remove_images_in_element (
+ WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)));
+}
+
+static void
+toggle_smileys (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ gboolean html_mode;
+ gint length;
+ gint ii;
+ WebKitDOMNodeList *smileys;
+
+ html_mode = is_in_html_mode (extension);
+
+ smileys = webkit_dom_document_query_selector_all (
+ document, "img.-x-evo-smiley-img", NULL);
+
+ length = webkit_dom_node_list_get_length (smileys);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *img = webkit_dom_node_list_item (smileys, ii);
+ WebKitDOMNode *text = webkit_dom_node_get_next_sibling (img);
+ WebKitDOMElement *parent = webkit_dom_node_get_parent_element (img);
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (html_mode ? text : img),
+ "style",
+ "display: none",
+ NULL);
+
+ webkit_dom_element_remove_attribute (
+ WEBKIT_DOM_ELEMENT (html_mode ? img : text), "style");
+
+ if (html_mode)
+ element_add_class (parent, "-x-evo-resizable-wrapper");
+ else
+ element_remove_class (parent, "-x-evo-resizable-wrapper");
+ }
+
+ g_object_unref (smileys);
+}
+
+static void
+toggle_paragraphs_style_in_element (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ gboolean html_mode)
+{
+ gint ii, length;
+ WebKitDOMNodeList *paragraphs;
+
+ paragraphs = webkit_dom_element_query_selector_all (
+ element, ".-x-evo-paragraph", NULL);
+
+ length = webkit_dom_node_list_get_length (paragraphs);
+
+ for (ii = 0; ii < length; ii++) {
+ gchar *style;
+ const gchar *css_align;
+ WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
+
+ if (html_mode) {
+ style = webkit_dom_element_get_attribute (
+ WEBKIT_DOM_ELEMENT (node), "style");
+
+ if ((css_align = strstr (style, "text-align: "))) {
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (node),
+ "style",
+ g_str_has_prefix (css_align + 12, "center") ?
+ "text-align: center" :
+ "text-align: right",
+ NULL);
+ } else {
+ /* In HTML mode the paragraphs don't have width limit */
+ webkit_dom_element_remove_attribute (
+ WEBKIT_DOM_ELEMENT (node), "style");
+ }
+ g_free (style);
+ } else {
+ WebKitDOMNode *parent;
+
+ parent = webkit_dom_node_get_parent_node (node);
+ /* If the paragraph is inside indented paragraph don't set
+ * the style as it will be inherited */
+ if (!element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-indented")) {
+ const gchar *style_to_add = "";
+ style = webkit_dom_element_get_attribute (
+ WEBKIT_DOM_ELEMENT (node), "style");
+
+ if ((css_align = strstr (style, "text-align: "))) {
+ style_to_add = g_str_has_prefix (
+ css_align + 12, "center") ?
+ "text-align: center;" :
+ "text-align: right;";
+ }
+
+ /* In plain text mode the paragraphs have width limit */
+ dom_set_paragraph_style (
+ document, WEBKIT_DOM_ELEMENT (node), -1, 0, style_to_add);
+
+ g_free (style);
+ }
+ }
+ }
+ g_object_unref (paragraphs);
+}
+
+static void
+toggle_paragraphs_style (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ toggle_paragraphs_style_in_element (
+ document,
+ WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)),
+ is_in_html_mode (extension));
+}
+
+static gchar *
+process_content_for_saving_as_draft (WebKitDOMDocument *document)
+{
+ WebKitDOMHTMLElement *body;
+ WebKitDOMElement *document_element;
+ gchar *content;
+
+ body = webkit_dom_document_get_body (document);
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-evo-draft", "", NULL);
+
+ document_element = webkit_dom_document_get_document_element (document);
+ content = webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (document_element));
+
+ webkit_dom_element_remove_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-evo-draft");
+
+ return content;
+}
+
+static gchar *
+process_content_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 (extension, body, FALSE, TRUE, TRUE, plain_text);
+
+ g_string_append (plain_text, "</body></html>");
+
+ return g_string_free (plain_text, FALSE);
+}
+
+static void
+convert_element_from_html_to_plain_text (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ gboolean *wrap,
+ gboolean *quote)
+{
+ gint blockquotes_count;
+ gchar *inner_text, *inner_html;
+ gboolean restore = TRUE;
+ WebKitDOMElement *top_signature, *signature, *blockquote, *main_blockquote;
+ WebKitDOMNode *signature_clone, *from;
+
+ top_signature = webkit_dom_element_query_selector (
+ element, ".-x-evo-top-signature", NULL);
+ signature = webkit_dom_element_query_selector (
+ element, "span.-x-evo-signature", NULL);
+ main_blockquote = webkit_dom_element_query_selector (
+ element, "#-x-evo-main-cite", NULL);
+
+ blockquote = webkit_dom_document_create_element (
+ document, "blockquote", NULL);
+
+ if (main_blockquote) {
+ WebKitDOMElement *input_start;
+
+ webkit_dom_element_set_attribute (
+ blockquote, "type", "cite", NULL);
+
+ input_start = webkit_dom_element_query_selector (
+ element, "#-x-evo-input-start", NULL);
+
+ restore = input_start ? TRUE : FALSE;
+
+ if (input_start)
+ add_selection_markers_into_element_start (
+ document, WEBKIT_DOM_ELEMENT (input_start), NULL, NULL);
+ from = WEBKIT_DOM_NODE (main_blockquote);
+ } else {
+ if (signature) {
+ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (signature));
+ signature_clone = webkit_dom_node_clone_node (parent, TRUE);
+ remove_node (parent);
+ }
+ from = WEBKIT_DOM_NODE (element);
+ }
+
+ blockquotes_count = create_text_markers_for_citations_in_element (
+ WEBKIT_DOM_ELEMENT (from));
+
+ inner_text = webkit_dom_html_element_get_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (from));
+
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (blockquote), inner_text, NULL);
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (blockquote));
+
+ parse_html_into_paragraphs (
+ document,
+ main_blockquote ? blockquote : WEBKIT_DOM_ELEMENT (element),
+ inner_html);
+
+ if (main_blockquote) {
+ webkit_dom_node_replace_child (
+ webkit_dom_node_get_parent_node (
+ WEBKIT_DOM_NODE (main_blockquote)),
+ WEBKIT_DOM_NODE (blockquote),
+ WEBKIT_DOM_NODE (main_blockquote),
+ NULL);
+
+ remove_evolution_attributes (WEBKIT_DOM_ELEMENT (element));
+ } else {
+ WebKitDOMNode *first_child;
+
+ if (signature) {
+ if (!top_signature) {
+ signature_clone = webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (element),
+ signature_clone,
+ NULL);
+ } else {
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (element),
+ signature_clone,
+ webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (element)),
+ NULL);
+ }
+ }
+
+ first_child = webkit_dom_node_get_first_child (
+ WEBKIT_DOM_NODE (element));
+ if (first_child) {
+ if (!webkit_dom_node_has_child_nodes (first_child)) {
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (first_child),
+ "<br>",
+ NULL);
+ }
+ add_selection_markers_into_element_start (
+ document, WEBKIT_DOM_ELEMENT (first_child), NULL, NULL);
+ }
+ }
+
+ *wrap = TRUE;
+ *quote = main_blockquote || blockquotes_count > 0;
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (element), "data-converted", "", NULL);
+
+ g_free (inner_text);
+ g_free (inner_html);
+
+ if (restore)
+ dom_selection_restore (document);
+}
+
+static gchar *
+process_content_for_plain_text (EHTMLEditorWebExtension *extension,
+ WebKitDOMDocument *document)
+{
+ gboolean wrap = FALSE, quote = FALSE, clean = FALSE;
+ gboolean converted, is_from_new_message;
+ gint length, ii;
+ GString *plain_text;
+ WebKitDOMNode *body, *source;
+ WebKitDOMNodeList *paragraphs;
+
+ plain_text = g_string_sized_new (1024);
+
+ body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
+ converted = webkit_dom_element_has_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-converted");
+ is_from_new_message = webkit_dom_element_has_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-new-message");
+ source = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
+
+ /* If composer is in HTML mode we have to move the content to plain version */
+ if (is_in_html_mode (extension)) {
+ if (converted || is_from_new_message) {
+ toggle_paragraphs_style_in_element (
+ document, WEBKIT_DOM_ELEMENT (source), FALSE);
+ remove_images_in_element (
+ document, WEBKIT_DOM_ELEMENT (source));
+ remove_background_images_in_document (document);
+ } else {
+ gchar *inner_html;
+ WebKitDOMElement *div;
+
+ inner_html = webkit_dom_html_element_get_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (body));
+
+ div = webkit_dom_document_create_element (
+ document, "div", NULL);
+
+ webkit_dom_html_element_set_inner_html (
+ WEBKIT_DOM_HTML_ELEMENT (div), inner_html, NULL);
+
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (body),
+ WEBKIT_DOM_NODE (div),
+ NULL);
+
+ paragraphs = webkit_dom_element_query_selector_all (
+ div, "#-x-evo-input-start", 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);
+
+ webkit_dom_element_remove_attribute (
+ WEBKIT_DOM_ELEMENT (paragraph), "id");
+ }
+ g_object_unref (paragraphs);
+
+ convert_element_from_html_to_plain_text (
+ document, div, &wrap, "e);
+
+ g_object_unref (source);
+
+ source = WEBKIT_DOM_NODE (div);
+
+ clean = TRUE;
+ }
+ }
+
+ paragraphs = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (source), ".-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);
+
+ if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (paragraph) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (paragraph)) {
+ WebKitDOMNode *item = webkit_dom_node_get_first_child (paragraph);
+
+ while (item) {
+ WebKitDOMNode *next_item =
+ webkit_dom_node_get_next_sibling (item);
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (item)) {
+ dom_wrap_paragraph (
+ document, WEBKIT_DOM_ELEMENT (item));
+ }
+ item = next_item;
+ }
+ } else {
+ dom_wrap_paragraph (
+ document, WEBKIT_DOM_ELEMENT (paragraph));
+ }
+ }
+ g_object_unref (paragraphs);
+
+ paragraphs = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (source),
+ "span[id^=\"-x-evo-selection-\"], span#-x-evo-caret-position",
+ NULL);
+
+ length = webkit_dom_node_list_get_length (paragraphs);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
+ WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
+
+ remove_node (node);
+ webkit_dom_node_normalize (parent);
+ }
+ g_object_unref (paragraphs);
+
+ if (is_in_html_mode (extension) || quote)
+ quote_plain_text_recursive (document, source, source, 0);
+
+ process_elements (extension, source, FALSE, FALSE, TRUE, plain_text);
+
+ if (clean)
+ remove_node (source);
+ else
+ g_object_unref (source);
+
+ /* Return text content between <body> and </body> */
+ return g_string_free (plain_text, FALSE);
+}
+
+static gchar *
+process_content_for_html (WebKitDOMDocument *document)
+{
+ WebKitDOMNode *body, *document_clone;
+ gchar *html_content;
+
+ document_clone = webkit_dom_node_clone_node (
+ WEBKIT_DOM_NODE (webkit_dom_document_get_document_element (document)), TRUE);
+ body = WEBKIT_DOM_NODE (webkit_dom_element_query_selector (
+ WEBKIT_DOM_ELEMENT (document_clone), "body", NULL));
+ process_elements (extension, body, TRUE, FALSE, FALSE, NULL);
+
+ html_content = webkit_dom_html_element_get_outer_html (
+ WEBKIT_DOM_HTML_ELEMENT (document_clone));
+
+ g_object_unref (document_clone);
+
+ return html_content;
+}
+
+static void
+clear_attributes (WebKitDOMDocument *document)
+{
+ gint length, ii;
+ WebKitDOMNamedNodeMap *attributes;
+ WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
+ WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head (document);
+ WebKitDOMElement *document_element =
+ webkit_dom_document_get_document_element (document);
+
+ /* Remove all attributes from HTML element */
+ attributes = webkit_dom_element_get_attributes (document_element);
+ length = webkit_dom_named_node_map_get_length (attributes);
+ for (ii = length - 1; ii >= 0; ii--) {
+ WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+ webkit_dom_element_remove_attribute_node (
+ document_element, WEBKIT_DOM_ATTR (node), NULL);
+ }
+ g_object_unref (attributes);
+
+ /* Remove everything from HEAD element */
+ while (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)))
+ remove_node (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)));
+
+ /* Remove non Evolution attributes from BODY element */
+ attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
+ length = webkit_dom_named_node_map_get_length (attributes);
+ for (ii = length - 1; ii >= 0; ii--) {
+ gchar *name;
+ WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
+
+ name = webkit_dom_node_get_local_name (node);
+
+ if (!g_str_has_prefix (name, "data-") ||
+ g_str_has_prefix (name, "data-inline") ||
+ g_str_has_prefix (name, "data-name")) {
+ webkit_dom_element_remove_attribute_node (
+ WEBKIT_DOM_ELEMENT (body),
+ WEBKIT_DOM_ATTR (node),
+ NULL);
+ }
+
+ g_free (name);
+ }
+ g_object_unref (attributes);
+}
+
+void
+convert_when_changing_composer_mode (WebKitDOMDocument *document)
+{
+ gboolean quote = FALSE, wrap = FALSE;
+ WebKitDOMHTMLElement *body;
+
+ body = webkit_dom_document_get_body (document);
+
+ convert_element_from_html_to_plain_text (
+ document, WEBKIT_DOM_ELEMENT (body), &wrap, "e);
+
+ if (wrap)
+ dom_wrap_paragraphs_in_document (document);
+
+ if (quote) {
+ dom_selection_save (document);
+ if (wrap)
+ quote_plain_text_elements_after_wrapping_in_document (
+ document);
+ else
+ body = WEBKIT_DOM_HTML_ELEMENT (dom_quote_plain_text (document));
+ dom_selection_restore (document);
+ }
+
+ toggle_paragraphs_style (document);
+ toggle_smileys (document);
+ remove_images (document);
+ remove_background_images_in_document (document);
+
+ clear_attributes (document);
+
+ webkit_dom_element_set_attribute (
+ WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
+}
+
+static void
+wrap_paragraphs_in_quoted_content (WebKitDOMDocument *document)
+{
+ gint ii, length;
+ WebKitDOMNodeList *paragraphs;
+
+ paragraphs = webkit_dom_document_query_selector_all (
+ document, "blockquote[type=cite] > .-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);
+
+ dom_wrap_paragraph (document, WEBKIT_DOM_ELEMENT (paragraph));
+ }
+ g_object_unref (paragraphs);
+}
+
diff --git a/e-util/e-html-editor-view-dom-functions.h b/e-util/e-html-editor-view-dom-functions.h
index fe5d6ba..4bf6963 100644
--- a/e-util/e-html-editor-view-dom-functions.h
+++ b/e-util/e-html-editor-view-dom-functions.h
@@ -21,6 +21,8 @@
#include <webkitdom/webkitdom.h>
+#include "web-extensions/e-html-editor-web-extension.h"
+
#include "e-util-enums.h"
G_BEGIN_DECLS
@@ -29,6 +31,20 @@ gboolean dom_exec_command (WebKitDOMDocument *document,
EHTMLEditorViewCommand command,
const gchar *value);
+void dom_force_spell_check_for_current_paragraph
+ (WebKitDOMDocument *document);
+
+void dom_force_spell_check (WebKitDOMDocument *document);
+
+void dom_convert_and_insert_html_into_selection
+ (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
+ const gchar *html,
+ gboolean is_html);
+
+WebKitDOMElement *
+ dom_quote_plain_text_element (WebKitDOMDocument *document,
+ WebKitDOMElement *element);
G_END_DECLS
#endif /* E_HTML_EDITOR_VIEW_DOM_FUNCTIONS_H */
diff --git a/e-util/e-html-editor-view.c b/e-util/e-html-editor-view.c
index 60373e0..40c60ea 100644
--- a/e-util/e-html-editor-view.c
+++ b/e-util/e-html-editor-view.c
@@ -25,14 +25,15 @@
#include "e-html-editor-view.h"
#include "e-html-editor.h"
#include "e-emoticon-chooser.h"
+#include "e-misc-utils.h"
+
+#include "web-extensions/e-html-editor-web-extension-names.h"
#include <e-util/e-util.h>
#include <e-util/e-marshal.h>
#include <glib/gi18n-lib.h>
#include <gdk/gdkkeysyms.h>
-#include "web-extensions/e-html-editor-web-extension.h"
-
#define E_HTML_EDITOR_VIEW_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_HTML_EDITOR_VIEW, EHTMLEditorViewPrivate))
@@ -126,8 +127,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-static CamelDataCache *emd_global_http_cache = NULL;
-
typedef void (*PostReloadOperationFunc) (EHTMLEditorView *view, gpointer data);
typedef struct {
@@ -164,54 +163,144 @@ html_editor_view_queue_post_reload_operation (EHTMLEditorView *view,
g_queue_push_head (view->priv->post_reload_operations, op);
}
-static WebKitDOMRange *
-html_editor_view_get_dom_range (EHTMLEditorView *view)
+static void
+html_editor_view_can_redo_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ EHTMLEditorView *view)
{
- WebKitDOMDocument *document;
- WebKitDOMDOMWindow *window;
- WebKitDOMDOMSelection *selection;
+ gboolean value;
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- window = webkit_dom_document_get_default_view (document);
- selection = webkit_dom_dom_window_get_selection (window);
+ value = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
- if (webkit_dom_dom_selection_get_range_count (selection) < 1) {
- return NULL;
+ if (view->priv->can_redo != value) {
+ view->priv->can_redo = value;
+ g_object_notify (G_OBJECT (view), "can-redo");
+ }
+}
+
+static gboolean
+html_editor_view_can_redo (EHTMLEditorView *view)
+{
+ return view->priv->can_redo;
+}
+
+static void
+html_editor_view_can_undo_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ EHTMLEditorView *view)
+{
+ gboolean value;
+
+ value = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
+
+ if (view->priv->can_undo != value) {
+ view->priv->can_undo = value;
+ g_object_notify (G_OBJECT (view), "can-undo");
}
+}
- return webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+static gboolean
+html_editor_view_can_undo (EHTMLEditorView *view)
+{
+ return view->priv->can_undo;
}
static void
-html_editor_view_user_changed_contents_cb (EHTMLEditorView *view,
- gpointer user_data)
+html_editor_view_user_changed_contents_cb (EHTMLEditorView *view)
{
WebKitWebView *web_view;
- gboolean can_redo, can_undo;
web_view = WEBKIT_WEB_VIEW (view);
e_html_editor_view_set_changed (view, TRUE);
- can_redo = webkit_web_view_can_redo (web_view);
- if (view->priv->can_redo != can_redo) {
- view->priv->can_redo = can_redo;
- g_object_notify (G_OBJECT (view), "can-redo");
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_REDO,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) html_editor_view_can_redo_cb,
+ view);
+
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_UNDO,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) html_editor_view_can_undo_cb,
+ view);
+}
+
+static void
+html_editor_view_can_copy_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ EHTMLEditorView *view)
+{
+ gboolean value;
+
+ value = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
+
+ if (view->priv->can_copy != value) {
+ view->priv->can_copy = value;
+ g_object_notify (G_OBJECT (view), "can-copy");
}
+}
- can_undo = webkit_web_view_can_undo (web_view);
- if (view->priv->can_undo != can_undo) {
- view->priv->can_undo = can_undo;
- g_object_notify (G_OBJECT (view), "can-undo");
+static gboolean
+html_editor_view_can_copy (EHTMLEditorView *view)
+{
+ return view->priv->can_copy;
+}
+
+static void
+html_editor_view_can_paste_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ EHTMLEditorView *view)
+{
+ gboolean value;
+
+ value = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
+
+ if (view->priv->can_paste != value) {
+ view->priv->can_paste = value;
+ g_object_notify (G_OBJECT (view), "can-paste");
}
}
+static gboolean
+html_editor_view_can_paste (EHTMLEditorView *view)
+{
+ return view->priv->can_paste;
+}
+
static void
-html_editor_view_selection_changed_cb (EHTMLEditorView *view,
- gpointer user_data)
+html_editor_view_can_cut_cb (WebKitWebView *webkit_web_view,
+ GAsyncResult *result,
+ EHTMLEditorView *view)
+{
+ gboolean value;
+
+ value = webkit_web_view_can_execute_editing_command_finish (
+ webkit_web_view, result, NULL);
+
+ if (view->priv->can_cut != value) {
+ view->priv->can_cut = value;
+ g_object_notify (G_OBJECT (view), "can-cut");
+ }
+}
+
+static gboolean
+html_editor_view_can_cut (EHTMLEditorView *view)
+{
+ return view->priv->can_cut;
+}
+
+static void
+html_editor_view_selection_changed_cb (EHTMLEditorView *view)
{
WebKitWebView *web_view;
- gboolean can_copy, can_cut, can_paste;
web_view = WEBKIT_WEB_VIEW (view);
@@ -224,23 +313,26 @@ html_editor_view_selection_changed_cb (EHTMLEditorView *view,
return;
}
- can_copy = webkit_web_view_can_copy_clipboard (web_view);
- if (view->priv->can_copy != can_copy) {
- view->priv->can_copy = can_copy;
- g_object_notify (G_OBJECT (view), "can-copy");
- }
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_COPY,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) html_editor_view_can_copy_cb,
+ view);
- can_cut = webkit_web_view_can_cut_clipboard (web_view);
- if (view->priv->can_cut != can_cut) {
- view->priv->can_cut = can_cut;
- g_object_notify (G_OBJECT (view), "can-cut");
- }
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_CUT,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) html_editor_view_can_cut_cb,
+ view);
- can_paste = webkit_web_view_can_paste_clipboard (web_view);
- if (view->priv->can_paste != can_paste) {
- view->priv->can_paste = can_paste;
- g_object_notify (G_OBJECT (view), "can-paste");
- }
+ webkit_web_view_can_execute_editing_command (
+ WEBKIT_WEB_VIEW (web_view),
+ WEBKIT_EDITING_COMMAND_PASTE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) html_editor_view_can_paste_cb,
+ view);
}
static gboolean
@@ -250,273 +342,48 @@ html_editor_view_should_show_delete_interface_for_element (EHTMLEditorView *view
return FALSE;
}
-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_HTMLU_LIST_ELEMENT (parent) &&
- !WEBKIT_DOM_IS_HTMLO_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
e_html_editor_view_force_spell_check_for_current_paragraph (EHTMLEditorView *view)
{
- EHTMLEditorSelection *selection;
- WebKitDOMDocument *document;
- WebKitDOMDOMSelection *dom_selection;
- WebKitDOMDOMWindow *window;
- WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMElement *parent, *element;
- WebKitDOMRange *end_range, *actual;
- WebKitDOMText *text;
-
+/* FIXME WK2
if (!view->priv->inline_spelling)
return;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- window = webkit_dom_document_get_default_view (document);
- dom_selection = webkit_dom_dom_window_get_selection (window);
-
- element = webkit_dom_document_query_selector (
- document, "body[spellcheck=true]", NULL);
-
- if (!element)
- return;
-
- selection = e_html_editor_view_get_selection (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 (!selection_start_marker || !selection_end_marker)
- return;
-
+*/
/* Block callbacks of selection-changed signal as we don't want to
* recount all the block format things in EHTMLEditorSelection and here as well
* when we are moving with caret */
+/* FIXME WK2
g_signal_handlers_block_by_func (
view, html_editor_view_selection_changed_cb, NULL);
e_html_editor_selection_block_selection_changed (selection);
-
- parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_end_marker));
-
- /* Append some text on the end of the element */
- text = webkit_dom_document_create_text_node (document, "-x-evo-end");
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (parent),
- WEBKIT_DOM_NODE (text),
- NULL);
-
- parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start_marker));
-
- /* Create range that's pointing on the end of this text */
- end_range = webkit_dom_document_create_range (document);
- webkit_dom_range_select_node_contents (
- end_range, WEBKIT_DOM_NODE (text), NULL);
- webkit_dom_range_collapse (end_range, FALSE, NULL);
-
- /* Move on the beginning of the paragraph */
- actual = webkit_dom_document_create_range (document);
- webkit_dom_range_select_node_contents (
- actual, WEBKIT_DOM_NODE (parent), NULL);
- webkit_dom_range_collapse (actual, TRUE, NULL);
- webkit_dom_dom_selection_remove_all_ranges (dom_selection);
- webkit_dom_dom_selection_add_range (dom_selection, actual);
-
- /* Go through all words to spellcheck them. To avoid this we have to wait for
- * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
- actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- /* We are moving forward word by word until we hit the text on the end of
- * the paragraph that we previously inserted there */
- while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
- webkit_dom_dom_selection_modify (
- dom_selection, "move", "forward", "word");
- actual = webkit_dom_dom_selection_get_range_at (
- dom_selection, 0, NULL);
- }
-
- /* Remove the text that we inserted on the end of the paragraph */
- remove_node (WEBKIT_DOM_NODE (text));
+*/
/* Unblock the callbacks */
+/* FIXME WK2
g_signal_handlers_unblock_by_func (
view, html_editor_view_selection_changed_cb, NULL);
e_html_editor_selection_unblock_selection_changed (selection);
-
- e_html_editor_selection_restore (selection);
-}
-
-static WebKitDOMElement *
-create_selection_marker (WebKitDOMDocument *document,
- gboolean start)
-{
- WebKitDOMElement *element;
-
- element = webkit_dom_document_create_element (
- document, "SPAN", NULL);
- webkit_dom_element_set_id (
- element,
- start ? "-x-evo-selection-start-marker" :
- "-x-evo-selection-end-marker");
-
- return element;
-}
-
-static void
-add_selection_markers_into_element_start (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker)
-{
- WebKitDOMElement *marker;
-
- marker = create_selection_marker (document, FALSE);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (element),
- WEBKIT_DOM_NODE (marker),
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
- NULL);
- if (selection_end_marker)
- *selection_end_marker = marker;
-
- marker = create_selection_marker (document, TRUE);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (element),
- WEBKIT_DOM_NODE (marker),
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
- NULL);
- if (selection_start_marker)
- *selection_start_marker = marker;
-}
-
-static void
-add_selection_markers_into_element_end (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker)
-{
- WebKitDOMElement *marker;
-
- marker = create_selection_marker (document, TRUE);
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
- if (selection_start_marker)
- *selection_start_marker = marker;
-
- marker = create_selection_marker (document, FALSE);
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (marker), NULL);
- if (selection_end_marker)
- *selection_end_marker = marker;
+*/
}
static void
refresh_spell_check (EHTMLEditorView *view,
gboolean enable_spell_check)
{
- EHTMLEditorSelection *selection;
- WebKitDOMDocument *document;
- WebKitDOMDOMSelection *dom_selection;
- WebKitDOMDOMWindow *window;
- WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMHTMLElement *body;
- WebKitDOMRange *end_range, *actual;
- WebKitDOMText *text;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- window = webkit_dom_document_get_default_view (document);
- dom_selection = webkit_dom_dom_window_get_selection (window);
-
- /* Enable/Disable spellcheck in composer */
- body = webkit_dom_document_get_body (document);
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body),
- "spellcheck",
- enable_spell_check ? "true" : "false",
- NULL);
-
- selection = e_html_editor_view_get_selection (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);
-
- /* Sometimes the web view is not focused, so we have to save the selection
- * manually into the body */
- if (!selection_start_marker || !selection_end_marker) {
- WebKitDOMNode *child;
-
- child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
- if (!child)
- return;
-
- add_selection_markers_into_element_start (
- document,
- WEBKIT_DOM_ELEMENT (child),
- &selection_start_marker,
- &selection_end_marker);
- }
-
/* Block callbacks of selection-changed signal as we don't want to
* recount all the block format things in EHTMLEditorSelection and here as well
* when we are moving with caret */
+/* FIXME WK2
g_signal_handlers_block_by_func (
view, html_editor_view_selection_changed_cb, NULL);
e_html_editor_selection_block_selection_changed (selection);
-
- /* Append some text on the end of the body */
- text = webkit_dom_document_create_text_node (document, "-x-evo-end");
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (text), NULL);
-
- /* Create range that's pointing on the end of this text */
- end_range = webkit_dom_document_create_range (document);
- webkit_dom_range_select_node_contents (
- end_range, WEBKIT_DOM_NODE (text), NULL);
- webkit_dom_range_collapse (end_range, FALSE, NULL);
-
- /* Move on the beginning of the document */
- webkit_dom_dom_selection_modify (
- dom_selection, "move", "backward", "documentboundary");
-
- /* Go through all words to spellcheck them. To avoid this we have to wait for
- * http://www.w3.org/html/wg/drafts/html/master/editing.html#dom-forcespellcheck */
- actual = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- /* We are moving forward word by word until we hit the text on the end of
- * the body that we previously inserted there */
- while (actual && webkit_dom_range_compare_boundary_points (end_range, 2, actual, NULL) != 0) {
- webkit_dom_dom_selection_modify (
- dom_selection, "move", "forward", "word");
- actual = webkit_dom_dom_selection_get_range_at (
- dom_selection, 0, NULL);
- }
-
- /* Remove the text that we inserted on the end of the body */
- remove_node (WEBKIT_DOM_NODE (text));
-
+*/
/* Unblock the callbacks */
+/*
g_signal_handlers_unblock_by_func (
view, html_editor_view_selection_changed_cb, NULL);
e_html_editor_selection_unblock_selection_changed (selection);
-
- e_html_editor_selection_restore (selection);
+*/
}
void
@@ -532,339 +399,6 @@ e_html_editor_view_force_spell_check (EHTMLEditorView *view)
refresh_spell_check (view, TRUE);
}
-static gint
-get_citation_level (WebKitDOMNode *node,
- gboolean set_plaintext_quoted)
-{
- WebKitDOMNode *parent = node;
- gint level = 0;
-
- while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
- if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
- webkit_dom_element_has_attribute (WEBKIT_DOM_ELEMENT (parent), "type")) {
- level++;
-
- if (set_plaintext_quoted) {
- element_add_class (
- WEBKIT_DOM_ELEMENT (parent),
- "-x-evo-plaintext-quoted");
- }
- }
-
- parent = webkit_dom_node_get_parent_node (parent);
- }
-
- return level;
-}
-
-static gchar *
-get_quotation_for_level (gint quote_level)
-{
- gint ii;
- GString *output = g_string_new ("");
-
- for (ii = 0; ii < quote_level; ii++) {
- g_string_append (output, "<span class=\"-x-evo-quote-character\">");
- g_string_append (output, QUOTE_SYMBOL);
- g_string_append (output, " ");
- g_string_append (output, "</span>");
- }
-
- return g_string_free (output, FALSE);
-}
-
-static void
-quote_plain_text_element_after_wrapping (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- gint quote_level)
-{
- WebKitDOMNodeList *list;
- WebKitDOMNode *quoted_node;
- gint length, ii;
- gchar *quotation;
-
- quoted_node = WEBKIT_DOM_NODE (
- webkit_dom_document_create_element (document, "SPAN", NULL));
- webkit_dom_element_set_class_name (
- WEBKIT_DOM_ELEMENT (quoted_node), "-x-evo-quoted");
- quotation = get_quotation_for_level (quote_level);
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (quoted_node), quotation, NULL);
-
- list = webkit_dom_element_query_selector_all (
- element, "br.-x-evo-wrap-br", NULL);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (element),
- quoted_node,
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)),
- NULL);
-
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *br = webkit_dom_node_list_item (list, ii);
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (br),
- webkit_dom_node_clone_node (quoted_node, TRUE),
- webkit_dom_node_get_next_sibling (br),
- NULL);
- }
-
- g_object_unref (list);
- g_free (quotation);
-}
-
-static gboolean
-is_citation_node (WebKitDOMNode *node)
-{
- char *value;
-
- if (!WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))
- return FALSE;
-
- value = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (node), "type");
-
- /* citation == <blockquote type='cite'> */
- if (g_strcmp0 (value, "cite") == 0) {
- g_free (value);
- return TRUE;
- } else {
- g_free (value);
- return FALSE;
- }
-}
-
-static gboolean
-return_pressed_in_empty_line (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document)
-{
- WebKitDOMDOMSelection *dom_selection;
- WebKitDOMDOMWindow *dom_window;
- WebKitDOMNode *node;
- WebKitDOMRange *range;
-
- dom_window = webkit_dom_document_get_default_view (document);
- dom_selection = webkit_dom_dom_window_get_selection (dom_window);
-
- range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- if (!range)
- return FALSE;
-
- node = webkit_dom_range_get_start_container (range, NULL);
- if (!WEBKIT_DOM_IS_TEXT (node)) {
- WebKitDOMNode *first_child;
-
- first_child = webkit_dom_node_get_first_child (node);
- if (first_child && WEBKIT_DOM_IS_ELEMENT (first_child) &&
- element_has_class (WEBKIT_DOM_ELEMENT (first_child), "-x-evo-quoted")) {
- WebKitDOMNode *prev_sibling;
-
- prev_sibling = webkit_dom_node_get_previous_sibling (node);
- if (!prev_sibling)
- return webkit_dom_range_get_collapsed (range, NULL);
- }
- }
-
- return FALSE;
-}
-
-static WebKitDOMNode *
-get_parent_block_node_from_child (WebKitDOMNode *node)
-{
- WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
- if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") ||
- WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (parent) ||
- element_has_tag (WEBKIT_DOM_ELEMENT (parent), "b") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (parent), "i") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (parent), "u"))
- parent = webkit_dom_node_get_parent_node (parent);
-
- return parent;
-}
-
-static WebKitDOMElement *
-prepare_paragraph (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document,
- gboolean with_selection)
-{
- WebKitDOMElement *element, *paragraph;
-
- paragraph = e_html_editor_selection_get_paragraph_element (
- selection, document, -1, 0);
-
- if (with_selection)
- add_selection_markers_into_element_start (
- document, paragraph, NULL, NULL);
-
- element = webkit_dom_document_create_element (document, "BR", NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (paragraph), WEBKIT_DOM_NODE (element), NULL);
-
- return paragraph;
-}
-
-static WebKitDOMElement *
-insert_new_line_into_citation (EHTMLEditorView *view,
- const gchar *html_to_insert)
-{
- gboolean html_mode, ret_val, avoid_editor_call;
- EHTMLEditorSelection *selection;
- WebKitDOMDocument *document;
- WebKitDOMElement *element, *paragraph = NULL;
-
- html_mode = e_html_editor_view_get_html_mode (view);
- selection = e_html_editor_view_get_selection (view);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- avoid_editor_call =
- return_pressed_in_empty_line (selection, document);
-
- if (avoid_editor_call) {
- WebKitDOMElement *selection_start_marker;
- WebKitDOMNode *current_block, *parent, *parent_block, *block_clone;
-
- e_html_editor_selection_save (selection);
-
- selection_start_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-start-marker");
-
- current_block = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker));
-
- block_clone = webkit_dom_node_clone_node (current_block, TRUE);
- /* Find selection start marker and restore it after the new line
- * is inserted */
- selection_start_marker = webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (block_clone), "#-x-evo-selection-start-marker", NULL);
-
- /* Find parent node that is immediate child of the BODY */
- /* Build the same structure of parent nodes of the current block */
- parent_block = current_block;
- parent = webkit_dom_node_get_parent_node (parent_block);
- while (parent && !WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
- WebKitDOMNode *node;
-
- parent_block = parent;
- node = webkit_dom_node_clone_node (parent_block, FALSE);
- webkit_dom_node_append_child (node, block_clone, NULL);
- block_clone = node;
- parent = webkit_dom_node_get_parent_node (parent_block);
- }
-
- paragraph = e_html_editor_selection_get_paragraph_element (
- selection, document, -1, 0);
-
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (paragraph),
- UNICODE_ZERO_WIDTH_SPACE,
- NULL);
-
- /* Insert the selection markers to right place */
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (paragraph),
- webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_start_marker)),
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
- NULL);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (paragraph),
- WEBKIT_DOM_NODE (selection_start_marker),
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (paragraph)),
- NULL);
-
- /* Insert the cloned nodes before the BODY parent node */
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent_block),
- block_clone,
- parent_block,
- NULL);
-
- /* Insert the new empty paragraph before the BODY parent node */
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent_block),
- WEBKIT_DOM_NODE (paragraph),
- parent_block,
- NULL);
-
- /* Remove the old block (its copy was moved to the right place) */
- remove_node (current_block);
-
- e_html_editor_selection_restore (selection);
-
- return NULL;
- } else {
- ret_val = e_html_editor_view_exec_command (
- view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_NEW_LINE_IN_QUOTED_CONTENT, NULL);
-
- if (!ret_val)
- return NULL;
-
- element = webkit_dom_document_query_selector (
- document, "body>br", NULL);
-
- if (!element)
- return NULL;
- }
-
- if (!html_mode) {
- WebKitDOMNode *next_sibling;
-
- next_sibling = webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (element));
-
- if (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (next_sibling)) {
- gint citation_level, length;
- gint word_wrap_length =
- e_html_editor_selection_get_word_wrap_length (selection);
- WebKitDOMNode *node;
-
- node = webkit_dom_node_get_first_child (next_sibling);
- while (node && is_citation_node (node))
- node = webkit_dom_node_get_first_child (node);
-
- citation_level = get_citation_level (node, FALSE);
- length = word_wrap_length - 2 * citation_level;
-
- /* Rewrap and requote first block after the newly inserted line */
- if (node && WEBKIT_DOM_IS_ELEMENT (node)) {
- remove_quoting_from_element (WEBKIT_DOM_ELEMENT (node));
- remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (node));
- node = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
- selection, WEBKIT_DOM_ELEMENT (node), length));
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (node), citation_level);
- }
-
- e_html_editor_view_force_spell_check (view);
- }
- }
-
- if (html_to_insert && *html_to_insert) {
- paragraph = prepare_paragraph (selection, document, FALSE);
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (paragraph),
- html_to_insert,
- NULL);
- add_selection_markers_into_element_end (
- document, paragraph, NULL, NULL);
- } else
- paragraph = prepare_paragraph (selection, document, TRUE);
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
- WEBKIT_DOM_NODE (paragraph),
- WEBKIT_DOM_NODE (element),
- NULL);
-
- remove_node (WEBKIT_DOM_NODE (element));
-
- e_html_editor_selection_restore (selection);
-
- return paragraph;
-}
-
static void
set_base64_to_element_attribute (EHTMLEditorView *view,
WebKitDOMElement *element,
@@ -960,100 +494,6 @@ change_cid_images_src_to_base64 (EHTMLEditorView *view)
g_hash_table_remove_all (view->priv->inline_images);
}
-/* For purpose of this function see e-mail-formatter-quote.c */
-static void
-put_body_in_citation (WebKitDOMDocument *document)
-{
- WebKitDOMElement *cite_body = webkit_dom_document_query_selector (
- document, "span.-x-evo-cite-body", NULL);
-
- if (cite_body) {
- WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
- WebKitDOMNode *citation;
- WebKitDOMNode *sibling;
-
- citation = WEBKIT_DOM_NODE (
- webkit_dom_document_create_element (document, "blockquote", NULL));
- webkit_dom_element_set_id (WEBKIT_DOM_ELEMENT (citation), "-x-evo-main-cite");
- webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (citation), "type", "cite", NULL);
-
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (body),
- citation,
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
- NULL);
-
- while ((sibling = webkit_dom_node_get_next_sibling (citation)))
- webkit_dom_node_append_child (citation, sibling, NULL);
- }
-}
-
-/* For purpose of this function see e-mail-formatter-quote.c */
-static void
-move_elements_to_body (WebKitDOMDocument *document)
-{
- WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
- WebKitDOMNodeList *list;
- gint ii;
-
- list = webkit_dom_document_query_selector_all (
- document, "span.-x-evo-to-body[data-headers]", NULL);
- for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
- WebKitDOMNode *child;
- WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
- while ((child = webkit_dom_node_get_first_child (node))) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (body),
- child,
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (body)),
- NULL);
- }
-
- remove_node (node);
- }
- g_object_unref (list);
-
- list = webkit_dom_document_query_selector_all (
- document, "span.-x-evo-to-body[data-credits]", NULL);
- for (ii = webkit_dom_node_list_get_length (list) - 1; ii >= 0; ii--) {
- WebKitDOMNode *child;
- WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
- while ((child = webkit_dom_node_get_first_child (node))) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (body),
- child,
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (body)),
- NULL);
- }
-
- remove_node (node);
- }
- g_object_unref (list);
-}
-
-static void
-repair_gmail_blockquotes (WebKitDOMDocument *document)
-{
- WebKitDOMNodeList *list;
- gint ii, length;
-
- list = webkit_dom_document_query_selector_all (
- document, "blockquote.gmail_quote", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node = webkit_dom_node_list_item (list, ii);
-
- webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "class");
- webkit_dom_element_remove_attribute (WEBKIT_DOM_ELEMENT (node), "style");
- webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (node), "type", "cite", NULL);
- }
- g_object_unref (list);
-}
-
/* Based on original use_pictograms() from GtkHTML */
static const gchar *emoticons_chars =
/* 0 */ "DO)(|/PQ*!"
@@ -1484,7 +924,7 @@ emoticon_read_async_cb (GFile *file,
misplaced_selection = TRUE;
mime_type = g_content_type_get_mime_type (load_context->content_type);
- range = html_editor_view_get_dom_range (view);
+ range = dom_get_range (view);
node = webkit_dom_range_get_end_container (range, NULL);
if (WEBKIT_DOM_IS_TEXT (node))
node_text = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (node));
@@ -1683,395 +1123,34 @@ html_editor_view_check_magic_smileys (EHTMLEditorView *view,
}
static void
-html_editor_view_set_links_active (EHTMLEditorView *view,
- gboolean active)
-{
- WebKitDOMDocument *document;
- WebKitDOMElement *style;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- if (active) {
- style = webkit_dom_document_get_element_by_id (
- document, "--evolution-editor-style-a");
- if (style)
- remove_node (WEBKIT_DOM_NODE (style));
- } else {
- WebKitDOMHTMLHeadElement *head;
- head = webkit_dom_document_get_head (document);
-
- style = webkit_dom_document_create_element (document, "STYLE", NULL);
- webkit_dom_element_set_id (style, "--evolution-editor-style-a");
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (style), "a { cursor: text; }", NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (head), WEBKIT_DOM_NODE (style), NULL);
- }
-}
-
-static void
-fix_paragraph_structure_after_pressing_enter_after_smiley (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document)
-{
- WebKitDOMElement *element;
-
- element = webkit_dom_document_query_selector (
- document, "span.-x-evo-smiley-wrapper > br", NULL);
-
- if (element) {
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element));
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (
- webkit_dom_node_get_parent_node (parent)),
- UNICODE_ZERO_WIDTH_SPACE,
- NULL);
- }
-}
-
-static void
-mark_node_as_paragraph_after_ending_list (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document)
-{
- gint ii, length;
- WebKitDOMNodeList *list;
-
- /* When pressing Enter on empty line in the list WebKit will end that
- * list and inserts <div><br></div> so mark it for wrapping */
- list = webkit_dom_document_query_selector_all (
- document, "body > div:not(.-x-evo-paragraph) > br", NULL);
-
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node = webkit_dom_node_get_parent_node (
- webkit_dom_node_list_item (list, ii));
-
- e_html_editor_selection_set_paragraph_style (
- selection, WEBKIT_DOM_ELEMENT (node), -1, 0, "");
- }
- g_object_unref (list);
-}
-
-static gboolean
-surround_text_with_paragraph_if_needed (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document,
- WebKitDOMNode *node)
-{
- WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
- WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (node);
- WebKitDOMElement *element;
-
- /* All text in composer has to be written in div elements, so if
- * we are writing something straight to the body, surround it with
- * paragraph */
- if (WEBKIT_DOM_IS_TEXT (node) &&
- WEBKIT_DOM_IS_HTML_BODY_ELEMENT (webkit_dom_node_get_parent_node (node))) {
- element = e_html_editor_selection_put_node_into_paragraph (
- selection,
- document,
- node,
- e_html_editor_selection_get_caret_position_node (document));
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
- remove_node (next_sibling);
-
- /* Tab character */
- if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
- element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "Apple-tab-span")) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (element),
- prev_sibling,
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (element)),
- NULL);
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-body_input_event_cb (WebKitDOMElement *element,
- WebKitDOMEvent *event,
- EHTMLEditorView *view)
+insert_and_convert_html_into_selection (EHTMLEditorView *view,
+ const gchar *text,
+ gboolean is_html)
{
- EHTMLEditorSelection *selection;
- GdkEventKey *key_event;
- WebKitDOMNode *node;
- WebKitDOMRange *range = html_editor_view_get_dom_range (view);
- WebKitDOMDocument *document;
-
- selection = e_html_editor_view_get_selection (view);
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
+ GDBusProxy *web_extension;
- e_html_editor_view_set_changed (view, TRUE);
- key_event = view->priv->key_event;
+ g_return_if_fail (view != NULL);
- if (!key_event)
+ if (!text || !*text)
return;
- if (view->priv->magic_smileys && view->priv->html_mode)
- html_editor_view_check_magic_smileys (view, range);
-
- if (is_return_key (key_event) || (key_event->keyval == GDK_KEY_space)) {
- html_editor_view_check_magic_links (view, range, FALSE, key_event);
- mark_node_as_paragraph_after_ending_list (selection, document);
- if (view->priv->html_mode)
- fix_paragraph_structure_after_pressing_enter_after_smiley (
- selection, document);
- } else {
- WebKitDOMNode *node;
-
- node = webkit_dom_range_get_end_container (range, NULL);
-
- if (surround_text_with_paragraph_if_needed (selection, document, node)) {
- e_html_editor_selection_restore_caret_position (selection);
- node = webkit_dom_range_get_end_container (range, NULL);
- range = html_editor_view_get_dom_range (view);
- }
-
- if (WEBKIT_DOM_IS_TEXT (node)) {
- gchar *text;
-
- text = webkit_dom_node_get_text_content (node);
-
- if (g_strcmp0 (text, "") != 0 && !g_unichar_isspace (g_utf8_get_char (text))) {
- WebKitDOMNode *prev_sibling;
-
- prev_sibling = webkit_dom_node_get_previous_sibling (node);
-
- if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling))
- html_editor_view_check_magic_links (view, range, FALSE, key_event);
- }
- g_free (text);
- }
- }
-
- node = webkit_dom_range_get_end_container (range, NULL);
-
- /* After toggling monospaced format, we are using UNICODE_ZERO_WIDTH_SPACE
- * to move caret into right space. When this callback is called it is not
- * necassary anymore so remove it */
- if (view->priv->html_mode) {
- WebKitDOMElement *parent = webkit_dom_node_get_parent_element (node);
-
- if (parent) {
- WebKitDOMNode *prev_sibling;
-
- prev_sibling = webkit_dom_node_get_previous_sibling (
- WEBKIT_DOM_NODE (parent));
-
- if (prev_sibling && WEBKIT_DOM_IS_TEXT (prev_sibling)) {
- gchar *text = webkit_dom_node_get_text_content (
- prev_sibling);
-
- if (g_strcmp0 (text, UNICODE_ZERO_WIDTH_SPACE) == 0)
- remove_node (prev_sibling);
-
- g_free (text);
- }
-
- }
- }
-
- /* If text before caret includes UNICODE_ZERO_WIDTH_SPACE character, remove it */
- if (WEBKIT_DOM_IS_TEXT (node)) {
- gchar *text = webkit_dom_character_data_get_data (WEBKIT_DOM_CHARACTER_DATA (node));
- glong length = g_utf8_strlen (text, -1);
- WebKitDOMNode *parent;
-
- /* We have to preserve empty paragraphs with just UNICODE_ZERO_WIDTH_SPACE
- * character as when we will remove it it will collapse */
- if (length > 1) {
- if (g_str_has_prefix (text, UNICODE_ZERO_WIDTH_SPACE))
- webkit_dom_character_data_replace_data (
- WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
- else if (g_str_has_suffix (text, UNICODE_ZERO_WIDTH_SPACE))
- webkit_dom_character_data_replace_data (
- WEBKIT_DOM_CHARACTER_DATA (node), length - 1, 1, "", NULL);
- }
- g_free (text);
-
- parent = webkit_dom_node_get_parent_node (node);
- if ((WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (parent) ||
- WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent)) &&
- !element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph")) {
- if (e_html_editor_view_get_html_mode (view)) {
- element_add_class (
- WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph");
- } else {
- e_html_editor_selection_set_paragraph_style (
- selection,
- WEBKIT_DOM_ELEMENT (parent),
- -1, 0, "");
- }
- }
-
- /* When new smiley is added we have to use UNICODE_HIDDEN_SPACE to set the
- * caret position to right place. It is removed when user starts typing. But
- * when the user will press left arrow he will move the caret into
- * smiley wrapper. If he will start to write there we have to move the written
- * text out of the wrapper and move caret to right place */
- if (WEBKIT_DOM_IS_ELEMENT (parent) &&
- element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-smiley-wrapper")) {
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- e_html_editor_selection_get_caret_position_node (
- document),
- webkit_dom_node_get_next_sibling (parent),
- NULL);
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- node,
- webkit_dom_node_get_next_sibling (parent),
- NULL);
- e_html_editor_selection_restore_caret_position (selection);
- }
- }
-
- /* Writing into quoted content */
- if (!view->priv->html_mode) {
- gint citation_level;
- WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMNode *node, *parent;
- WebKitDOMRange *range;
-
- range = html_editor_view_get_dom_range (view);
- node = webkit_dom_range_get_end_container (range, NULL);
-
- citation_level = get_citation_level (node, FALSE);
- if (citation_level == 0)
- return;
-
- selection_start_marker = webkit_dom_document_query_selector (
- document, "span#-x-evo-selection-start-marker", NULL);
- if (selection_start_marker)
- return;
-
- 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 the selection was not saved, move it into the first child of body */
- if (!selection_start_marker || !selection_end_marker) {
- WebKitDOMHTMLElement *body;
- WebKitDOMNode *child;
-
- body = webkit_dom_document_get_body (document);
- child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
-
- add_selection_markers_into_element_start (
- document,
- WEBKIT_DOM_ELEMENT (child),
- &selection_start_marker,
- &selection_end_marker);
- }
-
- /* We have to process elements only inside normal block */
- parent = WEBKIT_DOM_NODE (get_parent_block_element (
- WEBKIT_DOM_NODE (selection_start_marker)));
- if (WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent)) {
- e_html_editor_selection_restore (selection);
- return;
- }
-
- if (selection_start_marker) {
- gchar *content;
- gint text_length, word_wrap_length, length;
- WebKitDOMElement *block;
- gboolean remove_quoting = FALSE;
-
- word_wrap_length =
- e_html_editor_selection_get_word_wrap_length (selection);
- length = word_wrap_length - 2 * citation_level;
-
- block = WEBKIT_DOM_ELEMENT (parent);
- if (webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
- WebKitDOMNode *prev_sibling;
-
- prev_sibling = webkit_dom_node_get_previous_sibling (
- WEBKIT_DOM_NODE (selection_end_marker));
-
- if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
- remove_quoting = element_has_class (
- WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
- }
-
- content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (block));
- text_length = g_utf8_strlen (content, -1);
- g_free (content);
-
- /* Wrap and quote the line */
- if (!remove_quoting && text_length >= word_wrap_length) {
- remove_quoting_from_element (block);
-
- block = e_html_editor_selection_wrap_paragraph_length (
- selection, block, length);
- webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (block), citation_level);
- selection_start_marker = webkit_dom_document_query_selector (
- document, "span#-x-evo-selection-start-marker", NULL);
- if (!selection_start_marker)
- add_selection_markers_into_element_end (
- document,
- WEBKIT_DOM_ELEMENT (block),
- NULL,
- NULL);
-
- e_html_editor_selection_restore (selection);
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
- return;
- }
- }
- e_html_editor_selection_restore (selection);
- }
-}
-
-static void
-remove_input_event_listener_from_body (EHTMLEditorView *view)
-{
- if (!view->priv->body_input_event_removed) {
- WebKitDOMDocument *document;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- webkit_dom_event_target_remove_event_listener (
- WEBKIT_DOM_EVENT_TARGET (
- webkit_dom_document_get_body (document)),
- "input",
- G_CALLBACK (body_input_event_cb),
- FALSE);
-
- view->priv->body_input_event_removed = TRUE;
- }
-}
-
-static void
-register_input_event_listener_on_body (EHTMLEditorView *view)
-{
- if (view->priv->body_input_event_removed) {
- WebKitDOMDocument *document;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (
- webkit_dom_document_get_body (document)),
- "input",
- G_CALLBACK (body_input_event_cb),
- FALSE,
- view);
+ web_extension = e_html_editor_view_get_web_extension_proxy (view);
+ if (!web_extension)
+ return;
- view->priv->body_input_event_removed = FALSE;
- }
+ g_dbus_proxy_call (
+ web_extension,
+ "DOMInsertAndConvertHTMLIntoSelection",
+ g_variant_new (
+ "(tsb)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ text,
+ is_html),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
}
static void
@@ -2079,14 +1158,7 @@ clipboard_text_received_for_paste_as_text (GtkClipboard *clipboard,
const gchar *text,
EHTMLEditorView *view)
{
- EHTMLEditorSelection *selection;
-
- if (!text || !*text)
- return;
-
- selection = e_html_editor_view_get_selection (view);
-
- html_editor_view_insert_converted_html_into_selection (view, TRUE, html);
+ insert_and_convert_html_into_selection (view, text, TRUE);
}
static void
@@ -2094,65 +1166,29 @@ clipboard_text_received (GtkClipboard *clipboard,
const gchar *text,
EHTMLEditorView *view)
{
- EHTMLEditorSelection *selection;
- gchar *escaped_text;
- WebKitDOMDocument *document;
- WebKitDOMDOMWindow *window;
- WebKitDOMDOMSelection *dom_selection;
- WebKitDOMElement *blockquote, *element;
- WebKitDOMNode *node;
- WebKitDOMRange *range;
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (view != NULL);
if (!text || !*text)
return;
- selection = e_html_editor_view_get_selection (view);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- window = webkit_dom_document_get_default_view (document);
- dom_selection = webkit_dom_dom_window_get_selection (window);
-
- /* This is a trick to escape any HTML characters (like <, > or &).
- * <textarea> automatically replaces all these unsafe characters
- * by <, > etc. */
- element = webkit_dom_document_create_element (document, "textarea", NULL);
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element), text, NULL);
- escaped_text = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element));
-
- element = webkit_dom_document_create_element (document, "pre", NULL);
-
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (element), escaped_text, NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (element),
- e_html_editor_selection_get_caret_position_node (document),
- NULL);
-
- blockquote = webkit_dom_document_create_element (document, "blockquote", NULL);
- webkit_dom_element_set_attribute (blockquote, "type", "cite", NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (blockquote), WEBKIT_DOM_NODE (element), NULL);
-
- if (!e_html_editor_view_get_html_mode (view))
- e_html_editor_view_quote_plain_text_element (view, element);
-
- range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
- node = webkit_dom_range_get_end_container (range, NULL);
+ web_extension = e_html_editor_view_get_web_extension_proxy (view);
+ if (!web_extension)
+ return;
- webkit_dom_node_append_child (
- webkit_dom_node_get_parent_node (node),
- WEBKIT_DOM_NODE (blockquote),
+ g_dbus_proxy_call (
+ web_extension,
+ "DOMQuoteAndInsertTextIntoSelection",
+ g_variant_new (
+ "(tsb)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ text),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
NULL);
-
- e_html_editor_selection_restore_caret_position (selection);
-
- e_html_editor_view_force_spell_check_for_current_paragraph (view);
-
- g_free (escaped_text);
}
static void
@@ -2205,32 +1241,32 @@ html_editor_view_get_property (GObject *object,
switch (property_id) {
case PROP_CAN_COPY:
g_value_set_boolean (
- value, webkit_web_view_can_copy_clipboard (
- WEBKIT_WEB_VIEW (object)));
+ value, html_editor_view_can_copy (
+ E_HTML_EDITOR_VIEW (object)));
return;
case PROP_CAN_CUT:
g_value_set_boolean (
- value, webkit_web_view_can_cut_clipboard (
- WEBKIT_WEB_VIEW (object)));
+ value, html_editor_view_can_cut (
+ E_HTML_EDITOR_VIEW (object)));
return;
case PROP_CAN_PASTE:
g_value_set_boolean (
- value, webkit_web_view_can_paste_clipboard (
- WEBKIT_WEB_VIEW (object)));
+ value, html_editor_view_can_paste (
+ E_HTML_EDITOR_VIEW (object)));
return;
case PROP_CAN_REDO:
g_value_set_boolean (
- value, webkit_web_view_can_redo (
- WEBKIT_WEB_VIEW (object)));
+ value, html_editor_view_can_redo (
+ E_HTML_EDITOR_VIEW (object)));
return;
case PROP_CAN_UNDO:
g_value_set_boolean (
- value, webkit_web_view_can_undo (
- WEBKIT_WEB_VIEW (object)));
+ value, html_editor_view_can_undo (
+ E_HTML_EDITOR_VIEW (object)));
return;
case PROP_CHANGED:
@@ -2452,218 +1488,6 @@ html_editor_view_button_release_event (GtkWidget *widget,
}
static gboolean
-prevent_from_deleting_last_element_in_body (EHTMLEditorView *view)
-{
- gboolean ret_val = FALSE;
- WebKitDOMDocument *document;
- WebKitDOMHTMLElement *body;
- WebKitDOMNodeList *list;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = webkit_dom_document_get_body (document);
-
- list = webkit_dom_node_get_child_nodes (WEBKIT_DOM_NODE (body));
-
- if (webkit_dom_node_list_get_length (list) <= 1) {
- gchar *content;
-
- content = webkit_dom_node_get_text_content (WEBKIT_DOM_NODE (body));
-
- if (!*content)
- ret_val = TRUE;
-
- g_free (content);
-
- if (webkit_dom_element_query_selector (WEBKIT_DOM_ELEMENT (body), "img", NULL))
- ret_val = FALSE;
- }
- g_object_unref (list);
-
- return ret_val;
-}
-
-static gboolean
-change_quoted_block_to_normal (EHTMLEditorView *view)
-{
- gint citation_level, success = FALSE;
- WebKitDOMDocument *document;
- WebKitDOMElement *selection_start_marker, *selection_end_marker, *block;
-
- 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);
-
- if (!selection_start_marker || !selection_end_marker)
- return FALSE;
-
- block = WEBKIT_DOM_ELEMENT (get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker)));
-
- citation_level = get_citation_level (
- WEBKIT_DOM_NODE (selection_start_marker), FALSE);
-
- if (selection_start_marker && citation_level > 0) {
- if (webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (block), ".-x-evo-quoted", NULL)) {
-
- WebKitDOMNode *prev_sibling;
-
- webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
-
- prev_sibling = webkit_dom_node_get_previous_sibling (
- WEBKIT_DOM_NODE (selection_start_marker));
-
- if (WEBKIT_DOM_IS_ELEMENT (prev_sibling))
- success = element_has_class (
- WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-quoted");
- /* We really have to be in the beginning of paragraph and
- * not on the beginning of some line in the paragraph */
- if (success && webkit_dom_node_get_previous_sibling (prev_sibling))
- success = FALSE;
- }
-
- if (view->priv->html_mode)
- success = WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (
- webkit_dom_node_get_parent_element (
- WEBKIT_DOM_NODE (block)));
- }
-
- if (success && citation_level == 1) {
- gchar *inner_html;
- WebKitDOMElement *paragraph;
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (block));
- webkit_dom_element_set_id (
- WEBKIT_DOM_ELEMENT (block), "-x-evo-to-remove");
-
- paragraph = insert_new_line_into_citation (view, inner_html);
- g_free (inner_html);
-
- if (paragraph) {
- if (view->priv->html_mode) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (paragraph),
- WEBKIT_DOM_NODE (selection_start_marker),
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (paragraph)),
- NULL);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (paragraph),
- WEBKIT_DOM_NODE (selection_end_marker),
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (paragraph)),
- NULL);
-
- }
-
- remove_quoting_from_element (paragraph);
- remove_wrapping_from_element (paragraph);
- }
-
- if (block)
- remove_node (WEBKIT_DOM_NODE (block));
- block = webkit_dom_document_get_element_by_id (
- document, "-x-evo-to-remove");
- if (block)
- remove_node (WEBKIT_DOM_NODE (block));
-
- if (paragraph)
- remove_node_if_empty (
- webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (paragraph)));
- }
-
- if (success && citation_level > 1) {
- gint length, word_wrap_length;
- EHTMLEditorSelection *selection;
- WebKitDOMNode *parent;
-
- selection = e_html_editor_view_get_selection (view);
- word_wrap_length = e_html_editor_selection_get_word_wrap_length (selection);
- length = word_wrap_length - 2 * (citation_level - 1);
-
- if (view->priv->html_mode) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (block),
- WEBKIT_DOM_NODE (selection_start_marker),
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (block)),
- NULL);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (block),
- WEBKIT_DOM_NODE (selection_end_marker),
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (block)),
- NULL);
-
- }
-
- remove_quoting_from_element (block);
- remove_wrapping_from_element (block);
-
- block = e_html_editor_selection_wrap_paragraph_length (
- selection, block, length);
- webkit_dom_node_normalize (WEBKIT_DOM_NODE (block));
- quote_plain_text_element_after_wrapping (
- document, block, citation_level - 1);
-
- parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (block));
-
- if (!webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (block))) {
- /* Currect block is in the beginning of citation, just move it
- * before the citation where already is */
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- WEBKIT_DOM_NODE (block),
- parent,
- NULL);
- } else if (!webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block))) {
- /* Currect block is at the end of the citation, just move it
- * after the citation where already is */
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- WEBKIT_DOM_NODE (block),
- webkit_dom_node_get_next_sibling (parent),
- NULL);
- } else {
- /* Current block is somewhere in the middle of the citation
- * so we need to split the citation and insert the block into
- * the citation that is one level lower */
- WebKitDOMNode *clone, *child;
-
- clone = webkit_dom_node_clone_node (parent, FALSE);
-
- /* Move nodes that are after the currect block into the
- * new blockquote */
- child = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (block));
- while (child) {
- WebKitDOMNode *next = webkit_dom_node_get_next_sibling (child);
- webkit_dom_node_append_child (clone, child, NULL);
- child = next;
- }
-
- clone = webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- clone,
- webkit_dom_node_get_next_sibling (parent),
- NULL);
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- WEBKIT_DOM_NODE (block),
- clone,
- NULL);
- }
- }
-
- return success;
-}
-
-static gboolean
html_editor_view_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
@@ -2922,101 +1746,6 @@ html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
view);
}
-static gboolean
-html_editor_view_image_exists_in_cache (const gchar *image_uri)
-{
- gchar *filename;
- gchar *hash;
- gboolean exists = FALSE;
-
- g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
-
- hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
- filename = camel_data_cache_get_filename (
- emd_global_http_cache, "http", hash);
-
- if (filename != NULL) {
- exists = g_file_test (filename, G_FILE_TEST_EXISTS);
- g_free (filename);
- }
-
- g_free (hash);
-
- return exists;
-}
-
-static gchar *
-html_editor_view_redirect_uri (EHTMLEditorView *view,
- const gchar *uri)
-{
- EImageLoadingPolicy image_policy;
- GSettings *settings;
- gboolean uri_is_http;
-
- uri_is_http =
- g_str_has_prefix (uri, "http:") ||
- g_str_has_prefix (uri, "https:") ||
- g_str_has_prefix (uri, "evo-http:") ||
- g_str_has_prefix (uri, "evo-https:");
-
- /* Redirect http(s) request to evo-http(s) protocol.
- * See EMailRequest for further details about this. */
- if (uri_is_http) {
- gchar *new_uri;
- SoupURI *soup_uri;
- gboolean image_exists;
-
- /* Check Evolution's cache */
- image_exists = html_editor_view_image_exists_in_cache (uri);
-
- settings = e_util_ref_settings ("org.gnome.evolution.mail");
- image_policy = g_settings_get_enum (settings, "image-loading-policy");
- g_object_unref (settings);
- /* If the URI is not cached and we are not allowed to load it
- * then redirect to invalid URI, so that webkit would display
- * a native placeholder for it. */
- if (!image_exists && (image_policy == E_IMAGE_LOADING_POLICY_NEVER)) {
- return g_strdup ("about:blank");
- }
-
- new_uri = g_strconcat ("evo-", uri, NULL);
- soup_uri = soup_uri_new (new_uri);
- g_free (new_uri);
-
- new_uri = soup_uri_to_string (soup_uri, FALSE);
-
- soup_uri_free (soup_uri);
-
- return new_uri;
- }
-
- return g_strdup (uri);
-}
-
-static void
-html_editor_view_resource_requested (WebKitWebView *web_view,
- WebKitWebFrame *frame,
- WebKitWebResource *resource,
- WebKitNetworkRequest *request,
- WebKitNetworkResponse *response,
- gpointer user_data)
-{
- const gchar *original_uri;
-
- original_uri = webkit_network_request_get_uri (request);
-
- if (original_uri != NULL) {
- gchar *redirected_uri;
-
- redirected_uri = html_editor_view_redirect_uri (
- E_HTML_EDITOR_VIEW (web_view), original_uri);
-
- webkit_network_request_set_uri (request, redirected_uri);
-
- g_free (redirected_uri);
- }
-}
-
static void
web_extension_proxy_created_cb (GDBusProxy *proxy,
GAsyncResult *result,
@@ -3044,7 +1773,7 @@ web_extension_appeared_cb (GDBusConnection *connection,
NULL,
name,
E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
- E_HTML_EDITOR_WEB_EXTENSION_INTERFACE
+ E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
NULL,
(GAsyncReadyCallback) web_extension_proxy_created_cb,
view);
@@ -3055,7 +1784,7 @@ web_extension_vanished_cb (GDBusConnection *connection,
const gchar *name,
EHTMLEditorView *view)
{
- g_clear_object (&web_view->priv->web_extension);
+ g_clear_object (&view->priv->web_extension);
}
static void
@@ -3109,7 +1838,7 @@ e_html_editor_view_get_element_attribute (EHTMLEditorView *view,
const gchar *attribute)
{
if (!view->priv->web_extension)
- return;
+ return NULL;
return g_dbus_proxy_call_sync (
view->priv->web_extension,
@@ -3122,7 +1851,6 @@ e_html_editor_view_get_element_attribute (EHTMLEditorView *view,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
- NULL,
NULL);
}
@@ -3175,9 +1903,9 @@ e_html_editor_view_remove_element_attribute (EHTMLEditorView *view,
}
static GObjectConstructParam*
-find_property(guint n_properties,
- GObjectConstructParam* properties,
- GParamSpec* param_spec)
+find_property (guint n_properties,
+ GObjectConstructParam* properties,
+ GParamSpec* param_spec)
{
while (n_properties--) {
if (properties->pspec == param_spec)
@@ -3188,7 +1916,7 @@ find_property(guint n_properties,
return NULL;
}
-static GObject*
+static GObject *
html_editor_view_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties)
@@ -3211,7 +1939,7 @@ html_editor_view_constructor (GType type,
g_type_class_unref (object_class);
- return G_OBJECT_CLASS (e_web_view_parent_class)->constructor(type, n_construct_properties,
construct_properties);
+ return G_OBJECT_CLASS (e_html_editor_view_parent_class)->constructor(type, n_construct_properties,
construct_properties);
}
static void
@@ -3467,1834 +2195,6 @@ e_html_editor_view_class_init (EHTMLEditorViewClass *class)
}
static void
-insert_quote_symbols (WebKitDOMHTMLElement *element,
- gint quote_level,
- gboolean skip_first,
- gboolean insert_newline)
-{
- gchar *text;
- gint ii;
- GString *output;
- gchar *quotation;
-
- if (!WEBKIT_DOM_IS_HTML_ELEMENT (element))
- return;
-
- text = webkit_dom_html_element_get_inner_html (element);
- output = g_string_new ("");
- quotation = get_quotation_for_level (quote_level);
-
- if (g_strcmp0 (text, "\n") == 0) {
- g_string_append (output, "<span class=\"-x-evo-quoted\">");
- g_string_append (output, quotation);
- g_string_append (output, "</span>");
- g_string_append (output, "\n");
- } else {
- gchar **lines;
-
- lines = g_strsplit (text, "\n", 0);
-
- for (ii = 0; lines[ii]; ii++) {
- if (ii == 0 && skip_first) {
- if (g_strv_length (lines) == 1) {
- g_strfreev (lines);
- goto exit;
- }
- g_string_append (output, lines[ii]);
- g_string_append (output, "\n");
- }
-
- g_string_append (output, "<span class=\"-x-evo-quoted\">");
- g_string_append (output, quotation);
- g_string_append (output, "</span>");
-
- /* Insert line of text */
- g_string_append (output, lines[ii]);
- if ((ii == g_strv_length (lines) - 1) &&
- !g_str_has_suffix (text, "\n") && !insert_newline) {
- /* If we are on last line and node's text doesn't
- * end with \n, don't insert it */
- break;
- }
- g_string_append (output, "\n");
- }
-
- g_strfreev (lines);
- }
-
- webkit_dom_html_element_set_inner_html (element, output->str, NULL);
- exit:
- g_free (quotation);
- g_free (text);
- g_string_free (output, TRUE);
-}
-
-static void
-quote_node (WebKitDOMDocument *document,
- WebKitDOMNode *node,
- gint quote_level)
-{
- gboolean skip_first = FALSE;
- gboolean insert_newline = FALSE;
- gboolean is_html_node = FALSE;
- WebKitDOMElement *wrapper;
- WebKitDOMNode *node_clone, *prev_sibling, *next_sibling;
-
- /* Don't quote when we are not in citation */
- if (quote_level == 0)
- return;
-
- if (WEBKIT_DOM_IS_COMMENT (node))
- return;
-
- if (WEBKIT_DOM_IS_HTML_ELEMENT (node)) {
- insert_quote_symbols (
- WEBKIT_DOM_HTML_ELEMENT (node), quote_level, FALSE, FALSE);
- return;
- }
-
- prev_sibling = webkit_dom_node_get_previous_sibling (node);
- next_sibling = webkit_dom_node_get_next_sibling (node);
-
- is_html_node =
- !WEBKIT_DOM_IS_TEXT (prev_sibling) &&
- !WEBKIT_DOM_IS_COMMENT (prev_sibling) && (
- WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling) ||
- element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "b") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "i") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (prev_sibling), "u"));
-
- if (prev_sibling && is_html_node)
- skip_first = TRUE;
-
- /* Skip the BR between first blockquote and pre */
- if (quote_level == 1 && next_sibling && WEBKIT_DOM_IS_HTML_PRE_ELEMENT (next_sibling))
- return;
-
- /* Do temporary wrapper */
- wrapper = webkit_dom_document_create_element (document, "SPAN", NULL);
- webkit_dom_element_set_class_name (wrapper, "-x-evo-temp-text-wrapper");
-
- node_clone = webkit_dom_node_clone_node (node, TRUE);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (wrapper),
- node_clone,
- NULL);
-
- insert_quote_symbols (
- WEBKIT_DOM_HTML_ELEMENT (wrapper),
- quote_level,
- skip_first,
- insert_newline);
-
- webkit_dom_node_replace_child (
- webkit_dom_node_get_parent_node (node),
- WEBKIT_DOM_NODE (wrapper),
- node,
- NULL);
-}
-
-static void
-insert_quote_symbols_before_node (WebKitDOMDocument *document,
- WebKitDOMNode *node,
- gint quote_level,
- gboolean is_html_node)
-{
- gboolean skip, wrap_br;
- gchar *quotation;
- WebKitDOMElement *element;
-
- quotation = get_quotation_for_level (quote_level);
- element = webkit_dom_document_create_element (document, "SPAN", NULL);
- element_add_class (element, "-x-evo-quoted");
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element), quotation, NULL);
-
- /* Don't insert temporary BR before BR that is used for wrapping */
- skip = WEBKIT_DOM_IS_HTMLBR_ELEMENT (node);
- wrap_br = element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br");
- skip = skip && wrap_br;
-
- if (is_html_node && !skip) {
- WebKitDOMElement *new_br;
-
- new_br = webkit_dom_document_create_element (document, "br", NULL);
- element_add_class (new_br, "-x-evo-temp-br");
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (node),
- WEBKIT_DOM_NODE (new_br),
- node,
- NULL);
- }
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (node),
- WEBKIT_DOM_NODE (element),
- node,
- NULL);
-
- if (is_html_node && !wrap_br)
- remove_node (node);
-
- g_free (quotation);
-}
-
-static gboolean
-element_is_selection_marker (WebKitDOMElement *element)
-{
- gboolean is_marker = FALSE;
-
- is_marker =
- element_has_id (element, "-x-evo-selection-start-marker") ||
- element_has_id (element, "-x-evo-selection-end-marker");
-
- return is_marker;
-}
-
-static gboolean
-check_if_suppress_next_node (WebKitDOMNode *node)
-{
- if (!node)
- return FALSE;
-
- if (node && WEBKIT_DOM_IS_ELEMENT (node))
- if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node)))
- if (!webkit_dom_node_get_previous_sibling (node))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-quote_br_node (WebKitDOMNode *node,
- gint quote_level)
-{
- gchar *quotation, *content;
-
- quotation = get_quotation_for_level (quote_level);
-
- content = g_strconcat (
- "<span class=\"-x-evo-quoted\">",
- quotation,
- "</span><br class=\"-x-evo-temp-br\">",
- NULL);
-
- webkit_dom_html_element_set_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (node),
- content,
- NULL);
-
- g_free (content);
- g_free (quotation);
-}
-
-static void
-quote_plain_text_recursive (WebKitDOMDocument *document,
- WebKitDOMNode *node,
- WebKitDOMNode *start_node,
- gint quote_level)
-{
- gboolean skip_node = FALSE;
- gboolean move_next = FALSE;
- gboolean suppress_next = FALSE;
- gboolean is_html_node = FALSE;
- gboolean next = FALSE;
- WebKitDOMNode *next_sibling, *prev_sibling;
-
- node = webkit_dom_node_get_first_child (node);
-
- while (node) {
- gchar *text_content;
-
- skip_node = FALSE;
- move_next = FALSE;
- is_html_node = FALSE;
-
- if (WEBKIT_DOM_IS_COMMENT (node) ||
- WEBKIT_DOM_IS_HTML_META_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_STYLE_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (node)) {
-
- move_next = TRUE;
- goto next_node;
- }
-
- prev_sibling = webkit_dom_node_get_previous_sibling (node);
- next_sibling = webkit_dom_node_get_next_sibling (node);
-
- if (WEBKIT_DOM_IS_TEXT (node)) {
- /* Start quoting after we are in blockquote */
- if (quote_level > 0 && !suppress_next) {
- /* When quoting text node, we are wrappering it and
- * afterwards replacing it with that wrapper, thus asking
- * for next_sibling after quoting will return NULL bacause
- * that node don't exist anymore */
- quote_node (document, node, quote_level);
- node = next_sibling;
- skip_node = TRUE;
- }
-
- goto next_node;
- }
-
- if (!(WEBKIT_DOM_IS_ELEMENT (node) || WEBKIT_DOM_IS_HTML_ELEMENT (node)))
- goto next_node;
-
- if (element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-position")) {
- if (quote_level > 0)
- element_add_class (
- WEBKIT_DOM_ELEMENT (node), "-x-evo-caret-quoting");
-
- move_next = TRUE;
- suppress_next = TRUE;
- next = FALSE;
- goto next_node;
- }
-
- if (element_is_selection_marker (WEBKIT_DOM_ELEMENT (node))) {
- /* If there is collapsed selection in the beginning of line
- * we cannot suppress first text that is after the end of
- * selection */
- suppress_next = check_if_suppress_next_node (prev_sibling);
- if (suppress_next)
- next = FALSE;
- move_next = TRUE;
- goto next_node;
- }
-
- if (!WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) &&
- webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (node)) != 0)
- goto with_children;
-
- /* Even in plain text mode we can have some basic html element
- * like anchor and others. When Forwaring e-mail as Quoted EMFormat
- * generates header that contatains <b> tags (bold font).
- * We have to treat these elements separately to avoid
- * modifications of theirs inner texts */
- is_html_node =
- WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node) ||
- element_has_tag (WEBKIT_DOM_ELEMENT (node), "b") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (node), "i") ||
- element_has_tag (WEBKIT_DOM_ELEMENT (node), "u");
-
- if (is_html_node) {
- gboolean wrap_br;
-
- wrap_br =
- prev_sibling &&
- WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling) &&
- element_has_class (
- WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-wrap-br");
-
- if (!prev_sibling || wrap_br)
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling) && !wrap_br)
- insert_quote_symbols_before_node (
- document, prev_sibling, quote_level, TRUE);
-
- move_next = TRUE;
- goto next_node;
- }
-
- /* If element doesn't have children, we can quote it */
- if (is_citation_node (node)) {
- /* Citation with just text inside */
- quote_node (document, node, quote_level + 1);
- /* Set citation as quoted */
- element_add_class (
- WEBKIT_DOM_ELEMENT (node),
- "-x-evo-plaintext-quoted");
-
- move_next = TRUE;
- goto next_node;
- }
-
- if (!WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) {
- if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (prev_sibling)) {
- move_next = TRUE;
- goto next_node;
- }
- goto not_br;
- } else if (element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-first-br") ||
- element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-last-br")) {
- quote_br_node (node, quote_level);
- node = next_sibling;
- skip_node = TRUE;
- goto next_node;
- }
-
- if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
- WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (next_sibling) &&
- element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
- /* Situation when anchors are alone on line */
- text_content = webkit_dom_node_get_text_content (prev_sibling);
-
- if (g_str_has_suffix (text_content, "\n")) {
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
- remove_node (node);
- g_free (text_content);
- node = next_sibling;
- skip_node = TRUE;
- goto next_node;
- }
- g_free (text_content);
- }
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling)) {
- quote_br_node (prev_sibling, quote_level);
- node = next_sibling;
- skip_node = TRUE;
- goto next_node;
- }
-
- if (!prev_sibling && !next_sibling) {
- WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
- if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (parent) ||
- WEBKIT_DOM_IS_HTML_PRE_ELEMENT (parent) ||
- (WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (parent) &&
- !is_citation_node (parent))) {
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
-
- goto next_node;
- }
- }
-
- if (WEBKIT_DOM_IS_ELEMENT (prev_sibling) &&
- element_has_class (WEBKIT_DOM_ELEMENT (prev_sibling), "-x-evo-temp-text-wrapper")) {
- text_content = webkit_dom_node_get_text_content (prev_sibling);
- if (text_content && !*text_content) {
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
-
- g_free (text_content);
- goto next_node;
-
- }
-
- g_free (text_content);
- }
-
- if (is_citation_node (prev_sibling)) {
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
- goto next_node;
- }
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node) &&
- !next_sibling &&
- element_is_selection_marker (WEBKIT_DOM_ELEMENT (prev_sibling))) {
- insert_quote_symbols_before_node (
- document, node, quote_level, FALSE);
- goto next_node;
- }
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node)) {
- move_next = TRUE;
- goto next_node;
- }
-
- not_br:
- text_content = webkit_dom_node_get_text_content (node);
- if (text_content && !*text_content) {
- g_free (text_content);
- move_next = TRUE;
- goto next_node;
- }
- g_free (text_content);
-
- quote_node (document, node, quote_level);
-
- move_next = TRUE;
- goto next_node;
-
- with_children:
- if (is_citation_node (node)) {
- /* Go deeper and increase level */
- quote_plain_text_recursive (
- document, node, start_node, quote_level + 1);
- /* set citation as quoted */
- element_add_class (
- WEBKIT_DOM_ELEMENT (node),
- "-x-evo-plaintext-quoted");
- move_next = TRUE;
- } else {
- quote_plain_text_recursive (
- document, node, start_node, quote_level);
- move_next = TRUE;
- }
- next_node:
- if (next) {
- suppress_next = FALSE;
- next = FALSE;
- }
-
- if (suppress_next)
- next = TRUE;
-
- if (!skip_node) {
- /* Move to next node */
- if (!move_next && webkit_dom_node_has_child_nodes (node)) {
- node = webkit_dom_node_get_first_child (node);
- } else if (webkit_dom_node_get_next_sibling (node)) {
- node = webkit_dom_node_get_next_sibling (node);
- } else {
- return;
- }
- }
- }
-}
-
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text_element (EHTMLEditorView *view,
- WebKitDOMElement *element)
-{
- WebKitDOMDocument *document;
- WebKitDOMNode *element_clone;
- WebKitDOMNodeList *list;
- gint ii, length, level;
-
- document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-
- element_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (element), TRUE);
- level = get_citation_level (WEBKIT_DOM_NODE (element), TRUE);
-
- /* Remove old quote characters if the exists */
- list = webkit_dom_element_query_selector_all (
- WEBKIT_DOM_ELEMENT (element_clone), "span.-x-evo-quoted", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++)
- remove_node (webkit_dom_node_list_item (list, ii));
-
- webkit_dom_node_normalize (element_clone);
- quote_plain_text_recursive (
- document, element_clone, element_clone, level);
-
- /* Set citation as quoted */
- if (is_citation_node (element_clone))
- element_add_class (
- WEBKIT_DOM_ELEMENT (element_clone),
- "-x-evo-plaintext-quoted");
-
- /* Replace old element with one, that is quoted */
- webkit_dom_node_replace_child (
- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
- element_clone,
- WEBKIT_DOM_NODE (element),
- NULL);
-
- g_object_unref (list);
- return WEBKIT_DOM_ELEMENT (element_clone);
-}
-
-/**
- * e_html_editor_view_quote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Quote text inside citation blockquotes in plain text mode.
- *
- * As this function is cloning and replacing all citation blockquotes keep on
- * mind that any pointers to nodes inside these blockquotes will be invalidated.
- */
-WebKitDOMElement *
-e_html_editor_view_quote_plain_text (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
- WebKitDOMHTMLElement *body;
- WebKitDOMNode *body_clone;
- WebKitDOMNamedNodeMap *attributes;
- WebKitDOMNodeList *list;
- WebKitDOMElement *element;
- gint ii, length;
- gulong attributes_length;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- /* Check if the document is already quoted */
- element = webkit_dom_document_query_selector (
- document, ".-x-evo-plaintext-quoted", NULL);
- if (element)
- return NULL;
-
- body = webkit_dom_document_get_body (document);
- body_clone = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
- /* Clean unwanted spaces before and after blockquotes */
- list = webkit_dom_element_query_selector_all (
- WEBKIT_DOM_ELEMENT (body_clone), "blockquote[type|=cite]", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *blockquote = webkit_dom_node_list_item (list, ii);
- WebKitDOMNode *prev_sibling = webkit_dom_node_get_previous_sibling (blockquote);
- WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (blockquote);
-
- if (prev_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (prev_sibling))
- remove_node (prev_sibling);
-
- if (next_sibling && WEBKIT_DOM_IS_HTMLBR_ELEMENT (next_sibling))
- remove_node (next_sibling);
-
- if (webkit_dom_node_has_child_nodes (blockquote)) {
- WebKitDOMNode *child = webkit_dom_node_get_first_child (blockquote);
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
- remove_node (child);
- }
- }
- g_object_unref (list);
-
- webkit_dom_node_normalize (body_clone);
- quote_plain_text_recursive (document, body_clone, body_clone, 0);
-
- /* Copy attributes */
- attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
- attributes_length = webkit_dom_named_node_map_get_length (attributes);
- for (ii = 0; ii < attributes_length; ii++) {
- gchar *name, *value;
- WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
- name = webkit_dom_node_get_local_name (node);
- value = webkit_dom_node_get_node_value (node);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body_clone), name, value, NULL);
-
- g_free (name);
- g_free (value);
- }
- g_object_unref (attributes);
-
- /* Replace old BODY with one, that is quoted */
- webkit_dom_node_replace_child (
- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
- body_clone,
- WEBKIT_DOM_NODE (body),
- NULL);
-
- return WEBKIT_DOM_ELEMENT (body_clone);
-}
-
-/**
- * e_html_editor_view_dequote_plain_text:
- * @view: an #EHTMLEditorView
- *
- * Dequote already quoted plain text in editor.
- * Editor have to be quoted with e_html_editor_view_quote_plain_text otherwise
- * it's not working.
- */
-void
-e_html_editor_view_dequote_plain_text (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
- WebKitDOMNodeList *paragraphs;
- gint length, ii;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- paragraphs = webkit_dom_document_query_selector_all (
- document, "blockquote.-x-evo-plaintext-quoted", NULL);
- length = webkit_dom_node_list_get_length (paragraphs);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMElement *element;
-
- element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (paragraphs, ii));
-
- if (is_citation_node (WEBKIT_DOM_NODE (element))) {
- element_remove_class (element, "-x-evo-plaintext-quoted");
- remove_quoting_from_element (element);
- }
- }
- g_object_unref (paragraphs);
-}
-
-static gboolean
-create_anchor_for_link (const GMatchInfo *info,
- GString *res,
- gpointer data)
-{
- gint offset = 0;
- gchar *match;
- gboolean address_surrounded;
-
- match = g_match_info_fetch (info, 0);
-
- address_surrounded =
- strstr (match, "@") &&
- g_str_has_prefix (match, "<") &&
- g_str_has_suffix (match, ">");
-
- if (address_surrounded)
- offset += 4;
-
- if (g_str_has_prefix (match, " "))
- offset += 6;
-
- if (address_surrounded)
- g_string_append (res, "<");
-
- g_string_append (res, "<a href=\"");
- if (strstr (match, "@")) {
- g_string_append (res, "mailto:");
- g_string_append (res, match + offset);
- if (address_surrounded)
- g_string_truncate (res, res->len - 4);
-
- g_string_append (res, "\">");
- g_string_append (res, match + offset);
- if (address_surrounded)
- g_string_truncate (res, res->len - 4);
- } else {
- g_string_append (res, match + offset);
- g_string_append (res, "\">");
- g_string_append (res, match + offset);
- }
- g_string_append (res, "</a>");
-
- if (address_surrounded)
- g_string_append (res, ">");
-
- g_free (match);
-
- return FALSE;
-}
-
-static gboolean
-replace_to_nbsp (const GMatchInfo *info,
- GString *res,
- gboolean use_nbsp)
-{
- gchar *match;
- const gchar *string, *previous_tab;
- gint ii, length = 0, start = 0;
-
- match = g_match_info_fetch (info, 0);
- g_match_info_fetch_pos (info, 0, &start, NULL);
- string = g_match_info_get_string (info);
-
- if (start > 0) {
- previous_tab = g_strrstr_len (string, start, "\x9");
- if (previous_tab && *previous_tab) {
- const char *act_tab = NULL;
- act_tab = strstr (previous_tab + 1, "\x9");
-
- if (act_tab && *act_tab) {
- length = act_tab - previous_tab - 1;
- length = TAB_LENGTH - length;
- }
- }
- }
-
- if (length == 0) {
- if (strstr (match, "\x9")) {
- gint tab_count = strlen (match);
- length = TAB_LENGTH - (start % TAB_LENGTH);
- length += (tab_count - 1) * TAB_LENGTH;
- } else
- length = strlen (match);
- }
-
- for (ii = 0; ii < length; ii++)
- g_string_append (res, " ");
-
- g_free (match);
-
- return FALSE;
-}
-
-static gboolean
-surround_links_with_anchor (const gchar *text)
-{
- return (strstr (text, "http") || strstr (text, "ftp") ||
- strstr (text, "www") || strstr (text, "@"));
-}
-
-static void
-append_new_paragraph (WebKitDOMElement *parent,
- WebKitDOMElement **paragraph)
-{
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (parent),
- WEBKIT_DOM_NODE (*paragraph),
- NULL);
-
- *paragraph = NULL;
-}
-
-static WebKitDOMElement *
-create_and_append_new_paragraph (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document,
- WebKitDOMElement *parent,
- const gchar *content)
-{
- WebKitDOMElement *paragraph;
-
- paragraph = e_html_editor_selection_get_paragraph_element (
- selection, document, -1, 0);
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (paragraph),
- content,
- NULL);
-
- append_new_paragraph (parent, ¶graph);
-
- return paragraph;
-}
-
-static void
-append_citation_mark (WebKitDOMDocument *document,
- WebKitDOMElement *parent,
- const gchar *citation_mark_text)
-{
- WebKitDOMText *text;
-
- text = webkit_dom_document_create_text_node (document, citation_mark_text);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (parent),
- WEBKIT_DOM_NODE (text),
- NULL);
-}
-
-static glong
-get_decoded_line_length (WebKitDOMDocument *document,
- const gchar *line_text)
-{
- gchar *decoded_text;
- glong length = 0;
- WebKitDOMElement *decode;
-
- decode = webkit_dom_document_create_element (document, "DIV", NULL);
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (decode), line_text, NULL);
-
- decoded_text = webkit_dom_html_element_get_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (decode));
- length = g_utf8_strlen (decoded_text, -1);
-
- g_free (decoded_text);
- g_object_unref (decode);
-
- return length;
-}
-
-static gboolean
-check_if_end_paragraph (const gchar *input,
- glong length)
-{
- const gchar *next_space;
-
- next_space = strstr (input, " ");
- if (next_space) {
- const gchar *next_br;
- glong length_next_word =
- next_space - input - 4;
-
- if (g_str_has_prefix (input + 4, "<br>"))
- length_next_word = 0;
-
- if (length_next_word > 0)
- next_br = strstr (input + 4, "<br>");
-
- if (length_next_word > 0 && next_br < next_space)
- length_next_word = 0;
-
- if (length_next_word + length < 72)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* This parses the HTML code (that contains just text, and BR elements)
- * into paragraphs.
- * HTML code in that format we can get by taking innerText from some element,
- * setting it to another one and finally getting innerHTML from it */
-static void
-parse_html_into_paragraphs (EHTMLEditorView *view,
- WebKitDOMDocument *document,
- WebKitDOMElement *blockquote,
- const gchar *html)
-{
- EHTMLEditorSelection *selection;
- gboolean ignore_next_br = FALSE;
- gboolean first_element = TRUE;
- gboolean citation_was_first_element = FALSE;
- const gchar *prev_br, *next_br;
- gchar *inner_html;
- GRegex *regex_nbsp = NULL, *regex_links = NULL;
- GString *start, *end;
- WebKitDOMElement *paragraph = NULL;
-
- selection = e_html_editor_view_get_selection (view);
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (blockquote), "", NULL);
-
- prev_br = html;
- next_br = strstr (prev_br, "<br>");
-
- /* Replace single spaces on the beginning of line, 2+ spaces and
- * tabulators with non breaking spaces */
- regex_nbsp = g_regex_new ("^\\s{1}|\\s{2,}|\x9", 0, 0, NULL);
- regex_links = g_regex_new (URL_PATTERN, 0, 0, NULL);
-
- while (next_br) {
- gboolean local_ignore_next_br = ignore_next_br;
- gboolean prevent_block = TRUE;
- const gchar *citation = NULL, *citation_end = NULL;
- const gchar *rest = NULL, *with_br = NULL;
- gchar *to_insert = NULL;
-
- ignore_next_br = FALSE;
-
- to_insert = g_utf8_substring (
- prev_br, 0, g_utf8_pointer_to_offset (prev_br, next_br));
-
- with_br = strstr (to_insert, "<br>");
- citation = strstr (to_insert, "##CITATION_");
- if (citation) {
- gchar *citation_mark;
-
- if (strstr (citation, "END##")) {
- ignore_next_br = TRUE;
- if (paragraph)
- append_new_paragraph (blockquote, ¶graph);
- }
-
- citation_end = strstr (citation + 2, "##");
- if (citation_end)
- rest = citation_end + 2;
-
- if (first_element)
- citation_was_first_element = TRUE;
-
- if (paragraph)
- append_new_paragraph (blockquote, ¶graph);
-
- citation_mark = g_utf8_substring (
- citation, 0, g_utf8_pointer_to_offset (citation, rest));
-
- append_citation_mark (document, blockquote, citation_mark);
-
- g_free (citation_mark);
- } else
- rest = with_br ?
- to_insert + 4 + (with_br - to_insert) : to_insert;
-
- if (!rest)
- goto next;
-
- if (*rest) {
- gboolean empty = FALSE;
- gchar *truncated = g_strdup (rest);
- gchar *rest_to_insert;
-
- g_strchomp (truncated);
- empty = !*truncated && strlen (rest) > 0;
-
- if (strchr (" +- *=", *rest))
- prevent_block = FALSE;
-
- rest_to_insert = g_regex_replace_eval (
- regex_nbsp,
- empty ? rest : truncated,
- -1,
- 0,
- 0,
- (GRegexEvalCallback) replace_to_nbsp,
- NULL,
- NULL);
- g_free (truncated);
-
- if (surround_links_with_anchor (rest_to_insert)) {
- truncated = g_regex_replace_eval (
- regex_links,
- rest_to_insert,
- -1,
- 0,
- 0,
- create_anchor_for_link,
- NULL,
- NULL);
-
- g_free (rest_to_insert);
- rest_to_insert = truncated;
- }
-
- if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0) {
- paragraph = create_and_append_new_paragraph (
- selection, document, blockquote, "<br>");
- } else if (prevent_block) {
- gchar *html;
- gchar *new_content;
-
- if (!paragraph)
- paragraph = e_html_editor_selection_get_paragraph_element (
- selection, document, -1, 0);
-
- html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (paragraph));
-
- new_content = g_strconcat (
- html && *html ? html : "",
- html && *html ? " " : "",
- rest_to_insert ? rest_to_insert : "<br>",
- NULL),
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (paragraph),
- new_content,
- NULL);
-
- g_free (html);
- g_free (new_content);
- } else
- paragraph = create_and_append_new_paragraph (
- selection, document, blockquote, rest_to_insert);
-
- if (rest_to_insert && *rest_to_insert && prevent_block && paragraph) {
- glong length = 0;
-
- if (strstr (rest, "&"))
- length = get_decoded_line_length (document, rest);
- else
- length = g_utf8_strlen (rest, -1);
-
- /* End the block if there is line with less that 62 characters. */
- /* The shorter line can also mean that there is a long word on next
- * line (and the line was wrapped). So look at it and decide what to do. */
- if (length < 62 && check_if_end_paragraph (next_br, length))
- append_new_paragraph (blockquote, ¶graph);
-
- if (length > 72)
- append_new_paragraph (blockquote, ¶graph);
- }
-
- citation_was_first_element = FALSE;
-
- g_free (rest_to_insert);
- } else if (with_br) {
- if (!citation && (!local_ignore_next_br || citation_was_first_element)) {
- if (paragraph)
- append_new_paragraph (blockquote, ¶graph);
-
- paragraph = create_and_append_new_paragraph (
- selection, document, blockquote, "<br>");
-
- citation_was_first_element = FALSE;
- } else if (first_element && !citation_was_first_element) {
- paragraph = create_and_append_new_paragraph (
- selection,
- document,
- blockquote,
- "<br class=\"-x-evo-first-br\">");
- }
- }
- next:
- first_element = FALSE;
- prev_br = next_br;
- next_br = strstr (prev_br + 4, "<br>");
- g_free (to_insert);
- }
-
- if (paragraph)
- append_new_paragraph (blockquote, ¶graph);
-
- if (g_utf8_strlen (prev_br, -1) > 0) {
- gchar *rest_to_insert;
- gchar *truncated = g_strdup (
- g_str_has_prefix (prev_br, "<br>") ? prev_br + 4 : prev_br);
-
- /* On the end on the HTML there is always an extra BR element,
- * so skip it and if there was another BR element before it mark it. */
- if (truncated && !*truncated) {
- WebKitDOMNode *child;
-
- child = webkit_dom_node_get_last_child (
- WEBKIT_DOM_NODE (blockquote));
- if (child) {
- child = webkit_dom_node_get_first_child (child);
- if (child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)) {
- element_add_class (
- WEBKIT_DOM_ELEMENT (child),
- "-x-evo-last-br");
- }
- }
- g_free (truncated);
- goto end;
- }
-
- if (g_ascii_strncasecmp (truncated, "##CITATION_END##", 16) == 0) {
- append_citation_mark (document, blockquote, truncated);
- g_free (truncated);
- goto end;
- }
-
- g_strchomp (truncated);
-
- rest_to_insert = g_regex_replace_eval (
- regex_nbsp,
- truncated,
- -1,
- 0,
- 0,
- (GRegexEvalCallback) replace_to_nbsp,
- NULL,
- NULL);
- g_free (truncated);
-
- if (surround_links_with_anchor (rest_to_insert)) {
- truncated = g_regex_replace_eval (
- regex_links,
- rest_to_insert,
- -1,
- 0,
- 0,
- create_anchor_for_link,
- NULL,
- NULL);
-
- g_free (rest_to_insert);
- rest_to_insert = truncated;
- }
-
- if (g_strcmp0 (rest_to_insert, UNICODE_ZERO_WIDTH_SPACE) == 0)
- create_and_append_new_paragraph (
- selection, document, blockquote, "<br>");
- else
- create_and_append_new_paragraph (
- selection, document, blockquote, rest_to_insert);
-
- g_free (rest_to_insert);
- }
-
- end:
- /* Replace text markers with actual HTML blockquotes */
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (blockquote));
- start = e_str_replace_string (
- inner_html, "##CITATION_START##","<blockquote type=\"cite\">");
- end = e_str_replace_string (
- start->str, "##CITATION_END##", "</blockquote>");
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (blockquote), end->str, NULL);
-
- g_regex_unref (regex_nbsp);
- g_regex_unref (regex_links);
- g_free (inner_html);
- g_string_free (start, TRUE);
- g_string_free (end, TRUE);
-}
-
-static void
-mark_citation (WebKitDOMElement *citation)
-{
- gchar *inner_html, *surrounded;
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (citation));
-
- surrounded = g_strconcat (
- "<span>##CITATION_START##</span>", inner_html,
- "<span>##CITATION_END##</span>", NULL);
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (citation), surrounded, NULL);
-
- element_add_class (citation, "marked");
-
- g_free (inner_html);
- g_free (surrounded);
-}
-
-static gint
-create_text_markers_for_citations_in_document (WebKitDOMDocument *document)
-{
- gint count = 0;
- WebKitDOMElement *citation;
-
- citation = webkit_dom_document_query_selector (
- document, "blockquote[type=cite]:not(.marked)", NULL);
-
- while (citation) {
- mark_citation (citation);
- count ++;
-
- citation = webkit_dom_document_query_selector (
- document, "blockquote[type=cite]:not(.marked)", NULL);
- }
-
- return count;
-}
-
-static gint
-create_text_markers_for_citations_in_element (WebKitDOMElement *element)
-{
- gint count = 0;
- WebKitDOMElement *citation;
-
- citation = webkit_dom_element_query_selector (
- element, "blockquote[type=cite]:not(.marked)", NULL);
-
- while (citation) {
- mark_citation (citation);
- count ++;
-
- citation = webkit_dom_element_query_selector (
- element, "blockquote[type=cite]:not(.marked)", NULL);
- }
-
- return count;
-}
-
-static void
-quote_plain_text_elements_after_wrapping_in_document (WebKitDOMDocument *document)
-{
- gint length, ii;
- WebKitDOMNodeList *list;
-
- list = webkit_dom_document_query_selector_all (
- document, "blockquote[type=cite] > div.-x-evo-paragraph", NULL);
-
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- gint citation_level;
- WebKitDOMNode *child;
-
- child = webkit_dom_node_list_item (list, ii);
- citation_level = get_citation_level (child, TRUE);
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (child), citation_level);
- }
- g_object_unref (list);
-}
-
-static void
-html_editor_convert_view_content (EHTMLEditorView *view,
- const gchar *preferred_text)
-{
- EHTMLEditorSelection *selection = e_html_editor_view_get_selection (view);
- gboolean start_bottom, empty = FALSE;
- gchar *inner_html;
- gint ii, length;
- GSettings *settings;
- WebKitDOMDocument *document;
- WebKitDOMElement *paragraph, *content_wrapper, *top_signature;
- WebKitDOMElement *cite_body, *signature, *wrapper;
- WebKitDOMHTMLElement *body;
- WebKitDOMNodeList *list;
- WebKitDOMNode *node;
-
- settings = e_util_ref_settings ("org.gnome.evolution.mail");
- start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom");
- g_object_unref (settings);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = webkit_dom_document_get_body (document);
- /* Wrapper that will represent the new body. */
- wrapper = webkit_dom_document_create_element (document, "div", NULL);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
-
- cite_body = webkit_dom_document_query_selector (
- document, "span.-x-evo-cite-body", NULL);
-
- /* content_wrapper when the processed text will be placed. */
- content_wrapper = webkit_dom_document_create_element (
- document, cite_body ? "blockquote" : "div", NULL);
- if (cite_body) {
- webkit_dom_element_set_attribute (content_wrapper, "type", "cite", NULL);
- webkit_dom_element_set_attribute (content_wrapper, "id", "-x-evo-main-cite", NULL);
- }
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (wrapper), WEBKIT_DOM_NODE (content_wrapper), NULL);
-
- /* Remove all previously inserted paragraphs. */
- list = webkit_dom_document_query_selector_all (
- document, ".-x-evo-paragraph", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++)
- remove_node (webkit_dom_node_list_item (list, ii));
- g_object_unref (list);
-
- /* Insert the paragraph where the caret will be. */
- paragraph = prepare_paragraph (selection, document, TRUE);
- webkit_dom_element_set_id (paragraph, "-x-evo-input-start");
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- WEBKIT_DOM_NODE (paragraph),
- start_bottom ?
- webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (content_wrapper)) :
- WEBKIT_DOM_NODE (content_wrapper),
- NULL);
-
- /* Insert signature (if presented) to the right position. */
- top_signature = webkit_dom_document_query_selector (
- document, ".-x-evo-top-signature", NULL);
- signature = webkit_dom_document_query_selector (
- document, ".-x-evo-signature-content_wrapper", NULL);
- if (signature) {
- if (top_signature) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- WEBKIT_DOM_NODE (signature),
- start_bottom ?
- WEBKIT_DOM_NODE (content_wrapper) :
- webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (paragraph)),
- NULL);
- /* Insert NL after the signature */
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- WEBKIT_DOM_NODE (prepare_paragraph (
- selection, document, FALSE)),
- webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (signature)),
- NULL);
- } else {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- WEBKIT_DOM_NODE (signature),
- webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (
- start_bottom ? paragraph : content_wrapper)),
- NULL);
- }
- }
-
- /* Move credits to the body */
- list = webkit_dom_document_query_selector_all (
- document, "span.-x-evo-to-body[data-credits]", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node, *child;
-
- node = webkit_dom_node_list_item (list, ii);
- while ((child = webkit_dom_node_get_first_child (node))) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- child,
- WEBKIT_DOM_NODE (content_wrapper),
- NULL);
- }
-
- remove_node (node);
- }
- g_object_unref (list);
-
- /* Move headers to body */
- list = webkit_dom_document_query_selector_all (
- document, "span.-x-evo-to-body[data-headers]", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node, *child;
-
- node = webkit_dom_node_list_item (list, ii);
- while ((child = webkit_dom_node_get_first_child (node))) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (wrapper),
- child,
- WEBKIT_DOM_NODE (content_wrapper),
- NULL);
- }
-
- remove_node (node);
- }
- g_object_unref (list);
-
- repair_gmail_blockquotes (document);
- create_text_markers_for_citations_in_document (document);
-
- if (preferred_text && *preferred_text)
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (content_wrapper), preferred_text, NULL);
- else {
- gchar *inner_text;
-
- inner_text = webkit_dom_html_element_get_inner_text (body);
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (content_wrapper), inner_text, NULL);
-
- g_free (inner_text);
- }
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (content_wrapper));
-
- /* Replace the old body with the new one. */
- node = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), FALSE);
- webkit_dom_node_replace_child (
- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (body)),
- node,
- WEBKIT_DOM_NODE (body),
- NULL);
- body = WEBKIT_DOM_HTML_ELEMENT (node);
-
- /* Copy all to nodes to the new body. */
- while ((node = webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (wrapper)))) {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (body),
- WEBKIT_DOM_NODE (node),
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)),
- NULL);
- }
- remove_node (WEBKIT_DOM_NODE (wrapper));
-
- /* FIXME XXX */
- length = webkit_dom_element_get_child_element_count (WEBKIT_DOM_ELEMENT (body));
- if (length <= 1) {
- empty = TRUE;
- if (length == 1) {
- WebKitDOMNode *child;
-
- child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
- empty = child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child);
- }
- }
-
- if (preferred_text && *preferred_text)
- empty = FALSE;
-
- if (!empty)
- parse_html_into_paragraphs (view, document, content_wrapper, inner_html);
-
- if (!cite_body) {
- if (!empty) {
- WebKitDOMNode *child;
-
- while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (content_wrapper))))
{
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (content_wrapper)),
- child,
- WEBKIT_DOM_NODE (content_wrapper),
- NULL);
- }
- }
-
- remove_node (WEBKIT_DOM_NODE (content_wrapper));
- }
-
- if (view->priv->is_message_from_edit_as_new || view->priv->remove_initial_input_line) {
- WebKitDOMNode *child;
-
- remove_node (WEBKIT_DOM_NODE (paragraph));
- child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
- if (child)
- add_selection_markers_into_element_start (
- document, WEBKIT_DOM_ELEMENT (child), NULL, NULL);
- }
-
- paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-last-br", NULL);
- if (paragraph)
- webkit_dom_element_remove_attribute (paragraph, "class");
- paragraph = webkit_dom_document_query_selector (document, "br.-x-evo-first-br", NULL);
- if (paragraph)
- webkit_dom_element_remove_attribute (paragraph, "class");
-
- if (!e_html_editor_view_get_html_mode (view)) {
- e_html_editor_selection_wrap_paragraphs_in_document (
- selection, document);
-
- quote_plain_text_elements_after_wrapping_in_document (document);
- }
-
- e_html_editor_selection_restore (selection);
- e_html_editor_view_force_spell_check (view);
-
- /* Register on input event that is called when the content (body) is modified */
- webkit_dom_event_target_add_event_listener (
- WEBKIT_DOM_EVENT_TARGET (body),
- "input",
- G_CALLBACK (body_input_event_cb),
- FALSE,
- view);
-
- g_free (inner_html);
-}
-
-static void
-fix_structure_after_pasting_multiline_content (WebKitDOMNode *node)
-{
- WebKitDOMNode *first_child, *parent;
-
- /* When pasting content that does not contain just the
- * one line text WebKit inserts all the content after the
- * first line into one element. So we have to take it out
- * of this element and insert it after that element. */
- parent = webkit_dom_node_get_parent_node (node);
- if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent))
- return;
- first_child = webkit_dom_node_get_first_child (parent);
- while (first_child) {
- WebKitDOMNode *next_child =
- webkit_dom_node_get_next_sibling (first_child);
- if (webkit_dom_node_has_child_nodes (first_child))
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- first_child,
- parent,
- NULL);
- first_child = next_child;
- }
- remove_node (parent);
-}
-
-static void
-html_editor_view_insert_converted_html_into_selection (EHTMLEditorView *view,
- gboolean is_html,
- const gchar *html)
-{
- EHTMLEditorSelection *selection = e_html_editor_view_get_selection (view);
- gboolean has_selection;
- gchar *inner_html;
- gint citation_level;
- WebKitDOMDocument *document;
- WebKitDOMElement *element;
- WebKitDOMNode *node;
- WebKitDOMRange *range;
-
- remove_input_event_listener_from_body (view);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- element = webkit_dom_document_create_element (document, "div", NULL);
- if (is_html) {
- gchar *inner_text;
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
- inner_text = webkit_dom_html_element_get_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (element));
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (element), inner_text, NULL);
-
- g_free (inner_text);
- } else
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (element), html, NULL);
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element));
- parse_html_into_paragraphs (view, document, element, inner_html);
-
- g_free (inner_html);
-
- has_selection = !e_html_editor_selection_is_collapsed (selection);
-
- range = html_editor_view_get_dom_range (view);
- node = webkit_dom_range_get_end_container (range, NULL);
- citation_level = get_citation_level (node, FALSE);
- /* Pasting into the citation */
- if (citation_level > 0) {
- gint length;
- gint word_wrap_length = e_html_editor_selection_get_word_wrap_length (selection);
- WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMElement *br;
- WebKitDOMNode *first_paragraph, *last_paragraph;
- WebKitDOMNode *child, *parent;
-
- e_html_editor_selection_save (selection);
- selection_start_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-start-marker");
- selection_end_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-end-marker");
-
- first_paragraph = webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (element));
- last_paragraph = webkit_dom_node_get_last_child (
- WEBKIT_DOM_NODE (element));
-
- length = word_wrap_length - 2 * citation_level;
-
- /* Pasting text that was parsed just into one paragraph */
- if (webkit_dom_node_is_same_node (first_paragraph, last_paragraph)) {
- WebKitDOMNode *child, *parent;
-
- parent = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker));
-
- remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
- remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
- while ((child = webkit_dom_node_get_first_child (first_paragraph)))
- webkit_dom_node_insert_before (
- parent,
- child,
- WEBKIT_DOM_NODE (selection_start_marker),
- NULL);
-
- parent = WEBKIT_DOM_NODE (
- e_html_editor_selection_wrap_paragraph_length (
- selection, WEBKIT_DOM_ELEMENT (parent), length));
- webkit_dom_node_normalize (parent);
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (parent), citation_level);
-
- goto delete;
- }
-
- /* Pasting content parsed into the multiple paragraphs */
- parent = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker));
-
- remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
- remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
- /* Move the elements from the first paragraph before the selection start element */
- while ((child = webkit_dom_node_get_first_child (first_paragraph)))
- webkit_dom_node_insert_before (
- parent,
- child,
- WEBKIT_DOM_NODE (selection_start_marker),
- NULL);
-
- remove_node (first_paragraph);
-
- /* If the BR element is on the last position, remove it as we don't need it */
- child = webkit_dom_node_get_last_child (parent);
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child))
- remove_node (child);
-
- parent = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_end_marker)),
-
- child = webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (selection_end_marker));
- /* Move the elements that are in the same paragraph as the selection end
- * on the end of pasted text, but avoid BR on the end of paragraph */
- while (child) {
- WebKitDOMNode *next_child =
- webkit_dom_node_get_next_sibling (child);
- if (!(!next_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)))
- webkit_dom_node_append_child (last_paragraph, child, NULL);
- child = next_child;
- }
-
- /* Caret will be restored on the end of pasted text */
- webkit_dom_node_append_child (
- last_paragraph,
- e_html_editor_selection_get_caret_position_node (document),
- NULL);
-
- /* Insert the paragraph with the end of the pasted text after
- * the paragraph that contains the selection end */
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (parent),
- last_paragraph,
- webkit_dom_node_get_next_sibling (parent),
- NULL);
-
- /* Wrap, quote and move all paragraphs from pasted text into the body */
- while ((child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element)))) {
- child = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
- selection, WEBKIT_DOM_ELEMENT (child), length));
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (child), citation_level);
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (last_paragraph),
- child,
- last_paragraph,
- NULL);
- }
-
- webkit_dom_node_normalize (last_paragraph);
-
- last_paragraph = WEBKIT_DOM_NODE (
- e_html_editor_selection_wrap_paragraph_length (
- selection, WEBKIT_DOM_ELEMENT (last_paragraph), length));
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (last_paragraph), citation_level);
-
- remove_quoting_from_element (WEBKIT_DOM_ELEMENT (parent));
- remove_wrapping_from_element (WEBKIT_DOM_ELEMENT (parent));
-
- parent = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker));
- parent = WEBKIT_DOM_NODE (e_html_editor_selection_wrap_paragraph_length (
- selection, WEBKIT_DOM_ELEMENT (parent), length));
- quote_plain_text_element_after_wrapping (
- document, WEBKIT_DOM_ELEMENT (parent), citation_level);
-
- /* If the pasted text begun or ended with a new line we have to
- * quote these paragraphs as well */
- br = webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (last_paragraph), "br.-x-evo-last-br", NULL);
- if (br) {
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
- quote_plain_text_recursive (document, parent, parent, citation_level);
- webkit_dom_element_remove_attribute (br, "class");
- }
-
- br = webkit_dom_document_query_selector (
- document, "* > br.-x-evo-first-br", NULL);
- if (br) {
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (br));
- quote_plain_text_recursive (document, parent, parent, citation_level);
- webkit_dom_element_remove_attribute (br, "class");
- }
- delete:
- e_html_editor_selection_restore (selection);
- /* Remove the text that was meant to be replaced by the pasted text */
- if (has_selection)
- e_html_editor_view_exec_command (
- view, E_HTML_EDITOR_VIEW_COMMAND_DELETE, NULL);
-
- e_html_editor_selection_restore_caret_position (selection);
- goto out;
- }
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (element));
- e_html_editor_view_exec_command (
- view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, inner_html);
- g_free (inner_html);
-
- e_html_editor_selection_save (selection);
-
- element = webkit_dom_document_query_selector (
- document, "* > br.-x-evo-first-br", NULL);
- if (element) {
- WebKitDOMNode *next_sibling;
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (element));
-
- next_sibling = webkit_dom_node_get_next_sibling (parent);
- if (next_sibling)
- remove_node (WEBKIT_DOM_NODE (parent));
- else
- webkit_dom_element_remove_attribute (element, "class");
- }
-
- element = webkit_dom_document_query_selector (
- document, "* > br.-x-evo-last-br", NULL);
- if (element) {
- WebKitDOMNode *parent;
- WebKitDOMNode *child;
- WebKitDOMElement *selection_marker;
-
- parent = webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (element));
-
- node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent));
- if (node) {
- node = webkit_dom_node_get_first_child (node);
- if (node) {
- inner_html = webkit_dom_node_get_text_content (node);
- if (g_str_has_prefix (inner_html, UNICODE_NBSP))
- webkit_dom_character_data_replace_data (
- WEBKIT_DOM_CHARACTER_DATA (node), 0, 1, "", NULL);
- g_free (inner_html);
- }
- }
-
- selection_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-end-marker");
-
- if (has_selection) {
- /* Everything after the selection end marker have to be in separate
- * paragraph */
- child = webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (selection_marker));
- /* Move the elements that are in the same paragraph as the selection end
- * on the end of pasted text, but avoid BR on the end of paragraph */
- while (child) {
- WebKitDOMNode *next_child =
- webkit_dom_node_get_next_sibling (child);
- if (!(!next_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)))
- webkit_dom_node_append_child (parent, child, NULL);
- child = next_child;
- }
-
- remove_node (WEBKIT_DOM_NODE (element));
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (
- webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (selection_marker))),
- parent,
- webkit_dom_node_get_next_sibling (
- webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (selection_marker))),
- NULL);
- node = parent;
- } else {
- node = webkit_dom_node_get_next_sibling (parent);
- if (!node)
- fix_structure_after_pasting_multiline_content (parent);
- }
-
- if (node) {
- /* Restore caret on the end of pasted text */
- webkit_dom_node_insert_before (
- node,
- WEBKIT_DOM_NODE (selection_marker),
- webkit_dom_node_get_first_child (node),
- NULL);
-
- selection_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-start-marker");
- webkit_dom_node_insert_before (
- node,
- WEBKIT_DOM_NODE (selection_marker),
- webkit_dom_node_get_first_child (node),
- NULL);
- }
-
- if (element)
- webkit_dom_element_remove_attribute (element, "class");
-
- if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)) && !has_selection)
- remove_node (parent);
- } else {
- /* When pasting the content that was copied from the composer, WebKit
- * restores the selection wrongly, thus is saved wrongly and we have
- * to fix it */
- WebKitDOMElement *selection_start_marker, *selection_end_marker;
- WebKitDOMNode *paragraph, *parent;
-
- selection_start_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-start-marker");
- selection_end_marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-end-marker");
-
- paragraph = get_parent_block_node_from_child (
- WEBKIT_DOM_NODE (selection_start_marker));
- parent = webkit_dom_node_get_parent_node (paragraph);
- if (element_has_class (WEBKIT_DOM_ELEMENT (paragraph), "-x-evo-paragraph") &&
- element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-paragraph"))
- fix_structure_after_pasting_multiline_content (paragraph);
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (selection_start_marker)),
- WEBKIT_DOM_NODE (selection_end_marker),
- webkit_dom_node_get_next_sibling (
- WEBKIT_DOM_NODE (selection_start_marker)),
- NULL);
- }
-
- e_html_editor_selection_restore (selection);
- out:
- e_html_editor_view_force_spell_check (view);
- e_html_editor_selection_scroll_to_caret (selection);
-
- register_input_event_listener_on_body (view);
-}
-
-static void
initialize_web_extensions_cb (WebKitWebContext *web_context)
{
/* Set the web extensions dir before the process is launched */
@@ -5413,1466 +2313,6 @@ e_html_editor_view_get_html_mode (EHTMLEditorView *view)
return view->priv->html_mode;
}
-static gint
-get_indentation_level (WebKitDOMElement *element)
-{
- WebKitDOMElement *parent;
- gint level = 1;
-
- parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (element));
- /* Count level of indentation */
- while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
- if (element_has_class (parent, "-x-evo-indented"))
- level++;
-
- parent = webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (parent));
- }
-
- return level;
-}
-
-static void
-process_blockquote (WebKitDOMElement *blockquote)
-{
- WebKitDOMNodeList *list;
- int jj, length;
-
- /* First replace wrappers */
- list = webkit_dom_element_query_selector_all (
- blockquote, "span.-x-evo-temp-text-wrapper", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (jj = 0; jj < length; jj++) {
- WebKitDOMNode *quoted_node;
- gchar *text_content;
-
- quoted_node = webkit_dom_node_list_item (list, jj);
- text_content = webkit_dom_node_get_text_content (quoted_node);
- webkit_dom_html_element_set_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
-
- g_free (text_content);
- }
- g_object_unref (list);
-
- /* Afterwards replace quote nodes with symbols */
- list = webkit_dom_element_query_selector_all (
- blockquote, "span.-x-evo-quoted", NULL);
- length = webkit_dom_node_list_get_length (list);
- for (jj = 0; jj < length; jj++) {
- WebKitDOMNode *quoted_node;
- gchar *text_content;
-
- quoted_node = webkit_dom_node_list_item (list, jj);
- text_content = webkit_dom_node_get_text_content (quoted_node);
- webkit_dom_html_element_set_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (quoted_node), text_content, NULL);
-
- g_free (text_content);
- }
- g_object_unref (list);
-
- if (element_has_class (blockquote, "-x-evo-indented")) {
- WebKitDOMNode *child;
- gchar *spaces;
-
- spaces = g_strnfill (4 * get_indentation_level (blockquote), ' ');
-
- child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (blockquote));
- while (child) {
- /* If next sibling is indented blockqoute skip it,
- * it will be processed afterwards */
- if (WEBKIT_DOM_IS_ELEMENT (child) &&
- element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-indented"))
- child = webkit_dom_node_get_next_sibling (child);
-
- if (WEBKIT_DOM_IS_TEXT (child)) {
- gchar *text_content;
- gchar *indented_text;
-
- text_content = webkit_dom_text_get_whole_text (WEBKIT_DOM_TEXT (child));
- indented_text = g_strconcat (spaces, text_content, NULL);
-
- webkit_dom_text_replace_whole_text (
- WEBKIT_DOM_TEXT (child),
- indented_text,
- NULL);
-
- g_free (text_content);
- g_free (indented_text);
- }
-
- if (!child)
- break;
-
- /* Move to next node */
- if (webkit_dom_node_has_child_nodes (child))
- child = webkit_dom_node_get_first_child (child);
- else if (webkit_dom_node_get_next_sibling (child))
- child = webkit_dom_node_get_next_sibling (child);
- else {
- if (webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (blockquote), child))
- break;
-
- child = webkit_dom_node_get_parent_node (child);
- if (child)
- child = webkit_dom_node_get_next_sibling (child);
- }
- }
- g_free (spaces);
-
- webkit_dom_element_remove_attribute (blockquote, "style");
- }
-}
-
-/* Taken from GtkHTML */
-static gchar *
-get_alpha_value (gint value,
- gboolean lower)
-{
- GString *str;
- gchar *rv;
- gint add = lower ? 'a' : 'A';
-
- str = g_string_new (". ");
-
- do {
- g_string_prepend_c (str, ((value - 1) % 26) + add);
- value = (value - 1) / 26;
- } while (value);
-
- rv = str->str;
- g_string_free (str, FALSE);
-
- return rv;
-}
-
-/* Taken from GtkHTML */
-static gchar *
-get_roman_value (gint value,
- gboolean lower)
-{
- GString *str;
- const gchar *base = "IVXLCDM";
- gchar *rv;
- gint b, r, add = lower ? 'a' - 'A' : 0;
-
- if (value > 3999)
- return g_strdup ("?. ");
-
- str = g_string_new (". ");
-
- for (b = 0; value > 0 && b < 7 - 1; b += 2, value /= 10) {
- r = value % 10;
- if (r != 0) {
- if (r < 4) {
- for (; r; r--)
- g_string_prepend_c (str, base[b] + add);
- } else if (r == 4) {
- g_string_prepend_c (str, base[b + 1] + add);
- g_string_prepend_c (str, base[b] + add);
- } else if (r == 5) {
- g_string_prepend_c (str, base[b + 1] + add);
- } else if (r < 9) {
- for (; r > 5; r--)
- g_string_prepend_c (str, base[b] + add);
- g_string_prepend_c (str, base[b + 1] + add);
- } else if (r == 9) {
- g_string_prepend_c (str, base[b + 2] + add);
- g_string_prepend_c (str, base[b] + add);
- }
- }
- }
-
- rv = str->str;
- g_string_free (str, FALSE);
-
- return rv;
-}
-
-static void
-process_list_to_plain_text (EHTMLEditorView *view,
- WebKitDOMElement *element,
- gint level,
- GString *output)
-{
- EHTMLEditorSelectionBlockFormat format;
- EHTMLEditorSelectionAlignment alignment;
- gint counter = 1;
- gchar *indent_per_level = g_strnfill (SPACES_PER_LIST_LEVEL, ' ');
- WebKitDOMNode *item;
- gint word_wrap_length = e_html_editor_selection_get_word_wrap_length (
- e_html_editor_view_get_selection (view));
-
- format = e_html_editor_selection_get_list_format_from_node (
- WEBKIT_DOM_NODE (element));
-
- /* Process list items to plain text */
- item = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (element));
- while (item) {
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (item))
- g_string_append (output, "\n");
-
- if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
- gchar *space, *item_str = NULL;
- gint ii = 0;
- WebKitDOMElement *wrapped;
- GString *item_value = g_string_new ("");
-
- alignment = e_html_editor_selection_get_list_alignment_from_node (
- WEBKIT_DOM_NODE (item));
-
- wrapped = webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (item), ".-x-evo-wrap-br", NULL);
- /* Wrapped text */
- if (wrapped) {
- WebKitDOMNode *node = webkit_dom_node_get_first_child (item);
- GString *line = g_string_new ("");
- while (node) {
- if (WEBKIT_DOM_IS_TEXT (node)) {
- /* append text from line */
- gchar *text_content;
- text_content = webkit_dom_node_get_text_content (node);
- g_string_append (line, text_content);
- g_free (text_content);
- }
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (node) &&
- element_has_class (WEBKIT_DOM_ELEMENT (node), "-x-evo-wrap-br")) {
- g_string_append (line, "\n");
- /* put spaces before line characters -> wordwraplength -
indentation */
- for (ii = 0; ii < level; ii++)
- g_string_append (line, indent_per_level);
- g_string_append (item_value, line->str);
- g_string_erase (line, 0, -1);
- }
- node = webkit_dom_node_get_next_sibling (node);
- }
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT)
- g_string_append (item_value, line->str);
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
- gchar *fill = NULL;
- gint fill_length;
-
- fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
- fill_length -= ii * SPACES_PER_LIST_LEVEL;
- fill_length /= 2;
-
- if (fill_length < 0)
- fill_length = 0;
-
- fill = g_strnfill (fill_length, ' ');
-
- g_string_append (item_value, fill);
- g_string_append (item_value, line->str);
- g_free (fill);
- }
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
- gchar *fill = NULL;
- gint fill_length;
-
- fill_length = word_wrap_length - g_utf8_strlen (line->str, -1);
- fill_length -= ii * SPACES_PER_LIST_LEVEL;
-
- if (fill_length < 0)
- fill_length = 0;
-
- fill = g_strnfill (fill_length, ' ');
-
- g_string_append (item_value, fill);
- g_string_append (item_value, line->str);
- g_free (fill);
- }
- g_string_free (line, TRUE);
- /* that same here */
- } else {
- gchar *text_content =
- webkit_dom_node_get_text_content (item);
- g_string_append (item_value, text_content);
- g_free (text_content);
- }
-
- if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) {
- space = g_strnfill (SPACES_PER_LIST_LEVEL - 2, ' ');
- item_str = g_strdup_printf (
- "%s* %s", space, item_value->str);
- g_free (space);
- }
-
- if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
- gint length = 1, tmp = counter;
-
- while ((tmp = tmp / 10) > 1)
- length++;
-
- if (tmp == 1)
- length++;
-
- space = g_strnfill (SPACES_PER_LIST_LEVEL - 2 - length, ' ');
- item_str = g_strdup_printf (
- "%s%d. %s", space, counter, item_value->str);
- g_free (space);
- }
-
- if (format > E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) {
- gchar *value;
-
- if (format == E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA)
- value = get_alpha_value (counter, FALSE);
- else
- value = get_roman_value (counter, FALSE);
-
- /* Value already containes dot and space */
- space = g_strnfill (SPACES_PER_LIST_LEVEL - strlen (value), ' ');
- item_str = g_strdup_printf (
- "%s%s%s", space, value, item_value->str);
- g_free (space);
- g_free (value);
- }
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT) {
- for (ii = 0; ii < level - 1; ii++) {
- g_string_append (output, indent_per_level);
- }
- g_string_append (output, item_str);
- }
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT) {
- if (!wrapped) {
- gchar *fill = NULL;
- gint fill_length;
-
- fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
- fill_length -= ii * SPACES_PER_LIST_LEVEL;
-
- if (fill_length < 0)
- fill_length = 0;
-
- if (g_str_has_suffix (item_str, " "))
- fill_length++;
-
- fill = g_strnfill (fill_length, ' ');
-
- g_string_append (output, fill);
- g_free (fill);
- }
- if (g_str_has_suffix (item_str, " "))
- g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) -
1);
- else
- g_string_append (output, item_str);
- }
-
- if (alignment == E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER) {
- if (!wrapped) {
- gchar *fill = NULL;
- gint fill_length = 0;
-
- for (ii = 0; ii < level - 1; ii++)
- g_string_append (output, indent_per_level);
-
- fill_length = word_wrap_length - g_utf8_strlen (item_str, -1);
- fill_length -= ii * SPACES_PER_LIST_LEVEL;
- fill_length /= 2;
-
- if (fill_length < 0)
- fill_length = 0;
-
- if (g_str_has_suffix (item_str, " "))
- fill_length++;
-
- fill = g_strnfill (fill_length, ' ');
-
- g_string_append (output, fill);
- g_free (fill);
- }
- if (g_str_has_suffix (item_str, " "))
- g_string_append_len (output, item_str, g_utf8_strlen (item_str, -1) -
1);
- else
- g_string_append (output, item_str);
- }
-
- counter++;
- item = webkit_dom_node_get_next_sibling (item);
- if (item)
- g_string_append (output, "\n");
-
- g_free (item_str);
- g_string_free (item_value, TRUE);
- } else if (WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (item) ||
- WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (item)) {
- process_list_to_plain_text (
- view, WEBKIT_DOM_ELEMENT (item), level + 1, output);
- item = webkit_dom_node_get_next_sibling (item);
- } else {
- item = webkit_dom_node_get_next_sibling (item);
- }
- }
-
- if (webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (element)))
- g_string_append (output, "\n");
-
- g_free (indent_per_level);
-}
-
-static void
-remove_base_attributes (WebKitDOMElement *element)
-{
- webkit_dom_element_remove_attribute (element, "class");
- webkit_dom_element_remove_attribute (element, "id");
- webkit_dom_element_remove_attribute (element, "name");
-}
-
-static void
-remove_evolution_attributes (WebKitDOMElement *element)
-{
- webkit_dom_element_remove_attribute (element, "x-evo-smiley");
- webkit_dom_element_remove_attribute (element, "data-converted");
- webkit_dom_element_remove_attribute (element, "data-edit-as-new");
- webkit_dom_element_remove_attribute (element, "data-evo-draft");
- webkit_dom_element_remove_attribute (element, "data-inline");
- webkit_dom_element_remove_attribute (element, "data-uri");
- webkit_dom_element_remove_attribute (element, "data-message");
- webkit_dom_element_remove_attribute (element, "data-name");
- webkit_dom_element_remove_attribute (element, "data-new-message");
- webkit_dom_element_remove_attribute (element, "spellcheck");
-}
-/*
-static void
-remove_style_attributes (WebKitDOMElement *element)
-{
- webkit_dom_element_remove_attribute (element, "bgcolor");
- webkit_dom_element_remove_attribute (element, "background");
- webkit_dom_element_remove_attribute (element, "style");
-}
-*/
-static gboolean
-replace_to_whitespaces (const GMatchInfo *info,
- GString *res,
- gpointer data)
-{
- gint ii, length = 0;
- gint chars_count = GPOINTER_TO_INT (data);
-
- length = TAB_LENGTH - (chars_count % TAB_LENGTH);
-
- for (ii = 0; ii < length; ii++)
- g_string_append (res, " ");
-
- return FALSE;
-}
-
-static void
-process_elements (EHTMLEditorView *view,
- WebKitDOMNode *node,
- gboolean to_html,
- gboolean changing_mode,
- gboolean to_plain_text,
- GString *buffer)
-{
- WebKitDOMNodeList *nodes;
- gulong ii, length;
- gchar *content;
- gboolean skip_nl = FALSE;
-
- if (to_plain_text && !buffer)
- return;
-
- if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (node)) {
- if (changing_mode && to_plain_text) {
- WebKitDOMNamedNodeMap *attributes;
- gulong attributes_length;
-
- /* Copy attributes */
- g_string_append (buffer, "<html><head></head><body ");
- attributes = webkit_dom_element_get_attributes (
- WEBKIT_DOM_ELEMENT (node));
- attributes_length =
- webkit_dom_named_node_map_get_length (attributes);
-
- for (ii = 0; ii < attributes_length; ii++) {
- gchar *name, *value;
- WebKitDOMNode *node =
- webkit_dom_named_node_map_item (
- attributes, ii);
-
- name = webkit_dom_node_get_local_name (node);
- value = webkit_dom_node_get_node_value (node);
-
- g_string_append (buffer, name);
- g_string_append (buffer, "=\"");
- g_string_append (buffer, value);
- g_string_append (buffer, "\" ");
-
- g_free (name);
- g_free (value);
- }
- g_string_append (buffer, ">");
- g_object_unref (attributes);
- }
- if (to_html)
- remove_evolution_attributes (WEBKIT_DOM_ELEMENT (node));
- }
-
- nodes = webkit_dom_node_get_child_nodes (node);
- length = webkit_dom_node_list_get_length (nodes);
-
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *child;
- gboolean skip_node = FALSE;
-
- child = webkit_dom_node_list_item (nodes, ii);
-
- if (WEBKIT_DOM_IS_TEXT (child)) {
- gchar *content, *tmp;
- GRegex *regex;
- gint char_count = 0;
-
- content = webkit_dom_node_get_text_content (child);
- if (!changing_mode && to_plain_text) {
- /* Replace tabs with 8 whitespaces, otherwise they got
- * replaced by single whitespace */
- if (strstr (content, "\x9")) {
- if (buffer->str && *buffer->str) {
- gchar *start_of_line = g_strrstr_len (
- buffer->str, -1, "\n") + 1;
-
- if (start_of_line && *start_of_line)
- char_count = strlen (start_of_line);
- } else
- char_count = 0;
-
- regex = g_regex_new ("\x9", 0, 0, NULL);
- tmp = g_regex_replace_eval (
- regex,
- content,
- -1,
- 0,
- 0,
- (GRegexEvalCallback) replace_to_whitespaces,
- GINT_TO_POINTER (char_count),
- NULL);
-
- g_string_append (buffer, tmp);
- g_free (tmp);
- g_free (content);
- content = webkit_dom_node_get_text_content (child);
- g_regex_unref (regex);
- }
- }
-
- 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);
- webkit_dom_node_set_text_content (child, tmp, NULL);
- g_free (tmp);
- g_free (content);
- content = webkit_dom_node_get_text_content (child);
- g_regex_unref (regex);
- }
-
- if (to_plain_text && !changing_mode) {
- gchar *class;
- const gchar *css_align;
-
- if (strstr (content, UNICODE_NBSP)) {
- GString *nbsp_free;
-
- nbsp_free = e_str_replace_string (
- content, UNICODE_NBSP, " ");
-
- g_free (content);
- content = g_string_free (nbsp_free, FALSE);
- }
-
- 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;
- gint word_wrap_length =
- e_html_editor_selection_get_word_wrap_length (
- e_html_editor_view_get_selection (view));
-
- 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;
-
- length++;
- align = g_strnfill (length, ' ');
-
- tmp = g_strndup (content, g_utf8_strlen (content, -1)
-1);
-
- content_with_align = g_strconcat (
- align, tmp, NULL);
- g_free (tmp);
- } else {
- align = g_strnfill (length, ' ');
-
- content_with_align = g_strconcat (
- align, content, NULL);
- }
-
- g_free (content);
- g_free (align);
- content = content_with_align;
- }
- }
-
- g_free (class);
- }
-
- if (to_plain_text || changing_mode)
- g_string_append (buffer, content);
-
- g_free (content);
-
- goto next;
- }
-
- if (WEBKIT_DOM_IS_COMMENT (child) || !WEBKIT_DOM_IS_ELEMENT (child))
- goto next;
-
- /* Leave caret position untouched */
- if (element_has_id (WEBKIT_DOM_ELEMENT (child), "-x-evo-caret-position")) {
- 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)
- remove_node (child);
-
- skip_node = TRUE;
- goto next;
- }
-
- if (element_has_class (WEBKIT_DOM_ELEMENT (child), "Apple-tab-span")) {
- if (!changing_mode && to_plain_text) {
- gchar *content, *tmp;
- GRegex *regex;
- gint char_count = 0;
-
- content = webkit_dom_node_get_text_content (child);
- /* Replace tabs with 8 whitespaces, otherwise they got
- * replaced by single whitespace */
- if (strstr (content, "\x9")) {
- if (buffer->str && *buffer->str) {
- gchar *start_of_line = g_strrstr_len (
- buffer->str, -1, "\n") + 1;
-
- if (start_of_line && *start_of_line)
- char_count = strlen (start_of_line);
- } else
- char_count = 0;
-
- regex = g_regex_new ("\x9", 0, 0, NULL);
- tmp = g_regex_replace_eval (
- regex,
- content,
- -1,
- 0,
- 0,
- (GRegexEvalCallback) replace_to_whitespaces,
- GINT_TO_POINTER (char_count),
- NULL);
-
- g_string_append (buffer, tmp);
- g_free (tmp);
- g_regex_unref (regex);
- } else if (content && *content) {
- /* Some it happens that some text is written inside
- * the tab span element, so save it. */
- g_string_append (buffer, content);
- }
- g_free (content);
- }
- if (to_html) {
- element_remove_class (
- WEBKIT_DOM_ELEMENT (child),
- "Applet-tab-span");
- }
-
- skip_node = TRUE;
- goto next;
- }
-
- /* Leave blockquotes as they are */
- if (WEBKIT_DOM_IS_HTML_QUOTE_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);
- skip_node = TRUE;
- goto next;
- } else {
- if (!changing_mode && to_plain_text) {
- if (get_citation_level (child, FALSE) == 0) {
- gchar *value = webkit_dom_element_get_attribute (
- WEBKIT_DOM_ELEMENT (child), "type");
-
- if (value && g_strcmp0 (value, "cite") == 0)
- g_string_append (buffer, "\n");
- g_free (value);
- }
- }
- process_blockquote (WEBKIT_DOM_ELEMENT (child));
- if (to_html)
- remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
- }
- }
-
- 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) {
- if (changing_mode) {
- content = webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (child));
- g_string_append (buffer, content);
- g_free (content);
- } else {
- process_list_to_plain_text (
- view, WEBKIT_DOM_ELEMENT (child), 1, buffer);
- }
- skip_node = TRUE;
- goto next;
- }
- }
-
- if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-resizable-wrapper") &&
- !element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
- WebKitDOMNode *image =
- webkit_dom_node_get_first_child (child);
-
- if (to_html && WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (image)) {
- remove_evolution_attributes (
- WEBKIT_DOM_ELEMENT (image));
-
- webkit_dom_node_replace_child (
- node, image, child, NULL);
- }
-
- skip_node = TRUE;
- goto next;
- }
-
- /* Leave paragraphs as they are */
- if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-paragraph")) {
- 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;
- goto next;
- }
- if (to_html) {
- remove_base_attributes (WEBKIT_DOM_ELEMENT (child));
- remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
- }
- if (!changing_mode && to_plain_text)
- if (!webkit_dom_node_has_child_nodes (child))
- g_string_append (buffer, "\n");
- }
-
- /* Signature */
- if (WEBKIT_DOM_IS_HTML_DIV_ELEMENT (child) &&
- element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-signature-wrapper")) {
- WebKitDOMNode *first_child;
-
- first_child = webkit_dom_node_get_first_child (child);
-
- if (to_html) {
- remove_base_attributes (
- WEBKIT_DOM_ELEMENT (first_child));
- remove_evolution_attributes (
- WEBKIT_DOM_ELEMENT (first_child));
- }
- if (to_plain_text && !changing_mode) {
- g_string_append (buffer, "\n");
- content = webkit_dom_html_element_get_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (first_child));
- g_string_append (buffer, content);
- g_free (content);
- skip_nl = TRUE;
- }
- if (to_plain_text && changing_mode) {
- content = webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (child));
- g_string_append (buffer, content);
- g_free (content);
- skip_node = TRUE;
- }
- skip_node = TRUE;
- goto next;
- }
-
- /* Replace smileys with their text representation */
- if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-smiley-wrapper")) {
- 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));
- g_string_append (buffer, content);
- g_free (content);
- skip_node = TRUE;
- goto next;
- }
- if (to_html) {
- WebKitDOMElement *img;
-
- img = WEBKIT_DOM_ELEMENT (
- webkit_dom_node_get_first_child (child)),
-
- remove_evolution_attributes (img);
- remove_base_attributes (img);
-
- webkit_dom_node_insert_before (
- webkit_dom_node_get_parent_node (child),
- WEBKIT_DOM_NODE (img),
- child,
- NULL);
- remove_node (child);
- skip_node = TRUE;
- goto next;
- }
- }
-
- /* Leave PRE elements untouched */
- if (WEBKIT_DOM_IS_HTML_PRE_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);
- skip_node = TRUE;
- }
- if (to_html)
- remove_evolution_attributes (WEBKIT_DOM_ELEMENT (child));
- }
-
- if (WEBKIT_DOM_IS_HTMLBR_ELEMENT (child)) {
- if (to_plain_text) {
- if (element_has_class (WEBKIT_DOM_ELEMENT (child), "-x-evo-wrap-br")) {
- g_string_append (buffer, changing_mode ? "<br>" : "\n");
- goto next;
- }
-
- /* Insert new line when we hit the BR element that is
- * not the last element in the block */
- if (!webkit_dom_node_is_same_node (
- child, webkit_dom_node_get_last_child (node))) {
- g_string_append (buffer, changing_mode ? "<br>" : "\n");
- } else {
- /* In citations in the empty lines the BR element
- * is on the end and we have to put NL there */
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (child);
- if (webkit_dom_node_get_next_sibling (parent)) {
- parent = webkit_dom_node_get_parent_node (parent);
-
- if (is_citation_node (parent))
- g_string_append (buffer, changing_mode ? "<br>" :
"\n");
- }
- }
- }
- }
-
- if (WEBKIT_DOM_IS_HTML_ANCHOR_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);
- skip_node = TRUE;
- }
- if (!changing_mode && to_plain_text) {
- content = webkit_dom_html_element_get_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (child));
- g_string_append (buffer, content);
- g_free (content);
- skip_node = TRUE;
- }
- }
- next:
- if (webkit_dom_node_has_child_nodes (child) && !skip_node)
- process_elements (
- view, child, to_html, changing_mode, to_plain_text, buffer);
- }
-
- if (to_plain_text && (
- WEBKIT_DOM_IS_HTML_DIV_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_PRE_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_QUOTE_ELEMENT (node))) {
-
- gboolean add_br = TRUE;
- WebKitDOMNode *next_sibling = webkit_dom_node_get_next_sibling (node);
- WebKitDOMNode *last_child = webkit_dom_node_get_last_child (node);
-
- if (last_child && WEBKIT_DOM_IS_HTMLBR_ELEMENT (last_child))
- if (webkit_dom_node_get_previous_sibling (last_child))
- add_br = FALSE;
-
- /* If we don't have next sibling (last element in body) or next element is
- * signature we are not adding the BR element */
- if (!next_sibling)
- add_br = FALSE;
- else if (next_sibling && WEBKIT_DOM_IS_HTML_DIV_ELEMENT (next_sibling)) {
- if (webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (next_sibling),
- "span.-x-evo-signature", NULL)) {
-
- add_br = FALSE;
- }
- }
-
- if (add_br && !skip_nl)
- g_string_append (buffer, changing_mode ? "<br>" : "\n");
- }
-
- g_object_unref (nodes);
-}
-
-static void
-remove_wrapping_from_view (EHTMLEditorView *view)
-{
- gint length;
- gint ii;
- WebKitDOMDocument *document;
- WebKitDOMNodeList *list;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- list = webkit_dom_document_query_selector_all (document, "br.-x-evo-wrap-br", NULL);
-
- length = webkit_dom_node_list_get_length (list);
- for (ii = 0; ii < length; ii++)
- remove_node (webkit_dom_node_list_item (list, ii));
-
- g_object_unref (list);
-}
-
-static void
-remove_image_attributes_from_element (WebKitDOMElement *element)
-{
- webkit_dom_element_remove_attribute (element, "background");
- webkit_dom_element_remove_attribute (element, "data-uri");
- webkit_dom_element_remove_attribute (element, "data-inline");
- webkit_dom_element_remove_attribute (element, "data-name");
-}
-
-static void
-remove_background_images_in_document (WebKitDOMDocument *document)
-{
- gint length, ii;
- WebKitDOMNodeList *elements;
-
- elements = webkit_dom_document_query_selector_all (
- document, "[background][data-inline]", NULL);
-
- length = webkit_dom_node_list_get_length (elements);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMElement *element = WEBKIT_DOM_ELEMENT (
- webkit_dom_node_list_item (elements, ii));
-
- remove_image_attributes_from_element (element);
- }
-
- g_object_unref (elements);
-}
-
-static void
-remove_images_in_element (EHTMLEditorView *view,
- WebKitDOMElement *element)
-{
- gint length, ii;
- WebKitDOMNodeList *images;
-
- images = webkit_dom_element_query_selector_all (
- element, "img:not(.-x-evo-smiley-img)", NULL);
-
- length = webkit_dom_node_list_get_length (images);
- for (ii = 0; ii < length; ii++)
- remove_node (webkit_dom_node_list_item (images, ii));
-
- g_object_unref (images);
-}
-
-static void
-remove_images (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- remove_images_in_element (
- view, WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)));
-}
-
-static void
-toggle_smileys (EHTMLEditorView *view)
-{
- gboolean html_mode;
- gint length;
- gint ii;
- WebKitDOMDocument *document;
- WebKitDOMNodeList *smileys;
-
- html_mode = e_html_editor_view_get_html_mode (view);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- smileys = webkit_dom_document_query_selector_all (
- document, "img.-x-evo-smiley-img", NULL);
-
- length = webkit_dom_node_list_get_length (smileys);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *img = webkit_dom_node_list_item (smileys, ii);
- WebKitDOMNode *text = webkit_dom_node_get_next_sibling (img);
- WebKitDOMElement *parent = webkit_dom_node_get_parent_element (img);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (html_mode ? text : img),
- "style",
- "display: none",
- NULL);
-
- webkit_dom_element_remove_attribute (
- WEBKIT_DOM_ELEMENT (html_mode ? img : text), "style");
-
- if (html_mode)
- element_add_class (parent, "-x-evo-resizable-wrapper");
- else
- element_remove_class (parent, "-x-evo-resizable-wrapper");
- }
-
- g_object_unref (smileys);
-}
-
-static void
-toggle_paragraphs_style_in_element (EHTMLEditorView *view,
- WebKitDOMElement *element,
- gboolean html_mode)
-{
- EHTMLEditorSelection *selection;
- gint ii, length;
- WebKitDOMNodeList *paragraphs;
-
- selection = e_html_editor_view_get_selection (view);
-
- paragraphs = webkit_dom_element_query_selector_all (
- element, ".-x-evo-paragraph", NULL);
-
- length = webkit_dom_node_list_get_length (paragraphs);
-
- for (ii = 0; ii < length; ii++) {
- gchar *style;
- const gchar *css_align;
- WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
-
- if (html_mode) {
- style = webkit_dom_element_get_attribute (
- WEBKIT_DOM_ELEMENT (node), "style");
-
- if ((css_align = strstr (style, "text-align: "))) {
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (node),
- "style",
- g_str_has_prefix (css_align + 12, "center") ?
- "text-align: center" :
- "text-align: right",
- NULL);
- } else {
- /* In HTML mode the paragraphs don't have width limit */
- webkit_dom_element_remove_attribute (
- WEBKIT_DOM_ELEMENT (node), "style");
- }
- g_free (style);
- } else {
- WebKitDOMNode *parent;
-
- parent = webkit_dom_node_get_parent_node (node);
- /* If the paragraph is inside indented paragraph don't set
- * the style as it will be inherited */
- if (!element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-indented")) {
- const gchar *style_to_add = "";
- style = webkit_dom_element_get_attribute (
- WEBKIT_DOM_ELEMENT (node), "style");
-
- if ((css_align = strstr (style, "text-align: "))) {
- style_to_add = g_str_has_prefix (
- css_align + 12, "center") ?
- "text-align: center;" :
- "text-align: right;";
- }
-
- /* In plain text mode the paragraphs have width limit */
- e_html_editor_selection_set_paragraph_style (
- selection, WEBKIT_DOM_ELEMENT (node),
- -1, 0, style_to_add);
-
- g_free (style);
- }
- }
- }
- g_object_unref (paragraphs);
-}
-
-static void
-toggle_paragraphs_style (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
-
- toggle_paragraphs_style_in_element (
- view,
- WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document)),
- view->priv->html_mode);
-}
-
-static gchar *
-process_content_for_saving_as_draft (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
- WebKitDOMHTMLElement *body;
- WebKitDOMElement *document_element;
- gchar *content;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = webkit_dom_document_get_body (document);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-evo-draft", "", NULL);
-
- document_element = webkit_dom_document_get_document_element (document);
- content = webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (document_element));
-
- webkit_dom_element_remove_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-evo-draft");
-
- return content;
-}
-
-static gchar *
-process_content_for_mode_change (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
- WebKitDOMNode *body;
- GString *plain_text;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
-
- plain_text = g_string_sized_new (1024);
-
- process_elements (view, body, FALSE, TRUE, TRUE, plain_text);
-
- g_string_append (plain_text, "</body></html>");
-
- return g_string_free (plain_text, FALSE);
-}
-
-static void
-convert_element_from_html_to_plain_text (EHTMLEditorView *view,
- WebKitDOMElement *element,
- gboolean *wrap,
- gboolean *quote)
-{
- EHTMLEditorSelection *selection;
- gint blockquotes_count;
- gchar *inner_text, *inner_html;
- gboolean restore = TRUE;
- WebKitDOMDocument *document;
- WebKitDOMElement *top_signature, *signature, *blockquote, *main_blockquote;
- WebKitDOMNode *signature_clone, *from;
-
- selection = e_html_editor_view_get_selection (view);
-
- document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element));
-
- top_signature = webkit_dom_element_query_selector (
- element, ".-x-evo-top-signature", NULL);
- signature = webkit_dom_element_query_selector (
- element, "span.-x-evo-signature", NULL);
- main_blockquote = webkit_dom_element_query_selector (
- element, "#-x-evo-main-cite", NULL);
-
- blockquote = webkit_dom_document_create_element (
- document, "blockquote", NULL);
-
- if (main_blockquote) {
- WebKitDOMElement *input_start;
-
- webkit_dom_element_set_attribute (
- blockquote, "type", "cite", NULL);
-
- input_start = webkit_dom_element_query_selector (
- element, "#-x-evo-input-start", NULL);
-
- restore = input_start ? TRUE : FALSE;
-
- if (input_start)
- add_selection_markers_into_element_start (
- document, WEBKIT_DOM_ELEMENT (input_start), NULL, NULL);
- from = WEBKIT_DOM_NODE (main_blockquote);
- } else {
- if (signature) {
- WebKitDOMNode *parent = webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (signature));
- signature_clone = webkit_dom_node_clone_node (parent, TRUE);
- remove_node (parent);
- }
- from = WEBKIT_DOM_NODE (element);
- }
-
- blockquotes_count = create_text_markers_for_citations_in_element (
- WEBKIT_DOM_ELEMENT (from));
-
- inner_text = webkit_dom_html_element_get_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (from));
-
- webkit_dom_html_element_set_inner_text (
- WEBKIT_DOM_HTML_ELEMENT (blockquote), inner_text, NULL);
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (blockquote));
-
- parse_html_into_paragraphs (
- view, document,
- main_blockquote ? blockquote : WEBKIT_DOM_ELEMENT (element),
- inner_html);
-
- if (main_blockquote) {
- webkit_dom_node_replace_child (
- webkit_dom_node_get_parent_node (
- WEBKIT_DOM_NODE (main_blockquote)),
- WEBKIT_DOM_NODE (blockquote),
- WEBKIT_DOM_NODE (main_blockquote),
- NULL);
-
- remove_evolution_attributes (WEBKIT_DOM_ELEMENT (element));
- } else {
- WebKitDOMNode *first_child;
-
- if (signature) {
- if (!top_signature) {
- signature_clone = webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (element),
- signature_clone,
- NULL);
- } else {
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (element),
- signature_clone,
- webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (element)),
- NULL);
- }
- }
-
- first_child = webkit_dom_node_get_first_child (
- WEBKIT_DOM_NODE (element));
- if (first_child) {
- if (!webkit_dom_node_has_child_nodes (first_child)) {
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (first_child),
- "<br>",
- NULL);
- }
- add_selection_markers_into_element_start (
- document, WEBKIT_DOM_ELEMENT (first_child), NULL, NULL);
- }
- }
-
- *wrap = TRUE;
- *quote = main_blockquote || blockquotes_count > 0;
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (element), "data-converted", "", NULL);
-
- g_free (inner_text);
- g_free (inner_html);
-
- if (restore)
- e_html_editor_selection_restore (selection);
-}
-
-static gchar *
-process_content_for_plain_text (EHTMLEditorView *view)
-{
- EHTMLEditorSelection *selection;
- gboolean wrap = FALSE, quote = FALSE, clean = FALSE;
- gboolean converted, is_from_new_message;
- gint length, ii;
- GString *plain_text;
- WebKitDOMDocument *document;
- WebKitDOMNode *body, *source;
- WebKitDOMNodeList *paragraphs;
-
- plain_text = g_string_sized_new (1024);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = WEBKIT_DOM_NODE (webkit_dom_document_get_body (document));
- converted = webkit_dom_element_has_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-converted");
- is_from_new_message = webkit_dom_element_has_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-new-message");
- source = webkit_dom_node_clone_node (WEBKIT_DOM_NODE (body), TRUE);
-
- selection = e_html_editor_view_get_selection (view);
-
- /* If composer is in HTML mode we have to move the content to plain version */
- if (view->priv->html_mode) {
- if (converted || is_from_new_message) {
- toggle_paragraphs_style_in_element (
- view, WEBKIT_DOM_ELEMENT (source), FALSE);
- remove_images_in_element (
- view, WEBKIT_DOM_ELEMENT (source));
- remove_background_images_in_document (
- document);
- } else {
- gchar *inner_html;
- WebKitDOMElement *div;
-
- inner_html = webkit_dom_html_element_get_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (body));
-
- div = webkit_dom_document_create_element (
- document, "div", NULL);
-
- webkit_dom_html_element_set_inner_html (
- WEBKIT_DOM_HTML_ELEMENT (div), inner_html, NULL);
-
- webkit_dom_node_append_child (
- WEBKIT_DOM_NODE (body),
- WEBKIT_DOM_NODE (div),
- NULL);
-
- paragraphs = webkit_dom_element_query_selector_all (
- div, "#-x-evo-input-start", 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);
-
- webkit_dom_element_remove_attribute (
- WEBKIT_DOM_ELEMENT (paragraph), "id");
- }
- g_object_unref (paragraphs);
-
- convert_element_from_html_to_plain_text (
- view, div, &wrap, "e);
-
- g_object_unref (source);
-
- source = WEBKIT_DOM_NODE (div);
-
- clean = TRUE;
- }
- }
-
- paragraphs = webkit_dom_element_query_selector_all (
- WEBKIT_DOM_ELEMENT (source), ".-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);
-
- if (WEBKIT_DOM_IS_HTMLO_LIST_ELEMENT (paragraph) ||
- WEBKIT_DOM_IS_HTMLU_LIST_ELEMENT (paragraph)) {
- WebKitDOMNode *item = webkit_dom_node_get_first_child (paragraph);
-
- while (item) {
- WebKitDOMNode *next_item =
- webkit_dom_node_get_next_sibling (item);
-
- if (WEBKIT_DOM_IS_HTMLLI_ELEMENT (item)) {
- e_html_editor_selection_wrap_paragraph (
- selection, WEBKIT_DOM_ELEMENT (item));
- }
- item = next_item;
- }
- } else {
- e_html_editor_selection_wrap_paragraph (
- selection, WEBKIT_DOM_ELEMENT (paragraph));
- }
- }
- g_object_unref (paragraphs);
-
- paragraphs = webkit_dom_element_query_selector_all (
- WEBKIT_DOM_ELEMENT (source),
- "span[id^=\"-x-evo-selection-\"], span#-x-evo-caret-position",
- NULL);
-
- length = webkit_dom_node_list_get_length (paragraphs);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *node = webkit_dom_node_list_item (paragraphs, ii);
- WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node);
-
- remove_node (node);
- webkit_dom_node_normalize (parent);
- }
- g_object_unref (paragraphs);
-
- if (view->priv->html_mode || quote)
- quote_plain_text_recursive (document, source, source, 0);
-
- process_elements (view, source, FALSE, FALSE, TRUE, plain_text);
-
- if (clean)
- remove_node (source);
- else
- g_object_unref (source);
-
- /* Return text content between <body> and </body> */
- return g_string_free (plain_text, FALSE);
-}
-
-static gchar *
-process_content_for_html (EHTMLEditorView *view)
-{
- WebKitDOMDocument *document;
- WebKitDOMNode *body, *document_clone;
- gchar *html_content;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- document_clone = webkit_dom_node_clone_node (
- WEBKIT_DOM_NODE (webkit_dom_document_get_document_element (document)), TRUE);
- body = WEBKIT_DOM_NODE (webkit_dom_element_query_selector (
- WEBKIT_DOM_ELEMENT (document_clone), "body", NULL));
- process_elements (view, body, TRUE, FALSE, FALSE, NULL);
-
- html_content = webkit_dom_html_element_get_outer_html (
- WEBKIT_DOM_HTML_ELEMENT (document_clone));
-
- g_object_unref (document_clone);
-
- return html_content;
-}
-
static gboolean
show_lose_formatting_dialog (EHTMLEditorView *view)
{
@@ -6913,99 +2353,6 @@ show_lose_formatting_dialog (EHTMLEditorView *view)
}
static void
-clear_attributes (WebKitDOMDocument *document)
-{
- gint length, ii;
- WebKitDOMNamedNodeMap *attributes;
- WebKitDOMHTMLElement *body = webkit_dom_document_get_body (document);
- WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head (document);
- WebKitDOMElement *document_element =
- webkit_dom_document_get_document_element (document);
-
- /* Remove all attributes from HTML element */
- attributes = webkit_dom_element_get_attributes (document_element);
- length = webkit_dom_named_node_map_get_length (attributes);
- for (ii = length - 1; ii >= 0; ii--) {
- WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
- webkit_dom_element_remove_attribute_node (
- document_element, WEBKIT_DOM_ATTR (node), NULL);
- }
- g_object_unref (attributes);
-
- /* Remove everything from HEAD element */
- while (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)))
- remove_node (webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (head)));
-
- /* Remove non Evolution attributes from BODY element */
- attributes = webkit_dom_element_get_attributes (WEBKIT_DOM_ELEMENT (body));
- length = webkit_dom_named_node_map_get_length (attributes);
- for (ii = length - 1; ii >= 0; ii--) {
- gchar *name;
- WebKitDOMNode *node = webkit_dom_named_node_map_item (attributes, ii);
-
- name = webkit_dom_node_get_local_name (node);
-
- if (!g_str_has_prefix (name, "data-") ||
- g_str_has_prefix (name, "data-inline") ||
- g_str_has_prefix (name, "data-name")) {
- webkit_dom_element_remove_attribute_node (
- WEBKIT_DOM_ELEMENT (body),
- WEBKIT_DOM_ATTR (node),
- NULL);
- }
-
- g_free (name);
- }
- g_object_unref (attributes);
-}
-
-static void
-convert_when_changing_composer_mode (EHTMLEditorView *view)
-{
- EHTMLEditorSelection *selection;
- gboolean quote = FALSE, wrap = FALSE;
- WebKitDOMDocument *document;
- WebKitDOMHTMLElement *body;
-
- selection = e_html_editor_view_get_selection (view);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- body = webkit_dom_document_get_body (document);
-
- convert_element_from_html_to_plain_text (
- view, WEBKIT_DOM_ELEMENT (body), &wrap, "e);
-
- if (wrap)
- e_html_editor_selection_wrap_paragraphs_in_document (selection, document);
-
- if (quote) {
- e_html_editor_selection_save (selection);
- if (wrap)
- quote_plain_text_elements_after_wrapping_in_document (
- document);
- else
- body = WEBKIT_DOM_HTML_ELEMENT (e_html_editor_view_quote_plain_text (view));
- e_html_editor_selection_restore (selection);
- }
-
- toggle_paragraphs_style (view);
- toggle_smileys (view);
- remove_images (view);
- remove_background_images_in_document (document);
-
- clear_attributes (document);
-
- webkit_dom_element_set_attribute (
- WEBKIT_DOM_ELEMENT (body), "data-converted", "", NULL);
-
- /* Update fonts - in plain text we only want monospace */
- e_html_editor_view_update_fonts (view);
-
- e_html_editor_view_force_spell_check (view);
-}
-
-static void
html_editor_view_load_changed (EHTMLEditorView *view,
WebKitLoadEvent load_event)
{
@@ -7075,28 +2422,6 @@ html_editor_view_load_changed (EHTMLEditorView *view,
e_html_editor_view_turn_spell_check_off (view);
}
-static void
-wrap_paragraphs_in_quoted_content (EHTMLEditorSelection *selection,
- WebKitDOMDocument *document)
-{
- gint ii, length;
- WebKitDOMNodeList *paragraphs;
-
- paragraphs = webkit_dom_document_query_selector_all (
- document, "blockquote[type=cite] > .-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_html_editor_selection_wrap_paragraph (
- selection, WEBKIT_DOM_ELEMENT (paragraph));
- }
- g_object_unref (paragraphs);
-}
-
/**
* e_html_editor_view_set_html_mode:
* @view: an #EHTMLEditorView
@@ -7146,7 +2471,32 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
view->priv->html_mode = html_mode;
- convert_when_changing_composer_mode (view);
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (view != NULL);
+
+ web_extension = e_html_editor_view_get_web_extension_proxy (view);
+ if (!web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ web_extension,
+ "ConvertWhenChangingComposerMode",
+ g_variant_new (
+ "(tsb)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ text,
+ TRUE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+
+ /* Update fonts - in plain text we only want monospace */
+ e_html_editor_view_update_fonts (view);
+
+ e_html_editor_view_force_spell_check (view);
e_html_editor_selection_scroll_to_caret (selection);
@@ -7170,7 +2520,7 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
toggle_paragraphs_style (view);
toggle_smileys (view);
- remove_wrapping_from_view (view);
+ remove_wrapping_from_document (view);
} else {
gchar *plain;
@@ -7209,13 +2559,12 @@ e_html_editor_view_set_html_mode (EHTMLEditorView *view,
static void
e_html_editor_view_init (EHTMLEditorView *view)
{
- WebKitWebSettings *settings;
+ WebKitSettings *settings;
GSettings *g_settings;
GSettingsSchema *settings_schema;
ESpellChecker *checker;
gchar **languages;
gchar *comma_separated;
- const gchar *user_cache_dir;
view->priv = E_HTML_EDITOR_VIEW_GET_PRIVATE (view);
@@ -7244,9 +2593,6 @@ e_html_editor_view_init (EHTMLEditorView *view)
view, "should-show-delete-interface-for-element",
G_CALLBACK (html_editor_view_should_show_delete_interface_for_element), NULL);
g_signal_connect (
- view, "resource-request-starting",
- G_CALLBACK (html_editor_view_resource_requested), NULL);
- g_signal_connect (
view, "load-changed",
G_CALLBACK (html_editor_view_load_changed), NULL);
@@ -7319,21 +2665,10 @@ e_html_editor_view_init (EHTMLEditorView *view)
/* Make WebKit think we are displaying a local file, so that it
* does not block loading resources from file:// protocol */
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), "", "text/html", "UTF-8", "file://");
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), "", "file://");
html_editor_view_set_links_active (view, FALSE);
- if (emd_global_http_cache == NULL) {
- user_cache_dir = e_get_user_cache_dir ();
- emd_global_http_cache = camel_data_cache_new (user_cache_dir, NULL);
-
- /* cache expiry - 2 hour access, 1 day max */
- camel_data_cache_set_expire_age (
- emd_global_http_cache, 24 * 60 * 60);
- camel_data_cache_set_expire_access (
- emd_global_http_cache, 2 * 60 * 60);
- }
}
/**
@@ -7471,6 +2806,43 @@ e_html_editor_view_get_spell_checker (EHTMLEditorView *view)
return E_SPELL_CHECKER (webkit_get_text_checker ());
}
+static gchar *
+process_document (EHTMLEditorView *view,
+ const gchar *function)
+{
+ GDBusProxy *web_extension;
+ GVariant *result;
+
+ g_return_val_if_fail (view != NULL, NULL);
+
+ web_extension = e_html_editor_view_get_web_extension_proxy (view);
+ if (!web_extension)
+ return NULL;
+
+ result = g_dbus_proxy_call_sync (
+ web_extension,
+ function,
+ g_variant_new (
+ "(t)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+
+ if (result) {
+ gchar *value;
+ gsize length = 0;
+
+ value = g_variant_dup_string (result, &length);
+ g_variant_unref (result);
+
+ return value;
+ }
+
+ return NULL;
+}
+
/**
* e_html_editor_view_get_text_html:
* @view: an #EHTMLEditorView:
@@ -7483,7 +2855,7 @@ e_html_editor_view_get_spell_checker (EHTMLEditorView *view)
gchar *
e_html_editor_view_get_text_html (EHTMLEditorView *view)
{
- return process_content_for_html (view);
+ return process_document (view, "ProcessDocumentForHTML");
}
/**
@@ -7498,7 +2870,7 @@ e_html_editor_view_get_text_html (EHTMLEditorView *view)
gchar *
e_html_editor_view_get_text_html_for_drafts (EHTMLEditorView *view)
{
- return process_content_for_saving_as_draft (view);
+ return process_document (view, "ProcessDocumentForDrafts");
}
/**
@@ -7514,21 +2886,21 @@ e_html_editor_view_get_text_html_for_drafts (EHTMLEditorView *view)
gchar *
e_html_editor_view_get_text_plain (EHTMLEditorView *view)
{
- return process_content_for_plain_text (view);
+ return process_document (view, "ProcessDocumentForPlainText");
}
void
e_html_editor_view_convert_and_insert_plain_text (EHTMLEditorView *view,
const gchar *text)
{
- html_editor_view_insert_converted_html_into_selection (view, FALSE, text);
+ insert_and_convert_html_into_selection (view, text, FALSE);
}
void
e_html_editor_view_convert_and_insert_html_to_plain_text (EHTMLEditorView *view,
const gchar *html)
{
- html_editor_view_insert_converted_html_into_selection (view, TRUE, html);
+ insert_and_convert_html_into_selection (view, html, TRUE);
}
/**
@@ -7561,14 +2933,12 @@ e_html_editor_view_set_text_html (EHTMLEditorView *view,
view->priv->reload_in_progress = TRUE;
if (view->priv->is_message_from_draft) {
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
return;
}
if (view->priv->is_message_from_selection && !view->priv->html_mode) {
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
view->priv->convert_in_situ = TRUE;
return;
}
@@ -7578,17 +2948,15 @@ e_html_editor_view_set_text_html (EHTMLEditorView *view,
if (strstr (text, "<!-- text/html -->")) {
if (!show_lose_formatting_dialog (view)) {
e_html_editor_view_set_html_mode (view, TRUE);
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+ webkit_web_view_load_html (
+ WEBKIT_WEB_VIEW (view), text, "file://");
return;
}
}
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
view->priv->convert_in_situ = TRUE;
} else
- webkit_web_view_load_string (
- WEBKIT_WEB_VIEW (view), text, NULL, NULL, "file://");
+ webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), text, "file://");
}
/**
@@ -7659,16 +3027,20 @@ e_html_editor_view_paste_clipboard_quoted (EHTMLEditorView *view)
void
e_html_editor_view_embed_styles (EHTMLEditorView *view)
{
- WebKitWebSettings *settings;
- WebKitDOMDocument *document;
- WebKitDOMElement *sheet;
+ GDBusProxy *web_extension;
gchar *stylesheet_uri;
gchar *stylesheet_content;
const gchar *stylesheet;
gsize length;
+ WebKitSettings *settings;
+
+ g_return_if_fail (view != NULL);
+
+ web_extension = e_html_editor_view_get_web_extension_proxy (view);
+ if (!web_extension)
+ return;
settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view));
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
g_object_get (
G_OBJECT (settings),
@@ -7684,31 +3056,27 @@ e_html_editor_view_embed_styles (EHTMLEditorView *view)
return;
}
- e_web_view_create_and_add_css_style_sheet (document, "-x-evo-composer-sheet");
-
- sheet = webkit_dom_document_get_element_by_id (document, "-x-evo-composer-sheet");
- webkit_dom_element_set_attribute (
- sheet,
- "type",
- "text/css",
+ g_dbus_proxy_call (
+ web_extension,
+ "DOMEmbedStyleSheet",
+ g_variant_new (
+ "(ts)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (view)),
+ stylesheet_content),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
NULL);
- webkit_dom_html_element_set_inner_html (WEBKIT_DOM_HTML_ELEMENT (sheet), stylesheet_content, NULL);
-
g_free (stylesheet_content);
}
void
e_html_editor_view_remove_embed_styles (EHTMLEditorView *view)
{
- WebKitDOMDocument *document;
- WebKitDOMElement *sheet;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
- sheet = webkit_dom_document_get_element_by_id (
- document, "-x-evo-composer-sheet");
-
- remove_node (WEBKIT_DOM_NODE (sheet));
+ e_html_editor_view_call_simple_extension_function (
+ view, "DOMRemoveEmbedStyleSheet");
}
static const gchar *
@@ -7745,7 +3113,7 @@ citation_color_level_5 (void)
* e_html_editor_view_update_fonts:
* @view: an #EHTMLEditorView
*
- * Forces the editor to reload font settings from WebKitWebSettings and apply
+ * Forces the editor to reload font settings from WebKitSettings and apply
* it on the content of the editor document.
*/
void
@@ -7760,7 +3128,7 @@ e_html_editor_view_update_fonts (EHTMLEditorView *view)
GString *stylesheet;
GtkStyleContext *context;
PangoFontDescription *ms, *vw;
- WebKitWebSettings *settings;
+ WebKitSettings *settings;
g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
@@ -8173,7 +3541,7 @@ e_html_editor_view_check_magic_links (EHTMLEditorView *view,
g_return_if_fail (E_IS_HTML_EDITOR_VIEW (view));
- range = html_editor_view_get_dom_range (view);
+ range = dom_get_range (view);
html_editor_view_check_magic_links (view, range, include_space, NULL);
}
diff --git a/e-util/e-html-editor.c b/e-util/e-html-editor.c
index ee17cc0..d367249 100644
--- a/e-util/e-html-editor.c
+++ b/e-util/e-html-editor.c
@@ -307,7 +307,6 @@ static void
html_editor_update_actions (EHTMLEditor *editor,
guint flags)
{
- WebKitWebView *web_view;
WebKitSpellChecker *checker;
WebKitHitTestResult *hit_test;
WebKitHitTestResultContext context;
@@ -326,7 +325,6 @@ html_editor_update_actions (EHTMLEditor *editor,
view = e_html_editor_get_view (editor);
spell_checker = e_html_editor_view_get_spell_checker (view);
- web_view = WEBKIT_WEB_VIEW (view);
manager = e_html_editor_get_ui_manager (editor);
visible = (flags & E_HTML_EDITOR_NODE_IS_IMAGE);
@@ -440,7 +438,7 @@ html_editor_spell_languages_changed (EHTMLEditor *editor)
{
EHTMLEditorView *view;
ESpellChecker *spell_checker;
- WebKitWebSettings *settings;
+ WebKitSettings *settings;
gchar *comma_separated;
gchar **languages;
@@ -496,11 +494,15 @@ html_editor_context_menu_cb (WebKitWebView *webkit_web_view,
if (event)
gtk_menu_popup (
GTK_MENU (menu), NULL, NULL, NULL,
- GTK_WIDGET (webkit_web_view), ((GdkEventButton*) event)->button, event->time);
+ GTK_WIDGET (webkit_web_view),
+ ((GdkEventButton*) event)->button,
+ ((GdkEventButton*) event)->time);
else
gtk_menu_popup (
GTK_MENU (menu), NULL, NULL, NULL,
- GTK_WIDGET (webkit_web_view), 0, gtk_get_current_event_time ());
+ GTK_WIDGET (webkit_web_view),
+ 0,
+ gtk_get_current_event_time ());
return TRUE;
}
diff --git a/e-util/e-html-editor.h b/e-util/e-html-editor.h
index 5618cc8..5071435 100644
--- a/e-util/e-html-editor.h
+++ b/e-util/e-html-editor.h
@@ -64,7 +64,7 @@ struct _EHTMLEditorClass {
GtkGridClass parent_class;
void (*update_actions) (EHTMLEditor *editor,
- GdkEventButton *event);
+ guint flags);
void (*spell_languages_changed)
(EHTMLEditor *editor);
};
diff --git a/e-util/web-extensions/Makefile.am b/e-util/web-extensions/Makefile.am
index 335ea9b..a93a3f6 100644
--- a/e-util/web-extensions/Makefile.am
+++ b/e-util/web-extensions/Makefile.am
@@ -2,7 +2,8 @@ webextensions_LTLIBRARIES = libehtmleditorwebextension.la
libevolutionwebextension_la_SOURCES = \
e-html-editor-web-extension.c \
- e-html-editor-web-extension.h
+ e-html-editor-web-extension.h \
+ e-html-editor-web-extension-main.c
libevolutionwebextension_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
diff --git a/e-util/web-extensions/e-html-editor-web-extension-main.c
b/e-util/web-extensions/e-html-editor-web-extension-main.c
new file mode 100644
index 0000000..aa4fcce
--- /dev/null
+++ b/e-util/web-extensions/e-html-editor-web-extension-main.c
@@ -0,0 +1,51 @@
+/*
+ * e-html-editor-web-extension-main.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+
+#include "e-html-editor-web-extension.h"
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ EHTMLEditorWebExtension *extension)
+{
+ e_html_editor_web_extension_dbus_register (extension, connection);
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *wk_extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *wk_extension)
+{
+ EHTMLEditorWebExtension *extension;
+
+ extension = e_html_editor_web_extension_get ();
+ e_html_editor_web_extension_initialize (extension, wk_extension);
+
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ (GBusAcquiredCallback) bus_acquired_cb,
+ NULL, /* GBusNameAcquiredCallback */
+ NULL, /* GBusNameLostCallback */
+ g_object_ref (extension),
+ (GDestroyNotify) g_object_unref);
+}
diff --git a/web-extensions/evolution-web-extension.h
b/e-util/web-extensions/e-html-editor-web-extension-names.h
similarity index 59%
rename from web-extensions/evolution-web-extension.h
rename to e-util/web-extensions/e-html-editor-web-extension-names.h
index ccee49f..0c42931 100644
--- a/web-extensions/evolution-web-extension.h
+++ b/e-util/web-extensions/e-html-editor-web-extension-names.h
@@ -1,5 +1,5 @@
/*
- * evolution-web-extension.h
+ * e-html-editor-web-extension-names.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,11 @@
*
*/
-#ifndef EVOLUTION_WEB_EXTENSION_H
-#define EVOLUTION_WEB_EXTENSION_H
+#ifndef E_HTML_EDITOR_WEB_EXTENSION_NAMES_H
+#define E_HTML_EDITOR_WEB_EXTENSION_NAMES_H
-#define EVOLUTION_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
-#define EVOLUTION_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/WebExtension"
-#define EVOLUTION_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.EHTMLEditor.WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/EHTMLEditor/WebExtension"
+#define E_HTML_EDITOR_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.EHTMLEditor.WebExtension"
-#endif /* EVOLUTION_WEB_EXTENSION_H */
+#endif /* E_HTML_EDITOR_WEB_EXTENSION_NAMES_H */
diff --git a/e-util/web-extensions/e-html-editor-web-extension.c
b/e-util/web-extensions/e-html-editor-web-extension.c
index 5487aaa..251d471 100644
--- a/e-util/web-extensions/e-html-editor-web-extension.c
+++ b/e-util/web-extensions/e-html-editor-web-extension.c
@@ -16,14 +16,16 @@
*
*/
+#include "config.h"
+
#include "e-html-editor-web-extension.h"
+#include <string.h>
+
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <webkit2/webkit-web-extension.h>
-#include <string.h>
-
#include <e-util/e-dom-utils.h>
#include <e-util/e-html-editor-actions-dom-functions.h>
#include <e-util/e-html-editor-cell-dialog-dom-functions.h>
@@ -35,28 +37,43 @@
#include <e-util/e-html-editor-table-dialog-dom-functions.h>
#include <e-util/e-html-editor-view-dom-functions.h>
-/* FIXME Clean it */
-static GDBusConnection *dbus_connection;
-
-/* These properties show the actual state of EHTMLEditorView */
-static EHTMLEditorSelectionAlignment alignment;
-static gchar *background_color = NULL;
-static EHTMLEditorSelectionBlockFormat block_format;
-static gboolean bold = FALSE;
-/* FIXME XXX WK2
-static GdkRGBA *font_color = NULL; */
-static gchar *font_color = NULL;
-static gchar *font_name = NULL;
-static gint font_size;
-static gboolean indented = FALSE;
-static gboolean italic = FALSE;
-static gboolean monospaced = FALSE;
-static gboolean strikethrough = FALSE;
-static gboolean subscript = FALSE;
-static gboolean superscript = FALSE;
-/* FIXME XXX WK2 is it needed?
-static gchar *text = NULL; */
-static gboolean underline = FALSE;
+#define E_HTML_EDITOR_WEB_EXTENSION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionPrivate))
+
+struct _EWebExtensionPrivate {
+ WebKitWebExtension *wk_extension;
+
+ GDBusConnection *dbus_connection;
+ guint registration_id;
+
+ /* These properties show the actual state of EHTMLEditorView */
+ EHTMLEditorSelectionAlignment alignment;
+ EHTMLEditorSelectionBlockFormat block_format;
+ gchar *background_color;
+ gchar *font_color;
+ gchar *font_name;
+ gchar *text;
+ gint font_size;
+ gboolean bold;
+ gboolean indented;
+ gboolean italic;
+ gboolean monospaced;
+ gboolean strikethrough;
+ gboolean subscript;
+ gboolean superscript;
+ gboolean underline;
+
+ gboolean force_image_load;
+ gboolean changed;
+ gboolean inline_spelling;
+ gboolean magic_links;
+ gboolean magic_smileys;
+ gboolean html_mode;
+ gint word_wrap_length;
+};
+
+static CamelDataCache *emd_global_http_cache = NULL;
static const char introspection_xml[] =
"<node>"
@@ -65,6 +82,9 @@ static const char introspection_xml[] =
"<!-- PROPERTIES -->"
"<!-- ********************************************************* -->"
" <property type='b' name='ForceImageLoad' access='readwrite'/>"
+" <property type='b' name='InlineSpelling' access='readwrite'/>"
+" <property type='b' name='MagicLinks' access='readwrite'/>"
+" <property type='b' name='HTMLMode' access='readwrite'/>"
"<!-- ********************************************************* -->"
"<!-- These properties show the actual state of EHTMLEditorView -->"
"<!-- ********************************************************* -->"
@@ -82,6 +102,7 @@ static const char introspection_xml[] =
" <property type='b' name='Subscript' access='readwrite'/>"
" <property type='b' name='Superscript' access='readwrite'/>"
" <property type='b' name='Underline' access='readwrite'/>"
+" <property type='s' name='Text' access='readwrite'/>"
"<!-- ********************************************************* -->"
"<!-- METHODS -->"
"<!-- ********************************************************* -->"
@@ -336,10 +357,11 @@ handle_method_call (GDBusConnection *connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
- WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data);
- WebKitWebPage *web_page;
- WebKitDOMDocument *document;
guint64 page_id;
+ EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
+ WebKitDOMDocument *document;
+ WebKitWebExtension *web_extension = extension->priv->wk_extension;
+ WebKitWebPage *web_page;
if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
return;
@@ -1109,40 +1131,49 @@ handle_get_property (GDBusConnection *connection,
GError **error,
gpointer user_data)
{
+ EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
GVariant *variant;
if (g_strcmp0 (property_name, "ForceImageLoad") == 0)
- variant = g_variant_new_boolean (force_image_load);
+ variant = g_variant_new_boolean (extension->priv->force_image_load);
+ else if (g_strcmp0 (property_name, "InlineSpelling") == 0)
+ variant = g_variant_new_boolean (extension->priv->inline_spelling);
+ else if (g_strcmp0 (property_name, "MagicLinks") == 0)
+ variant = g_variant_new_boolean (extension->priv->magic_links);
+ else if (g_strcmp0 (property_name, "HTMLMode") == 0)
+ variant = g_variant_new_boolean (extension->priv->html_mode);
else if (g_strcmp0 (property_name, "Alignment") == 0)
- variant = g_variant_new_int32 (alignment);
+ variant = g_variant_new_int32 (extension->priv->alignment);
else if (g_strcmp0 (property_name, "BackgroundColor") == 0)
- variant = g_variant_new_string (background_color);
+ variant = g_variant_new_string (extension->priv->background_color);
else if (g_strcmp0 (property_name, "BlockFormat") == 0)
- variant = g_variant_new_int32 (block_format);
+ variant = g_variant_new_int32 (extension->priv->block_format);
else if (g_strcmp0 (property_name, "Bold") == 0)
- variant = g_variant_new_boolean (bold);
+ variant = g_variant_new_boolean (extension->priv->bold);
else if (g_strcmp0 (property_name, "FontColor") == 0)
- variant = g_variant_new_string (font_color);
+ variant = g_variant_new_string (extension->priv->font_color);
else if (g_strcmp0 (property_name, "FontName") == 0)
- variant = g_variant_new_string (font_name);
+ variant = g_variant_new_string (extension->priv->font_name);
else if (g_strcmp0 (property_name, "FontSize") == 0)
- variant = g_variant_new_int32 (font_size);
+ variant = g_variant_new_int32 (extension->priv->font_size);
else if (g_strcmp0 (property_name, "Indented") == 0)
- variant = g_variant_new_boolean (indented);
+ variant = g_variant_new_boolean (extension->priv->indented);
else if (g_strcmp0 (property_name, "Italic") == 0)
- variant = g_variant_new_boolean (italic);
+ variant = g_variant_new_boolean (extension->priv->italic);
else if (g_strcmp0 (property_name, "Monospaced") == 0)
- variant = g_variant_new_boolean (monospaced);
+ variant = g_variant_new_boolean (extension->priv->monospaced);
else if (g_strcmp0 (property_name, "Strikethrough") == 0)
- variant = g_variant_new_boolean (strikethrough);
+ variant = g_variant_new_boolean (extension->priv->strikethrough);
else if (g_strcmp0 (property_name, "Subscript") == 0)
- variant = g_variant_new_boolean (subscript);
+ variant = g_variant_new_boolean (extension->priv->subscript);
else if (g_strcmp0 (property_name, "Superscript") == 0)
- variant = g_variant_new_boolean (superscript);
+ variant = g_variant_new_boolean (extension->priv->superscript);
else if (g_strcmp0 (property_name, "Superscript") == 0)
- variant = g_variant_new_boolean (superscript);
+ variant = g_variant_new_boolean (extension->priv->superscript);
else if (g_strcmp0 (property_name, "Underline") == 0)
- variant = g_variant_new_boolean (underline);
+ variant = g_variant_new_boolean (extension->priv->underline);
+ else if (g_strcmp0 (property_name, "Text") == 0)
+ variant = g_variant_new_string (extension->priv->text);
return variant;
}
@@ -1157,6 +1188,7 @@ handle_set_property (GDBusConnection *connection,
GError **error,
gpointer user_data)
{
+ EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (user_data);
GError *local_error = NULL;
GVariantBuilder *builder;
@@ -1165,186 +1197,199 @@ handle_set_property (GDBusConnection *connection,
if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == force_image_load)
+ if (value == extension->priv->force_image_load)
goto exit;
- force_image_load = value;
+ extension->priv->force_image_load = value;
g_variant_builder_add (builder,
"{sv}",
"ForceImageLoad",
- g_variant_new_boolean (force_image_load));
+ g_variant_new_boolean (extension->priv->force_image_load));
} else if (g_strcmp0 (property_name, "Alignment") == 0) {
gint32 value = g_variant_get_int32 (variant);
- if (value == alignment)
+ if (value == extension->priv->alignment)
goto exit;
- alignment = value;
+ extension->priv->alignment = value;
g_variant_builder_add (builder,
"{sv}",
"Alignment",
- g_variant_new_int32 (alignment));
+ g_variant_new_int32 (extension->priv->alignment));
} else if (g_strcmp0 (property_name, "BackgroundColor") == 0) {
const gchar *value = g_variant_get_string (variant);
- if (g_strcmp0 (value, background_color) != 0)
+ if (g_strcmp0 (value, extension->priv->background_color) != 0)
goto exit;
- g_free (background_color);
- background_color = g_strdup (value);
+ g_free (extension->priv->background_color);
+ extension->priv->background_color = g_strdup (value);
g_variant_builder_add (builder,
"{sv}",
"BackgroundColor",
- g_variant_new_string (background_color));
+ g_variant_new_string (extension->priv->background_color));
} else if (g_strcmp0 (property_name, "BlockFormat") == 0) {
gint32 value = g_variant_get_int32 (variant);
- if (value == block_format)
+ if (value == extension->priv->block_format)
goto exit;
- block_format = value;
+ extension->priv->block_format = value;
g_variant_builder_add (builder,
"{sv}",
"BlockFormat",
- g_variant_new_int32 (block_format));
+ g_variant_new_int32 (extension->priv->block_format));
} else if (g_strcmp0 (property_name, "Bold") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == bold)
+ if (value == extension->priv->bold)
goto exit;
- bold = value;
+ extension->priv->bold = value;
g_variant_builder_add (builder,
"{sv}",
"Bold",
- g_variant_new_boolean (bold));
+ g_variant_new_boolean (extension->priv->bold));
} else if (g_strcmp0 (property_name, "FontColor") == 0) {
const gchar *value = g_variant_get_string (variant);
- if (g_strcmp0 (value, font_color) != 0)
+ if (g_strcmp0 (value, extension->priv->font_color) != 0)
goto exit;
- g_free (font_color);
- font_color = g_strdup (value);
+ g_free (extension->priv->font_color);
+ extension->priv->font_color = g_strdup (value);
g_variant_builder_add (builder,
"{sv}",
"FontColor",
- g_variant_new_string (font_color));
+ g_variant_new_string (extension->priv->font_color));
} else if (g_strcmp0 (property_name, "FontName") == 0) {
const gchar *value = g_variant_get_string (variant);
- if (g_strcmp0 (value, font_name) != 0)
+ if (g_strcmp0 (value, extension->priv->font_name) != 0)
goto exit;
- g_free (font_name);
- font_name = g_strdup (value);
+ g_free (extension->priv->font_name);
+ extension->priv->font_name = g_strdup (value);
g_variant_builder_add (builder,
"{sv}",
"FontName",
- g_variant_new_string (font_name));
+ g_variant_new_string (extension->priv->font_name));
} else if (g_strcmp0 (property_name, "FontSize") == 0) {
gint32 value = g_variant_get_int32 (variant);
- if (value == font_size)
+ if (value == extension->priv->font_size)
goto exit;
- font_size = value;
+ extension->priv->font_size = value;
g_variant_builder_add (builder,
"{sv}",
"FontSize",
- g_variant_new_int32 (font_size));
+ g_variant_new_int32 (extension->priv->font_size));
} else if (g_strcmp0 (property_name, "Indented") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == indented)
+ if (value == extension->priv->indented)
goto exit;
- indented = value;
+ extension->priv->indented = value;
g_variant_builder_add (builder,
"{sv}",
"Indented",
- g_variant_new_boolean (indented));
+ g_variant_new_boolean (extension->priv->indented));
} else if (g_strcmp0 (property_name, "Italic") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == italic)
+ if (value == extension->priv->italic)
goto exit;
- italic = value;
+ extension->priv->italic = value;
g_variant_builder_add (builder,
"{sv}",
"Italic",
- g_variant_new_boolean (italic));
+ g_variant_new_boolean (extension->priv->italic));
} else if (g_strcmp0 (property_name, "Monospaced") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == monospaced)
+ if (value == extension->priv->monospaced)
goto exit;
- monospaced = value;
+ extension->priv->monospaced = value;
g_variant_builder_add (builder,
"{sv}",
"Monospaced",
- g_variant_new_boolean (monospaced));
+ g_variant_new_boolean (extension->priv->monospaced));
} else if (g_strcmp0 (property_name, "Strikethrough") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == strikethrough)
+ if (value == extension->priv->strikethrough)
goto exit;
- strikethrough = value;
+ extension->priv->strikethrough = value;
g_variant_builder_add (builder,
"{sv}",
"Strikethrough",
- g_variant_new_boolean (strikethrough));
+ g_variant_new_boolean (extension->priv->strikethrough));
} else if (g_strcmp0 (property_name, "Subscript") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == subscript)
+ if (value == extension->priv->subscript)
goto exit;
- subscript = value;
+ extension->priv->subscript = value;
g_variant_builder_add (builder,
"{sv}",
"Subscript",
- g_variant_new_boolean (subscript));
+ g_variant_new_boolean (extension->priv->subscript));
} else if (g_strcmp0 (property_name, "Superscript") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == superscript)
+ if (value == extension->priv->superscript)
goto exit;
- superscript = value;
+ extension->priv->superscript = value;
g_variant_builder_add (builder,
"{sv}",
"Superscript",
- g_variant_new_boolean (superscript));
+ g_variant_new_boolean (extension->priv->superscript));
} else if (g_strcmp0 (property_name, "Underline") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == underline)
+ if (value == extension->priv->underline)
goto exit;
- underline = value;
+ extension->priv->underline = value;
g_variant_builder_add (builder,
"{sv}",
"Undeline",
- g_variant_new_boolean (underline));
+ g_variant_new_boolean (extension->priv->underline));
+ } else if (g_strcmp0 (property_name, "Text") == 0) {
+ const gchar *value = g_variant_get_string (variant);
+
+ if (g_strcmp0 (value, extension->priv->text) != 0)
+ goto exit;
+
+ g_free (extension->priv->text);
+ extension->priv->text = g_strdup (value);
+
+ g_variant_builder_add (builder,
+ "{sv}",
+ "Text",
+ g_variant_new_string (extension->priv->text));
}
g_dbus_connection_emit_signal (connection,
@@ -1374,48 +1419,376 @@ static const GDBusInterfaceVTable interface_vtable = {
};
static void
-bus_acquired_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
+e_html_editor_html_editor_web_extension_dispose (GObject *object)
+{
+ EHTMLEditorWebExtension *extension = E_HTML_EDITOR_WEB_EXTENSION (object);
+
+ if (extension->priv->dbus_connection) {
+ g_dbus_connection_unregister_object (
+ extension->priv->dbus_connection,
+ extension->priv->registration_id);
+ extension->priv->registration_id = 0;
+ extension->priv->dbus_connection = NULL;
+ }
+
+ if (extension->priv->background_color != NULL) {
+ g_free (extension->priv->background_color);
+ extension->priv->background_color = NULL;
+ }
+
+ if (extension->priv->font_color != NULL) {
+ g_free (extension->priv->font_color);
+ extension->priv->font_color = NULL;
+ }
+
+ if (extension->priv->font_name != NULL) {
+ g_free (extension->priv->font_name);
+ extension->priv->font_name = NULL;
+ }
+
+ if (extension->priv->text != NULL) {
+ g_free (extension->priv->text);
+ extension->priv->text = NULL;
+ }
+
+ g_clear_object (&extension->priv->wk_extension);
+
+ G_OBJECT_CLASS (e_html_editor_web_extension_parent_class)->dispose (object);
+}
+
+static void
+e_html_editor_web_extension_class_init (EHTMLEditorWebExtensionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = e_html_editor_web_extension_dispose;
+
+ g_type_class_add_private (object_class, sizeof(EHTMLEditorWebExtensionPrivate));
+}
+
+static void
+e_html_editor_web_extension_init (EHTMLEditorWebExtension *extension)
+{
+ extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, E_TYPE_HTML_EDITOR_WEB_EXTENSION,
EHTMLEditorWebExtensionPrivate);
+
+ extension->priv->bold = FALSE;
+ extension->priv->background_color = NULL;
+ extension->priv->font_color = NULL;
+ extension->priv->font_name = NULL;
+ extension->priv->text = NULL;
+ extension->priv->font_size = E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL;
+ extension->priv->indented = FALSE;
+ extension->priv->italic = FALSE;
+ extension->priv->monospaced = FALSE;
+ extension->priv->strikethrough = FALSE;
+ extension->priv->subscript = FALSE;
+ extension->priv->superscript = FALSE;
+ extension->priv->underline = FALSE;
+ extension->priv->alignment = E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT;
+ extension->priv->block_format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH;
+ extension->priv->changed = FALSE;
+ extension->priv->force_image_load = FALSE;
+ extension->priv->inline_spelling = FALSE;
+ extension->priv->magic_links = FALSE;
+ extension->priv->magic_smileys = FALSE;
+ extension->priv->html_mode = FALSE;
+ extension->priv->word_wrap_length = 71;
+}
+
+static gpointer
+e_html_editor_web_extension_create_instance(gpointer data)
+{
+ return g_object_new (E_TYPE_HTML_EDITOR_WEB_EXTENSION, NULL);
+}
+
+EHTMLEditorWebExtension *
+e_html_editor_web_extension_get (void)
+{
+ static GOnce once_init = G_ONCE_INIT;
+ return E_HTML_EDITOR_WEB_EXTENSION (g_once (&once_init, e_html_editor_web_extension_create_instance,
NULL));
+}
+
+static gboolean
+image_exists_in_cache (const gchar *image_uri)
+{
+ gchar *filename;
+ gchar *hash;
+ gboolean exists = FALSE;
+
+ g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
+
+ hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
+ filename = camel_data_cache_get_filename (
+ emd_global_http_cache, "http", hash);
+
+ if (filename != NULL) {
+ exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+ g_free (filename);
+ }
+
+ g_free (hash);
+
+ return exists;
+}
+
+static EMailImageLoadingPolicy
+get_image_loading_policy (void)
+{
+ GSettings *settings;
+ EMailImageLoadingPolicy image_policy;
+
+ settings = e_util_ref_settings ("org.gnome.evolution.mail");
+ image_policy = g_settings_get_enum (settings, "image-loading-policy");
+ g_object_unref (settings);
+
+ return image_policy;
+}
+
+static void
+redirect_http_uri (EWebExtension *extension,
+ WebKitWebPage *web_page,
+ WebKitURIRequest *request)
+{
+ const gchar *uri;
+ gchar *new_uri;
+ SoupURI *soup_uri;
+ gboolean image_exists;
+ EMailImageLoadingPolicy image_policy;
+
+ uri = webkit_uri_request_get_uri (request);
+
+ /* Check Evolution's cache */
+ image_exists = image_exists_in_cache (uri);
+
+ /* If the URI is not cached and we are not allowed to load it
+ * then redirect to invalid URI, so that webkit would display
+ * a native placeholder for it. */
+ image_policy = get_image_loading_policy ();
+ if (!image_exists && !extension->priv->force_image_load &&
+ (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
+ webkit_uri_request_set_uri (request, "about:blank");
+ return;
+ }
+
+ new_uri = g_strconcat ("evo-", uri, NULL);
+ soup_uri = soup_uri_new (new_uri);
+ g_free (new_uri);
+
+ new_uri = soup_uri_to_string (soup_uri, FALSE);
+ webkit_uri_request_set_uri (request, new_uri);
+ soup_uri_free (soup_uri);
+
+ g_free (new_uri);
+}
+
+static gboolean
+web_page_send_request_cb (WebKitWebPage *web_page,
+ WebKitURIRequest *request,
+ WebKitURIResponse *redirected_response,
+ EWebExtension *extension)
+{
+ const char *request_uri;
+ const char *page_uri;
+ gboolean uri_is_http;
+
+ request_uri = webkit_uri_request_get_uri (request);
+ page_uri = webkit_web_page_get_uri (web_page);
+
+ /* Always load the main resource. */
+ if (g_strcmp0 (request_uri, page_uri) == 0)
+ return FALSE;
+
+ uri_is_http =
+ g_str_has_prefix (request_uri, "http:") ||
+ g_str_has_prefix (request_uri, "https:") ||
+ g_str_has_prefix (request_uri, "evo-http:") ||
+ g_str_has_prefix (request_uri, "evo-https:");
+
+ if (uri_is_http)
+ redirect_http_uri (extension, web_page, request);
+
+ return FALSE;
+}
+
+static void
+web_page_document_loaded_cb (WebKitWebPage *web_page,
+ gpointer user_data)
+{
+
+}
+
+static void
+web_page_created_cb (WebKitWebExtension *wk_extension,
+ WebKitWebPage *web_page,
+ EWebExtension *extension)
+{
+ g_signal_connect_object (
+ web_page, "send-request",
+ G_CALLBACK (web_page_send_request),
+ extension, 0);
+
+ g_signal_connect_object (
+ web_page, "document-loaded",
+ G_CALLBACK (web_page_document_loaded),
+ extension, 0);
+
+}
+
+void
+e_html_editor_web_extension_initialize (EWebExtension *extension,
+ WebKitWebExtension *wk_extension)
+{
+ g_return_if_fail (E_HTML_EDITOR_IS_WEB_EXTENSION (extension));
+
+ extension->priv->wk_extension = g_object_ref (wk_extension);
+
+ if (emd_global_http_cache == NULL) {
+ emd_global_http_cache = camel_data_cache_new (
+ e_get_user_cache_dir (), NULL);
+
+ /* cache expiry - 2 hour access, 1 day max */
+ camel_data_cache_set_expire_age (
+ emd_global_http_cache, 24 * 60 * 60);
+ camel_data_cache_set_expire_access (
+ emd_global_http_cache, 2 * 60 * 60);
+ }
+}
+
+void
+e_html_editor_web_extension_dbus_register (EHTMLEditorWebExtension *extension,
+ GDBusConnection *connection)
{
- guint registration_id;
GError *error = NULL;
static GDBusNodeInfo *introspection_data = NULL;
- if (!introspection_data)
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
- registration_id =
- g_dbus_connection_register_object (
- connection,
- EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- g_object_ref (user_data),
- g_object_unref,
- &error);
-
- if (!registration_id) {
- g_warning ("Failed to register object: %s\n", error->message);
- g_error_free (error);
- } else {
- dbus_connection = connection;
- g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
+ g_return_if_fail (E_IS_HTML_EDITOR_WEB_EXTENSION (extension));
+ g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+
+ if (!introspection_data) {
+ introspection_data =
+ g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+ extension->priv->registration_id =
+ g_dbus_connection_register_object (
+ connection,
+ E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ extension,
+ NULL,
+ &error);
+
+ if (!extension->priv->registration_id) {
+ g_warning ("Failed to register object: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ extension->priv->dbus_connection = connection;
+ g_object_add_weak_pointer (
+ G_OBJECT (connection),
+ (gpointer *)&extension->priv->dbus_connection);
+ }
}
}
-/* Forward declaration */
-G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+void
+set_dbus_property_boolean (EHTMLEditorWebExtension *extension,
+ const gchar *name,
+ gboolean value)
+{
+ g_dbus_connection_call (
+ extension->priv->dbus_connection,
+ E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME,
+ E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH,
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ g_variant_new (
+ "(ssv)",
+ E_HTML_EDITOR_WEB_EXTENSION_INTERFACE,
+ name,
+ g_variant_new_boolean (value)),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+void
+e_html_editor_web_extension_set_content_changed (EHTMLEditorWebExtension *extension)
+{
+ set_dbus_property_boolean (extension, "Changed", TRUE);
+}
+
+gboolean
+e_html_editor_web_extension_get_html_mode (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->html_mode;
+}
+
+GDBusConnection *
+e_html_editor_web_extension_get_connection (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->connection;
+}
-G_MODULE_EXPORT void
-webkit_web_extension_initialize (WebKitWebExtension *extension)
+gint
+e_html_editor_web_extension_get_word_wrap_length (EHTMLEditorWebExtension *extension)
{
- g_bus_own_name (
- G_BUS_TYPE_SESSION,
- EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- bus_acquired_cb,
- NULL, NULL,
- g_object_ref (extension),
- g_object_unref);
+ return extension->priv->word_wrap_length;
}
+
+const gchar *
+e_html_editor_web_extension_get_selection_text (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->text;
+}
+
+gboolean
+e_html_editor_web_extension_get_bold (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->bold;
+}
+
+gboolean
+e_html_editor_web_extension_get_italic (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->italic;
+}
+
+gboolean
+e_html_editor_web_extension_get_underline (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->underline;
+}
+
+gboolean
+e_html_editor_web_extension_get_striketrough (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->strikethrough;
+}
+
+gint
+e_html_editor_web_extension_get_font_size (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->font_size;
+}
+
+EHTMLEditorSelectionAlignment
+e_html_editor_web_extension_get_alignment (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->alignment;
+}
+
+gboolean
+e_html_editor_web_extension_is_message_from_edit_as_new (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->is_message_from_edit_as_new;
+}
+
+gboolean
+e_html_editor_web_extension_get_remove_initial_input_line (EHTMLEditorWebExtension *extension)
+{
+ return extension->priv->remove_initial_input_line;
+}
+
diff --git a/e-util/web-extensions/e-html-editor-web-extension.h
b/e-util/web-extensions/e-html-editor-web-extension.h
index ec99d21..9803b2a 100644
--- a/e-util/web-extensions/e-html-editor-web-extension.h
+++ b/e-util/web-extensions/e-html-editor-web-extension.h
@@ -19,8 +19,106 @@
#ifndef E_HTML_EDITOR_WEB_EXTENSION_H
#define E_HTML_EDITOR_WEB_EXTENSION_H
-#define E_HTML_EDITOR_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.EHTMLEditor.WebExtension"
-#define E_HTML_EDITOR_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/EHTMLEditor/WebExtension"
-#define E_HTML_EDITOR_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.EHTMLEditor.WebExtension"
+#include "config.h"
+#include "e-util-enums.h"
+
+#include "e-html-editor-web-extension-names.h"
+
+#include <webkit2/webkit-web-extension.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define E_TYPE_HTML_EDITOR_WEB_EXTENSION \
+ (e_html_editor_web_extension_get_type ())
+#define E_HTML_EDITOR_WEB_EXTENSION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtension))
+#define E_HTML_EDITOR_WEB_EXTENSION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionClass))
+#define E_IS_HTML_EDITOR_WEB_EXTENSION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION))
+#define E_IS_HTML_EDITOR_WEB_EXTENSION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_HTML_EDITOR_WEB_EXTENSION))
+#define E_HTML_EDITOR_WEB_EXTENSION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_HTML_EDITOR_WEB_EXTENSION, EHTMLEditorWebExtensionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EHTMLEditorWebExtension EHTMLEditorWebExtension;
+typedef struct _EHTMLEditorWebExtensionClass EHTMLEditorWebExtensionClass;
+typedef struct _EHTMLEditorWebExtensionPrivate EHTMLEditorWebExtensionPrivate;
+
+struct _EHTMLEditorWebExtension {
+ GObject parent;
+ EHTMLEditorWebExtensionPrivate *priv;
+};
+
+struct _EHTMLEditorWebExtensionClass
+{
+ GObjectClass parent_class;
+};
+
+GType e_html_editor_web_extension_get_type
+ (void) G_GNUC_CONST;
+
+EHTMLEditorWebExtension *
+ e_html_editor_web_extension_get (void);
+
+void e_html_editor_web_extension_initialize
+ (EHTMLEditorWebExtension *extension,
+ WebKitWebExtension *wk_extension);
+
+void e_html_editor_web_extension_dbus_register
+ (EHTMLEditorWebExtension *extension,
+ GDBusConnection *connection);
+
+void set_dbus_property_boolean (EHTMLEditorWebExtension *extension,
+ const gchar *name,
+ gboolean value);
+
+void e_html_editor_web_extension_set_content_changed
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_html_mode
+ (EHTMLEditorWebExtension *extension);
+
+GDBusConnection *
+ e_html_editor_web_extension_get_connection
+ (EHTMLEditorWebExtension *extension);
+
+gint e_html_editor_web_extension_get_word_wrap_length
+ (EHTMLEditorWebExtension *extension);
+
+const gchar * e_html_editor_web_extension_get_selection_text
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_bold
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_italic
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_underline
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_strikethrough
+ (EHTMLEditorWebExtension *extension);
+
+gint e_html_editor_web_extension_get_font_size
+ (EHTMLEditorWebExtension *extension);
+
+EHTMLEditorSelectionAlignment
+ e_html_editor_web_extension_get_alignment
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_is_message_from_edit_as_new
+ (EHTMLEditorWebExtension *extension);
+
+gboolean e_html_editor_web_extension_get_remove_initial_input_line
+ (EHTMLEditorWebExtension *extension);
#endif /* E_HTML_EDITOR_WEB_EXTENSION_H */
diff --git a/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
index 7fc005d..99fee71 100644
--- a/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
+++ b/modules/itip-formatter/web-extension/module-itip-formatter-web-extension.c
@@ -451,9 +451,7 @@ handle_method_call (GDBusConnection *connection,
document_saved, select_id);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", value));
-
- g_free (value);
+ invocation, g_variant_new_take_string (value));
} else if (g_strcmp0 (method_name, "SelectSetSelected") == 0) {
const gchar *select_id, *option;
@@ -537,9 +535,7 @@ handle_method_call (GDBusConnection *connection,
document_saved, area_id);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", value));
-
- g_free (value);
+ invocation, g_variant_new_take_string (value));
} else if (g_strcmp0 (method_name, "RebuildSourceList") == 0) {
const gchar *optgroup_id, *optgroup_label, *option_id, *option_label;
gboolean writable;
diff --git a/modules/mail/web-extension/module-mail-web-extension.c
b/modules/mail/web-extension/module-mail-web-extension.c
index a3c9a7e..1468319 100644
--- a/modules/mail/web-extension/module-mail-web-extension.c
+++ b/modules/mail/web-extension/module-mail-web-extension.c
@@ -81,9 +81,7 @@ handle_method_call (GDBusConnection *connection,
element_name = e_dom_utils_get_active_element_name (document);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", element_name));
-
- g_free (element_name);
+ invocation, g_variant_new_take_string (element_name));
}
}
diff --git a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
index e83efb0..9f3b4ca 100644
--- a/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
+++ b/modules/prefer-plain/web-extension/module-prefer-plain-web-extension.c
@@ -116,9 +116,7 @@ handle_method_call (GDBusConnection *connection,
document_uri = g_strdup ("");
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", document_uri));
-
- g_free (document_uri);
+ invocation, g_variant_new_take_string (document_uri));
}
}
diff --git a/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
index 229b981..84f4a72 100644
--- a/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
+++ b/modules/text-highlight/web-extension/module-text-highlight-web-extension.c
@@ -116,9 +116,7 @@ handle_method_call (GDBusConnection *connection,
document_uri = g_strdup ("");
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", document_uri));
-
- g_free (document_uri);
+ invocation, g_variant_new_take_string (document_uri));
}
}
diff --git a/web-extensions/Makefile.am b/web-extensions/Makefile.am
index 4b3441e..5516a46 100644
--- a/web-extensions/Makefile.am
+++ b/web-extensions/Makefile.am
@@ -1,8 +1,9 @@
webextensions_LTLIBRARIES = libevolutionwebextension.la
libevolutionwebextension_la_SOURCES = \
- evolution-web-extension.c \
- evolution-web-extension.h
+ e-web-extension.c \
+ e-web-extension.h \
+ e-web-extension-main.c
libevolutionwebextension_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
diff --git a/web-extensions/e-web-extension-main.c b/web-extensions/e-web-extension-main.c
new file mode 100644
index 0000000..5df0126
--- /dev/null
+++ b/web-extensions/e-web-extension-main.c
@@ -0,0 +1,51 @@
+/*
+ * e-web-extension-main.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "config.h"
+
+#include "e-web-extension.h"
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ EWebExtension *extension)
+{
+ e_web_extension_dbus_register (extension, connection);
+}
+
+/* Forward declaration */
+G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *wk_extension);
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize (WebKitWebExtension *wk_extension)
+{
+ EWebExtension *extension;
+
+ extension = e_web_extension_get ();
+ e_web_extension_initialize (extension, wk_extension);
+
+ g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ E_WEB_EXTENSION_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ (GBusAcquiredCallback) bus_acquired_cb,
+ NULL, /* GBusNameAcquiredCallback */
+ NULL, /* GBusNameLostCallback */
+ g_object_ref (extension),
+ (GDestroyNotify) g_object_unref);
+}
diff --git a/web-extensions/evolution-web-extension.c b/web-extensions/e-web-extension.c
similarity index 71%
rename from web-extensions/evolution-web-extension.c
rename to web-extensions/e-web-extension.c
index ef425ba..663d232 100644
--- a/web-extensions/evolution-web-extension.c
+++ b/web-extensions/e-web-extension.c
@@ -1,5 +1,5 @@
/*
- * evolution-web-extension.c
+ * e-web-extension.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,12 @@
*
*/
-#include "evolution-web-extension.h"
+#include "config.h"
+
+#include "e-web-extension.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
-#include <webkit2/webkit-web-extension.h>
#include <libemail-engine/e-mail-enums.h>
@@ -29,10 +30,20 @@
#include <e-util/e-dom-utils.h>
#include <libedataserver/libedataserver.h>
-/* FIXME Clean it */
-static GDBusConnection *dbus_connection;
-static gboolean need_input = FALSE;
-static gboolean force_image_load = FALSE;
+#define E_WEB_EXTENSION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_WEB_EXTENSION, EWebExtensionPrivate))
+
+struct _EWebExtensionPrivate {
+ WebKitWebExtension *wk_extension;
+
+ GDBusConnection *dbus_connection;
+ guint registration_id;
+
+ gboolean need_input;
+ gboolean force_image_load;
+};
+
static CamelDataCache *emd_global_http_cache = NULL;
static const char introspection_xml[] =
@@ -112,156 +123,7 @@ static const char introspection_xml[] =
" </interface>"
"</node>";
-static gboolean
-image_exists_in_cache (const gchar *image_uri)
-{
- gchar *filename;
- gchar *hash;
- gboolean exists = FALSE;
-
- g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
-
- hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
- filename = camel_data_cache_get_filename (
- emd_global_http_cache, "http", hash);
-
- if (filename != NULL) {
- exists = g_file_test (filename, G_FILE_TEST_EXISTS);
- g_free (filename);
- }
-
- g_free (hash);
-
- return exists;
-}
-
-static EMailImageLoadingPolicy
-get_image_loading_policy (void)
-{
- GSettings *settings;
- EMailImageLoadingPolicy image_policy;
-
- settings = e_util_ref_settings ("org.gnome.evolution.mail");
- image_policy = g_settings_get_enum (settings, "image-loading-policy");
- g_object_unref (settings);
-
- return image_policy;
-}
-
-static void
-redirect_http_uri (WebKitWebPage *web_page,
- WebKitURIRequest *request)
-{
- const gchar *uri, *page_uri;
- gchar *new_uri, *mail_uri, *enc;
- SoupURI *soup_uri;
- GHashTable *query;
- gboolean image_exists;
- EMailImageLoadingPolicy image_policy;
-
- uri = webkit_uri_request_get_uri (request);
- page_uri = webkit_web_page_get_uri (web_page);
-
- /* Check Evolution's cache */
- image_exists = image_exists_in_cache (uri);
-
- /* If the URI is not cached and we are not allowed to load it
- * then redirect to invalid URI, so that webkit would display
- * a native placeholder for it. */
- image_policy = get_image_loading_policy ();
- if (!image_exists && !force_image_load &&
- (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
- webkit_uri_request_set_uri (request, "about:blank");
- return;
- }
-
- new_uri = g_strconcat ("evo-", uri, NULL);
- mail_uri = g_strndup (page_uri, strstr (page_uri, "?") - page_uri);
-
- soup_uri = soup_uri_new (new_uri);
- if (soup_uri->query)
- query = soup_form_decode (soup_uri->query);
- else
- query = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- g_free, g_free);
-
- enc = soup_uri_encode (mail_uri, NULL);
- g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
-
- if (force_image_load) {
- g_hash_table_insert (
- query,
- g_strdup ("__evo-load-images"),
- g_strdup ("true"));
- }
-
- g_free (mail_uri);
-
- soup_uri_set_query_from_form (soup_uri, query);
- g_free (new_uri);
-
- new_uri = soup_uri_to_string (soup_uri, FALSE);
-
- webkit_uri_request_set_uri (request, new_uri);
-
- soup_uri_free (soup_uri);
- g_hash_table_unref (query);
- g_free (new_uri);
-}
-
-static gboolean
-web_page_send_request (WebKitWebPage *web_page,
- WebKitURIRequest *request,
- WebKitURIResponse *redirected_response,
- gpointer user_data)
-{
- const char *request_uri;
- const char *page_uri;
- gboolean uri_is_http;
-
- request_uri = webkit_uri_request_get_uri (request);
- page_uri = webkit_web_page_get_uri (web_page);
-
- /* Always load the main resource. */
- if (g_strcmp0 (request_uri, page_uri) == 0)
- return FALSE;
-
- uri_is_http =
- g_str_has_prefix (request_uri, "http:") ||
- g_str_has_prefix (request_uri, "https:") ||
- g_str_has_prefix (request_uri, "evo-http:") ||
- g_str_has_prefix (request_uri, "evo-https:");
-
- if (uri_is_http)
- redirect_http_uri (web_page, request);
-
- return FALSE;
-}
-
-static void
-web_page_document_loaded (WebKitWebPage *web_page,
- gpointer user_data)
-{
-
-}
-
-static void
-web_page_created_callback (WebKitWebExtension *extension,
- WebKitWebPage *web_page,
- gpointer user_data)
-{
- g_signal_connect_object (
- web_page, "send-request",
- G_CALLBACK (web_page_send_request),
- NULL, 0);
-
- g_signal_connect_object (
- web_page, "document-loaded",
- G_CALLBACK (web_page_document_loaded),
- NULL, 0);
-
-}
+G_DEFINE_TYPE (EWebExtension, e_web_extension, G_TYPE_OBJECT)
static WebKitWebPage *
get_webkit_web_page_or_return_dbus_error (GDBusMethodInvocation *invocation,
@@ -287,17 +149,19 @@ handle_method_call (GDBusConnection *connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
- WebKitWebExtension *web_extension = WEBKIT_WEB_EXTENSION (user_data);
- WebKitWebPage *web_page;
- WebKitDOMDocument *document;
guint64 page_id;
+ EWebExtension *extension = E_WEB_EXTENSION (user_data);
+ WebKitDOMDocument *document;
+ WebKitWebExtension *web_extension = extension->priv->wk_extension;
+ WebKitWebPage *web_page;
- if (g_strcmp0 (interface_name, EVOLUTION_WEB_EXTENSION_INTERFACE) != 0)
+ if (g_strcmp0 (interface_name, E_WEB_EXTENSION_INTERFACE) != 0)
return;
if (g_strcmp0 (method_name, "ReplaceLocalImageLinks") == 0) {
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -309,7 +173,8 @@ handle_method_call (GDBusConnection *connection,
gchar *html_content;
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -317,14 +182,13 @@ handle_method_call (GDBusConnection *connection,
html_content = e_dom_utils_get_document_content_html (document);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", html_content));
-
- g_free (html_content);
+ invocation, g_variant_new_take_string (html_content);
} else if (g_strcmp0 (method_name, "GetSelectionContentHTML") == 0) {
gchar *html_content;
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -332,14 +196,13 @@ handle_method_call (GDBusConnection *connection,
html_content = e_dom_utils_get_selection_content_html (document);
g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(s)", html_content));
-
- g_free (html_content);
+ invocation, g_variant_new_take_string (html_content);
} else if (g_strcmp0 (method_name, "GetSelectionContentText") == 0) {
gchar *text_content;
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -347,9 +210,7 @@ handle_method_call (GDBusConnection *connection,
text_content = e_dom_utils_get_selection_content_html (document);
g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(s)", text_content));
-
- g_free (text_content);
+ invocation, g_variant_new_take_string (text_content);
} else if (g_strcmp0 (method_name, "AddCSSRuleIntoStyleSheet") == 0) {
const gchar *style_sheet_id, *selector, *style;
@@ -358,7 +219,8 @@ handle_method_call (GDBusConnection *connection,
"(t&s&s&s)",
&page_id, &style_sheet_id, &selector, &style);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -370,7 +232,8 @@ handle_method_call (GDBusConnection *connection,
const gchar *style_sheet_id;
g_variant_get (parameters, "(t&s)", &page_id, &style_sheet_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -380,7 +243,8 @@ handle_method_call (GDBusConnection *connection,
g_dbus_method_invocation_return_value (invocation, NULL);
} else if (g_strcmp0 (method_name, "EABContactFormatterBindDOM") == 0) {
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -390,7 +254,8 @@ handle_method_call (GDBusConnection *connection,
g_dbus_method_invocation_return_value (invocation, NULL);
} else if (g_strcmp0 (method_name, "EMailDisplayBindDOM") == 0) {
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -404,7 +269,8 @@ handle_method_call (GDBusConnection *connection,
gboolean element_exists;
g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -417,7 +283,8 @@ handle_method_call (GDBusConnection *connection,
gchar *element_name;
g_variant_get (parameters, "(t)", &page_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -425,14 +292,13 @@ handle_method_call (GDBusConnection *connection,
element_name = e_dom_utils_get_active_element_name (document);
g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(s)", element_name));
-
- g_free (element_name);
+ invocation, g_variant_new_take_string (element_name));
} else if (g_strcmp0 (method_name, "EMailPartHeadersBindDOMElement") == 0) {
const gchar *element_id;
g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -444,7 +310,8 @@ handle_method_call (GDBusConnection *connection,
const gchar *element_id;
g_variant_get (parameters, "(t&s)", &page_id, &element_id);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -461,7 +328,8 @@ handle_method_call (GDBusConnection *connection,
"(t&s&s&s)",
&page_id, &button_id, &html_label, &access_key);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -474,7 +342,8 @@ handle_method_call (GDBusConnection *connection,
const gchar *src, *button_id;
g_variant_get (parameters, "(t&s&s)", &page_id, &button_id, &src);
- web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ web_page = get_webkit_web_page_or_return_dbus_error (
+ invocation, web_extension, page_id);
if (!web_page)
return;
@@ -494,12 +363,13 @@ handle_get_property (GDBusConnection *connection,
GError **error,
gpointer user_data)
{
+ EWebExtension *extension = E_WEB_EXTENSION (user_data);
GVariant *variant;
if (g_strcmp0 (property_name, "NeedInput") == 0) {
- variant = g_variant_new_boolean (need_input);
+ variant = g_variant_new_boolean (extension->priv->need_input);
} else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
- variant = g_variant_new_boolean (force_image_load);
+ variant = g_variant_new_boolean (extension->priv->force_image_load);
}
return variant;
@@ -515,6 +385,7 @@ handle_set_property (GDBusConnection *connection,
GError **error,
gpointer user_data)
{
+ EWebExtension *extension = E_WEB_EXTENSION (user_data);
GError *local_error = NULL;
GVariantBuilder *builder;
@@ -523,27 +394,27 @@ handle_set_property (GDBusConnection *connection,
if (g_strcmp0 (property_name, "NeedInput") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == need_input)
+ if (value == extension->priv->need_input)
goto exit;
- need_input = value;
+ extension->priv->need_input = value;
g_variant_builder_add (builder,
"{sv}",
"NeedInput",
- g_variant_new_boolean (need_input));
+ g_variant_new_boolean (value));
} else if (g_strcmp0 (property_name, "ForceImageLoad") == 0) {
gboolean value = g_variant_get_boolean (variant);
- if (value == force_image_load)
+ if (value == extension->priv->force_image_load)
goto exit;
- force_image_load = value;
+ extension->priv->force_image_load = value;
g_variant_builder_add (builder,
"{sv}",
"ForceImageLoad",
- g_variant_new_boolean (force_image_load));
+ g_variant_new_boolean (value));
}
g_dbus_connection_emit_signal (connection,
@@ -573,64 +444,263 @@ static const GDBusInterfaceVTable interface_vtable = {
};
static void
-bus_acquired_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
+e_web_extension_dispose (GObject *object)
{
- guint registration_id;
- GError *error = NULL;
- static GDBusNodeInfo *introspection_data = NULL;
+ EWebExtension *extension = E_WEB_EXTENSION (object);
+
+ if (extension->priv->dbus_connection) {
+ g_dbus_connection_unregister_object (
+ extension->priv->dbus_connection,
+ extension->priv->registration_id);
+ extension->priv->registration_id = 0;
+ extension->priv->dbus_connection = NULL;
+ }
- if (!introspection_data)
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
- registration_id =
- g_dbus_connection_register_object (
- connection,
- EVOLUTION_WEB_EXTENSION_OBJECT_PATH,
- introspection_data->interfaces[0],
- &interface_vtable,
- g_object_ref (user_data),
- g_object_unref,
- &error);
-
- if (!registration_id) {
- g_warning ("Failed to register object: %s\n", error->message);
- g_error_free (error);
- } else {
- dbus_connection = connection;
- g_object_add_weak_pointer (G_OBJECT (connection), (gpointer *)&dbus_connection);
-
- if (emd_global_http_cache == NULL) {
- emd_global_http_cache = camel_data_cache_new (
- e_get_user_cache_dir (), NULL);
-
- /* cache expiry - 2 hour access, 1 day max */
- camel_data_cache_set_expire_age (
- emd_global_http_cache, 24 * 60 * 60);
- camel_data_cache_set_expire_access (
- emd_global_http_cache, 2 * 60 * 60);
- }
+ g_clear_object (&extension->priv->wk_extension);
+
+ G_OBJECT_CLASS (e_web_extension_parent_class)->dispose (object);
+}
+
+static void
+e_web_extension_class_init (EWebExtensionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = e_web_extension_dispose;
+
+ g_type_class_add_private (object_class, sizeof(EWebExtensionPrivate));
+}
+
+static void
+e_web_extension_init (EWebExtension *extension)
+{
+ extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension, E_TYPE_WEB_EXTENSION, EWebExtensionPrivate);
+
+ extension->priv->need_input = FALSE;
+ extension->priv->force_image_load = FALSE;
+}
+
+static gpointer
+e_web_extension_create_instance(gpointer data)
+{
+ return g_object_new (E_TYPE_WEB_EXTENSION, NULL);
+}
+
+EWebExtension *
+e_web_extension_get (void)
+{
+ static GOnce once_init = G_ONCE_INIT;
+ return E_WEB_EXTENSION (g_once (&once_init, e_web_extension_create_instance, NULL));
+}
+
+static gboolean
+image_exists_in_cache (const gchar *image_uri)
+{
+ gchar *filename;
+ gchar *hash;
+ gboolean exists = FALSE;
+
+ g_return_val_if_fail (emd_global_http_cache != NULL, FALSE);
+
+ hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, image_uri, -1);
+ filename = camel_data_cache_get_filename (
+ emd_global_http_cache, "http", hash);
+
+ if (filename != NULL) {
+ exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+ g_free (filename);
+ }
+
+ g_free (hash);
+
+ return exists;
+}
+
+static EMailImageLoadingPolicy
+get_image_loading_policy (void)
+{
+ GSettings *settings;
+ EMailImageLoadingPolicy image_policy;
+
+ settings = e_util_ref_settings ("org.gnome.evolution.mail");
+ image_policy = g_settings_get_enum (settings, "image-loading-policy");
+ g_object_unref (settings);
+
+ return image_policy;
+}
+
+static void
+redirect_http_uri (EWebExtension *extension,
+ WebKitWebPage *web_page,
+ WebKitURIRequest *request)
+{
+ const gchar *uri, *page_uri;
+ gchar *new_uri, *mail_uri, *enc;
+ SoupURI *soup_uri;
+ GHashTable *query;
+ gboolean image_exists;
+ EMailImageLoadingPolicy image_policy;
+
+ uri = webkit_uri_request_get_uri (request);
+ page_uri = webkit_web_page_get_uri (web_page);
+
+ /* Check Evolution's cache */
+ image_exists = image_exists_in_cache (uri);
+
+ /* If the URI is not cached and we are not allowed to load it
+ * then redirect to invalid URI, so that webkit would display
+ * a native placeholder for it. */
+ image_policy = get_image_loading_policy ();
+ if (!image_exists && !extension->priv->force_image_load &&
+ (image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
+ webkit_uri_request_set_uri (request, "about:blank");
+ return;
+ }
+
+ new_uri = g_strconcat ("evo-", uri, NULL);
+ mail_uri = g_strndup (page_uri, strstr (page_uri, "?") - page_uri);
+
+ soup_uri = soup_uri_new (new_uri);
+ if (soup_uri->query)
+ query = soup_form_decode (soup_uri->query);
+ else
+ query = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ enc = soup_uri_encode (mail_uri, NULL);
+ g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
+
+ if (extension->priv->force_image_load) {
+ g_hash_table_insert (
+ query,
+ g_strdup ("__evo-load-images"),
+ g_strdup ("true"));
}
+
+ g_free (mail_uri);
+
+ soup_uri_set_query_from_form (soup_uri, query);
+ g_free (new_uri);
+
+ new_uri = soup_uri_to_string (soup_uri, FALSE);
+
+ webkit_uri_request_set_uri (request, new_uri);
+
+ soup_uri_free (soup_uri);
+ g_hash_table_unref (query);
+ g_free (new_uri);
+}
+
+static gboolean
+web_page_send_request_cb (WebKitWebPage *web_page,
+ WebKitURIRequest *request,
+ WebKitURIResponse *redirected_response,
+ EWebExtension *extension)
+{
+ const char *request_uri;
+ const char *page_uri;
+ gboolean uri_is_http;
+
+ request_uri = webkit_uri_request_get_uri (request);
+ page_uri = webkit_web_page_get_uri (web_page);
+
+ /* Always load the main resource. */
+ if (g_strcmp0 (request_uri, page_uri) == 0)
+ return FALSE;
+
+ uri_is_http =
+ g_str_has_prefix (request_uri, "http:") ||
+ g_str_has_prefix (request_uri, "https:") ||
+ g_str_has_prefix (request_uri, "evo-http:") ||
+ g_str_has_prefix (request_uri, "evo-https:");
+
+ if (uri_is_http)
+ redirect_http_uri (extension, web_page, request);
+
+ return FALSE;
+}
+
+static void
+web_page_document_loaded_cb (WebKitWebPage *web_page,
+ gpointer user_data)
+{
+
}
-/* Forward declaration */
-G_MODULE_EXPORT void webkit_web_extension_initialize (WebKitWebExtension *extension);
+static void
+web_page_created_cb (WebKitWebExtension *wk_extension,
+ WebKitWebPage *web_page,
+ EWebExtension *extension)
+{
+ g_signal_connect_object (
+ web_page, "send-request",
+ G_CALLBACK (web_page_send_request),
+ extension, 0);
+
+ g_signal_connect_object (
+ web_page, "document-loaded",
+ G_CALLBACK (web_page_document_loaded),
+ extension, 0);
+
+}
-G_MODULE_EXPORT void
-webkit_web_extension_initialize (WebKitWebExtension *extension)
+void
+e_web_extension_initialize (EWebExtension *extension,
+ WebKitWebExtension *wk_extension)
{
+ g_return_if_fail (E_IS_WEB_EXTENSION (extension));
+
+ extension->priv->wk_extension = g_object_ref (wk_extension);
+
+ if (emd_global_http_cache == NULL) {
+ emd_global_http_cache = camel_data_cache_new (
+ e_get_user_cache_dir (), NULL);
+
+ /* cache expiry - 2 hour access, 1 day max */
+ camel_data_cache_set_expire_age (
+ emd_global_http_cache, 24 * 60 * 60);
+ camel_data_cache_set_expire_access (
+ emd_global_http_cache, 2 * 60 * 60);
+ }
+
g_signal_connect (
- extension, "page-created",
- G_CALLBACK (web_page_created_callback),
- NULL);
-
- g_bus_own_name (
- G_BUS_TYPE_SESSION,
- EVOLUTION_WEB_EXTENSION_SERVICE_NAME,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- bus_acquired_cb,
- NULL, NULL,
- g_object_ref (extension),
- g_object_unref);
+ wk_extension, "page-created",
+ G_CALLBACK (web_page_created_cb), extension);
+}
+
+void
+e_web_extension_dbus_register (EWebExtension *extension,
+ GDBusConnection *connection)
+{
+ GError *error = NULL;
+ static GDBusNodeInfo *introspection_data = NULL;
+
+ g_return_if_fail (E_IS_WEB_EXTENSION (extension));
+ g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+
+ if (!introspection_data) {
+ introspection_data =
+ g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+
+ extension->priv->registration_id =
+ g_dbus_connection_register_object (
+ connection,
+ E_WEB_EXTENSION_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &interface_vtable,
+ extension,
+ NULL,
+ &error);
+
+ if (!extension->priv->registration_id) {
+ g_warning ("Failed to register object: %s\n", error->message);
+ g_error_free (error);
+ } else {
+ extension->priv->dbus_connection = connection;
+ g_object_add_weak_pointer (
+ G_OBJECT (connection),
+ (gpointer *)&extension->priv->dbus_connection);
+ }
+ }
}
diff --git a/web-extensions/e-web-extension.h b/web-extensions/e-web-extension.h
new file mode 100644
index 0000000..d54ea96
--- /dev/null
+++ b/web-extensions/e-web-extension.h
@@ -0,0 +1,76 @@
+/*
+ * e-web-extension.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_WEB_EXTENSION_H
+#define E_WEB_EXTENSION_H
+
+#include <webkit2/webkit-web-extension.h>
+#include <glib-object.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WEB_EXTENSION \
+ (e_web_extension_get_type ())
+#define E_WEB_EXTENSION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_WEB_EXTENSION, EWebExtension))
+#define E_WEB_EXTENSION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_WEB_EXTENSION, EWebExtensionClass))
+#define E_IS_WEB_EXTENSION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_WEB_EXTENSION))
+#define E_IS_WEB_EXTENSION_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_WEB_EXTENSION))
+#define E_WEB_EXTENSION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_WEB_EXTENSION, EWebExtensionClass))
+
+#define E_WEB_EXTENSION_SERVICE_NAME "org.gnome.Evolution.WebExtension"
+#define E_WEB_EXTENSION_OBJECT_PATH "/org/gnome/Evolution/WebExtension"
+#define E_WEB_EXTENSION_INTERFACE "org.gnome.Evolution.WebExtension"
+
+G_BEGIN_DECLS
+
+typedef struct _EWebExtension EWebExtension;
+typedef struct _EWebExtensionClass EWebExtensionClass;
+typedef struct _EWebExtensionPrivate EWebExtensionPrivate;
+
+struct _EWebExtension {
+ GObject parent;
+ EWebExtensionPrivate *priv;
+};
+
+struct _EWebExtensionClass
+{
+ GObjectClass parent_class;
+};
+
+GType e_web_extension_get_type (void) G_GNUC_CONST;
+
+EWebExtension * e_web_extension_get (void);
+
+void e_web_extension_initialize (EWebExtension *extension,
+ WebKitWebExtension *wk_extension);
+
+void e_web_extension_dbus_register (EWebExtension *extension,
+ GDBusConnection *connection);
+
+G_END_DECLS
+
+#endif /* E_WEB_EXTENSION_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]