[evolution/wip/webkit2] Bug 753474 - Pressing Enter (Return) twice in a bulleted list to exit the list creates a paragraph w
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Bug 753474 - Pressing Enter (Return) twice in a bulleted list to exit the list creates a paragraph w
- Date: Mon, 29 Feb 2016 18:49:11 +0000 (UTC)
commit c5f6f55b17f71bd248af5ab98812575f60b5987e
Author: Tomas Popela <tpopela redhat com>
Date: Mon Feb 29 19:41:29 2016 +0100
Bug 753474 - Pressing Enter (Return) twice in a bulleted list to exit the list creates a paragraph with
negative margin
.../e-html-editor-selection-dom-functions.c | 239 +-------------------
.../e-html-editor-selection-dom-functions.h | 20 --
.../composer/e-html-editor-undo-redo-manager.c | 54 ++++-
.../composer/e-html-editor-view-dom-functions.c | 115 ++++++++-
.../composer/e-html-editor-view-dom-functions.h | 4 +
web-extensions/e-dom-utils.c | 251 ++++++++++++++++++++
web-extensions/e-dom-utils.h | 34 +++
7 files changed, 447 insertions(+), 270 deletions(-)
---
diff --git a/web-extensions/composer/e-html-editor-selection-dom-functions.c
b/web-extensions/composer/e-html-editor-selection-dom-functions.c
index 6b9d5ff..c00351e 100644
--- a/web-extensions/composer/e-html-editor-selection-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-selection-dom-functions.c
@@ -371,64 +371,6 @@ dom_create_link (WebKitDOMDocument *document,
dom_exec_command (document, extension, E_HTML_EDITOR_VIEW_COMMAND_CREATE_LINK, uri);
}
-/**
- * e_html_editor_selection_get_list_format_from_node:
- * @node: an #WebKitDOMNode
- *
- * Returns block format of given list.
- *
- * Returns: #EHTMLEditorSelectionBlockFormat
- */
-EHTMLEditorSelectionBlockFormat
-dom_get_list_format_from_node (WebKitDOMNode *node)
-{
- EHTMLEditorSelectionBlockFormat format =
- E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
-
- if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (node))
- return -1;
-
- if (WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node))
- return format;
-
- if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node)) {
- gchar *type_value = webkit_dom_element_get_attribute (
- WEBKIT_DOM_ELEMENT (node), "type");
-
- if (!type_value)
- return E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
-
- if (!*type_value)
- format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
- else if (g_ascii_strcasecmp (type_value, "A") == 0)
- format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA;
- else if (g_ascii_strcasecmp (type_value, "I") == 0)
- format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN;
- g_free (type_value);
-
- return format;
- }
-
- return -1;
-}
-
-static gboolean
-node_is_list_or_item (WebKitDOMNode *node)
-{
- return node && (
- WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_LI_ELEMENT (node));
-}
-
-static gboolean
-node_is_list (WebKitDOMNode *node)
-{
- return node && (
- WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node));
-}
-
static gint
get_list_level (WebKitDOMNode *node)
{
@@ -622,49 +564,6 @@ create_list_element (WebKitDOMDocument *document,
return list;
}
-static void
-merge_list_into_list (WebKitDOMNode *from,
- WebKitDOMNode *to,
- gboolean insert_before)
-{
- WebKitDOMNode *item;
-
- if (!(to && from))
- return;
-
- while ((item = webkit_dom_node_get_first_child (from)) != NULL) {
- if (insert_before)
- webkit_dom_node_insert_before (
- to, item, webkit_dom_node_get_last_child (to), NULL);
- else
- webkit_dom_node_append_child (to, item, NULL);
- }
-
- if (!webkit_dom_node_has_child_nodes (from))
- remove_node (from);
-
-}
-
-static void
-merge_lists_if_possible (WebKitDOMNode *list)
-{
- EHTMLEditorSelectionBlockFormat format, prev, next;
- WebKitDOMNode *prev_sibling, *next_sibling;
-
- prev_sibling = webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (list));
- next_sibling = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (list));
-
- format = dom_get_list_format_from_node (list),
- prev = dom_get_list_format_from_node (prev_sibling);
- next = dom_get_list_format_from_node (next_sibling);
-
- if (format == prev && format != -1 && prev != -1)
- merge_list_into_list (prev_sibling, list, TRUE);
-
- if (format == next && format != -1 && next != -1)
- merge_list_into_list (next_sibling, list, FALSE);
-}
-
static gboolean
indent_list (WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension)
@@ -806,60 +705,6 @@ indent_block (WebKitDOMDocument *document,
return tmp;
}
-static WebKitDOMNode *
-split_list_into_two (WebKitDOMDocument *document,
- WebKitDOMNode *item)
-{
- WebKitDOMDocumentFragment *fragment;
- WebKitDOMNode *parent, *prev_parent, *tmp;
-
- fragment = webkit_dom_document_create_document_fragment (document);
-
- tmp = item;
- parent = webkit_dom_node_get_parent_node (item);
- while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
- WebKitDOMNode *clone, *first_child, *insert_before = NULL, *sibling;
-
- first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
- clone = webkit_dom_node_clone_node (parent, FALSE);
- webkit_dom_node_insert_before (
- WEBKIT_DOM_NODE (fragment), clone, first_child, NULL);
-
- if (first_child)
- insert_before = webkit_dom_node_get_first_child (first_child);
-
- while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child)))
- webkit_dom_node_insert_before (first_child, sibling, insert_before, NULL);
-
- while ((sibling = webkit_dom_node_get_next_sibling (tmp)))
- webkit_dom_node_append_child (clone, sibling, NULL);
-
- webkit_dom_node_insert_before (
- clone, tmp, webkit_dom_node_get_first_child (clone), NULL);
-
- prev_parent = parent;
- tmp = webkit_dom_node_get_next_sibling (parent);
- parent = webkit_dom_node_get_parent_node (parent);
- if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
- first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
- insert_before = webkit_dom_node_get_first_child (first_child);
- while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child))) {
- webkit_dom_node_insert_before (
- first_child, sibling, insert_before, NULL);
- }
- }
- }
-
- tmp = webkit_dom_node_insert_before (
- parent,
- webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment)),
- webkit_dom_node_get_next_sibling (prev_parent),
- NULL);
- remove_node_if_empty (prev_parent);
-
- return tmp;
-}
-
static void
remove_node_and_parents_if_empty (WebKitDOMNode *node)
{
@@ -961,7 +806,7 @@ do_format_change_list_to_block (WebKitDOMDocument *document,
}
if (webkit_dom_node_contains (source_list, WEBKIT_DOM_NODE (selection_end)))
- source_list = split_list_into_two (document, item);
+ source_list = split_list_into_two (item);
else {
source_list = webkit_dom_node_get_next_sibling (source_list);
}
@@ -1120,88 +965,6 @@ dom_get_alignment_from_node (WebKitDOMNode *node)
return alignment;
}
-WebKitDOMElement *
-dom_create_selection_marker (WebKitDOMDocument *document,
- gboolean selection_start_marker)
-{
- WebKitDOMElement *element;
-
- element = webkit_dom_document_create_element (
- document, "SPAN", NULL);
- webkit_dom_element_set_id (
- element,
- selection_start_marker ?
- "-x-evo-selection-start-marker" :
- "-x-evo-selection-end-marker");
-
- return element;
-}
-
-void
-dom_remove_selection_markers (WebKitDOMDocument *document)
-{
- WebKitDOMElement *marker;
-
- marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-start-marker");
- if (marker)
- remove_node (WEBKIT_DOM_NODE (marker));
- marker = webkit_dom_document_get_element_by_id (
- document, "-x-evo-selection-end-marker");
- if (marker)
- remove_node (WEBKIT_DOM_NODE (marker));
-}
-
-void
-dom_add_selection_markers_into_element_start (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker)
-{
- WebKitDOMElement *marker;
-
- dom_remove_selection_markers (document);
- marker = dom_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 = dom_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;
-}
-
-void
-dom_add_selection_markers_into_element_end (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker)
-{
- WebKitDOMElement *marker;
-
- dom_remove_selection_markers (document);
- marker = dom_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 = dom_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;
-}
-
/**
* e_html_editor_selection_indent:
* @selection: an #EHTMLEditorSelection
diff --git a/web-extensions/composer/e-html-editor-selection-dom-functions.h
b/web-extensions/composer/e-html-editor-selection-dom-functions.h
index e668e4a..c4cb183 100644
--- a/web-extensions/composer/e-html-editor-selection-dom-functions.h
+++ b/web-extensions/composer/e-html-editor-selection-dom-functions.h
@@ -82,9 +82,6 @@ void dom_create_link (WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension,
const gchar *uri);
-EHTMLEditorSelectionBlockFormat
- dom_get_list_format_from_node (WebKitDOMNode *node);
-
void dom_selection_indent (WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension);
@@ -112,22 +109,6 @@ void dom_set_paragraph_style (WebKitDOMDocument *document,
const gchar *style_to_add);
WebKitDOMElement *
- dom_create_selection_marker (WebKitDOMDocument *document,
- gboolean selection_start_marker);
-
-void dom_add_selection_markers_into_element_start
- (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker);
-
-void dom_add_selection_markers_into_element_end
- (WebKitDOMDocument *document,
- WebKitDOMElement *element,
- WebKitDOMElement **selection_start_marker,
- WebKitDOMElement **selection_end_marker);
-
-WebKitDOMElement *
dom_get_paragraph_element (WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension,
gint width,
@@ -285,7 +266,6 @@ void dom_selection_get_coordinates (WebKitDOMDocument *document,
guint *start_y,
guint *end_x,
guint *end_y);
-void dom_remove_selection_markers (WebKitDOMDocument *document);
gboolean dom_is_selection_position_node (WebKitDOMNode *node);
G_END_DECLS
diff --git a/web-extensions/composer/e-html-editor-undo-redo-manager.c
b/web-extensions/composer/e-html-editor-undo-redo-manager.c
index 74191ad..7732e83 100644
--- a/web-extensions/composer/e-html-editor-undo-redo-manager.c
+++ b/web-extensions/composer/e-html-editor-undo-redo-manager.c
@@ -420,7 +420,7 @@ undo_delete (WebKitDOMDocument *document,
/* Redoing Return key press */
if (empty) {
- WebKitDOMNode *node;
+ WebKitDOMNode *node, *tmp_node;
range = get_range_for_point (document, event->before.start);
webkit_dom_dom_selection_remove_all_ranges (dom_selection);
@@ -432,7 +432,17 @@ undo_delete (WebKitDOMDocument *document,
if (!node)
return;
- element = get_parent_block_element (node);
+ tmp_node = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (event->data.fragment));
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (tmp_node) &&
+ WEBKIT_DOM_IS_HTML_BR_ELEMENT (webkit_dom_node_get_last_child (tmp_node)))
+ if (return_pressed_in_empty_list_item (document, extension, FALSE))
+ return;
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (webkit_dom_node_get_parent_node (node)))
+ element = webkit_dom_node_get_parent_element (node);
+ else
+ element = get_parent_block_element (node);
+
webkit_dom_node_insert_before (
webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (element)),
fragment,
@@ -1519,6 +1529,39 @@ undo_redo_remove_link (WebKitDOMDocument *document,
}
static void
+undo_return_in_empty_list_item (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
+ EHTMLEditorHistoryEvent *event)
+{
+ WebKitDOMElement *selection_start_marker;
+ WebKitDOMNode *parent;
+
+ dom_selection_save (document);
+
+ selection_start_marker = webkit_dom_document_get_element_by_id (document,
"-x-evo-selection-start-marker");
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (selection_start_marker));
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (parent)) {
+ WebKitDOMNode *parent_list;
+
+ dom_remove_selection_markers (document);
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (parent),
+ webkit_dom_node_clone_node (WEBKIT_DOM_NODE (event->data.fragment), TRUE),
+ webkit_dom_node_get_next_sibling (parent),
+ NULL);
+
+ parent_list = parent;
+ while (node_is_list_or_item (webkit_dom_node_get_parent_node (parent_list)))
+ parent_list = webkit_dom_node_get_parent_node (parent_list);
+
+ merge_lists_if_possible (parent_list);
+ }
+
+ dom_selection_restore (document);
+}
+
+static void
undo_input (EHTMLEditorUndoRedoManager *manager,
WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension,
@@ -1527,7 +1570,7 @@ undo_input (EHTMLEditorUndoRedoManager *manager,
gboolean remove_anchor;
WebKitDOMDOMWindow *dom_window;
WebKitDOMDOMSelection *dom_selection;
- WebKitDOMNode *node;
+ WebKitDOMNode *node, *tmp_node;
dom_window = webkit_dom_document_get_default_view (document);
dom_selection = webkit_dom_dom_window_get_selection (dom_window);
@@ -1570,6 +1613,11 @@ undo_input (EHTMLEditorUndoRedoManager *manager,
remove_node (node);
}
+ tmp_node = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (event->data.fragment));
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (tmp_node) &&
+ WEBKIT_DOM_IS_HTML_BR_ELEMENT (webkit_dom_node_get_last_child (tmp_node)))
+ undo_return_in_empty_list_item (document, extension, event);
+
g_object_unref (dom_window);
g_object_unref (dom_selection);
}
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.c
b/web-extensions/composer/e-html-editor-view-dom-functions.c
index cee32e8..ba51f40 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.c
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.c
@@ -5785,8 +5785,7 @@ process_list_to_plain_text (EHTMLEditorWebExtension *extension,
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)) {
+ } else if (node_is_list (item)) {
process_list_to_plain_text (
extension, WEBKIT_DOM_ELEMENT (item), level + 1, output);
item = webkit_dom_node_get_next_sibling (item);
@@ -6023,8 +6022,7 @@ process_elements (EHTMLEditorWebExtension *extension,
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 (node_is_list (child)) {
if (to_plain_text) {
if (changing_mode) {
content = webkit_dom_element_get_outer_html (
@@ -6413,9 +6411,7 @@ toggle_paragraphs_style_in_element (WebKitDOMDocument *document,
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 (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent) &&
- (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
- WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node))) {
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent) && node_is_list (node)) {
gint offset;
offset = WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node) ?
@@ -6719,8 +6715,7 @@ dom_process_content_for_plain_text (WebKitDOMDocument *document,
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)) {
+ if (node_is_list (paragraph)) {
WebKitDOMNode *item = webkit_dom_node_get_first_child (paragraph);
while (item) {
@@ -8188,6 +8183,103 @@ insert_tabulator (WebKitDOMDocument *document,
}
gboolean
+return_pressed_in_empty_list_item (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
+ gboolean save_history)
+{
+ WebKitDOMElement *selection_start_marker, *selection_end_marker;
+ WebKitDOMNode *parent, *node;
+
+ if (!dom_selection_is_collapsed (document))
+ return FALSE;
+
+ dom_selection_save (document);
+
+ 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");
+
+ parent = webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (selection_start_marker));
+ if (!WEBKIT_DOM_IS_HTML_LI_ELEMENT (parent)) {
+ dom_selection_restore (document);
+ return FALSE;
+ }
+
+ node = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (selection_end_marker));
+ /* Check if return was pressed inside an empty list item. */
+ if (!webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (selection_start_marker)) &&
+ (!node || (node && WEBKIT_DOM_IS_HTML_BR_ELEMENT (node) && !webkit_dom_node_get_next_sibling
(node)))) {
+ EHTMLEditorHistoryEvent *ev;
+ WebKitDOMDocumentFragment *fragment;
+ WebKitDOMElement *paragraph;
+ WebKitDOMNode *list;
+
+ if (save_history) {
+ /* Insert new history event for Return to have the right coordinates.
+ * The fragment will be added later. */
+ ev = g_new0 (EHTMLEditorHistoryEvent, 1);
+ ev->type = HISTORY_INPUT;
+
+ dom_selection_get_coordinates (
+ document,
+ &ev->before.start.x,
+ &ev->before.start.y,
+ &ev->before.end.x,
+ &ev->before.end.y);
+
+ fragment = webkit_dom_document_create_document_fragment (document);
+ }
+
+ list = split_list_into_two (parent);
+
+ if (save_history) {
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (fragment),
+ parent,
+ NULL);
+ } else {
+ remove_node (parent);
+ }
+
+ paragraph = dom_prepare_paragraph (document, extension, TRUE);
+
+ webkit_dom_node_insert_before (
+ webkit_dom_node_get_parent_node (list),
+ WEBKIT_DOM_NODE (paragraph),
+ list,
+ NULL);
+
+ dom_selection_restore (document);
+
+ if (save_history) {
+ EHTMLEditorUndoRedoManager *manager;
+
+ dom_selection_get_coordinates (
+ document,
+ &ev->after.start.x,
+ &ev->after.start.y,
+ &ev->after.end.x,
+ &ev->after.end.y);
+
+ ev->data.fragment = fragment;
+
+ manager = e_html_editor_web_extension_get_undo_redo_manager (extension);
+
+ e_html_editor_undo_redo_manager_insert_history_event (manager, ev);
+ }
+
+ e_html_editor_web_extension_set_content_changed (extension);
+
+ return TRUE;
+ }
+
+ dom_selection_restore (document);
+
+ return FALSE;
+}
+
+gboolean
dom_process_on_key_press (WebKitDOMDocument *document,
EHTMLEditorWebExtension *extension,
guint key_val,
@@ -8243,6 +8335,11 @@ dom_process_on_key_press (WebKitDOMDocument *document,
dom_remove_input_event_listener_from_body (document, extension);
return split_citation (document, extension);
}
+
+ /* If the ENTER key is pressed inside an empty list item then the list
+ * is broken into two and empty paragraph is inserted between lists. */
+ if (return_pressed_in_empty_list_item (document, extension, TRUE))
+ return TRUE;
}
if (key_val == GDK_KEY_BackSpace) {
diff --git a/web-extensions/composer/e-html-editor-view-dom-functions.h
b/web-extensions/composer/e-html-editor-view-dom-functions.h
index 81242f4..9b4ec4d 100644
--- a/web-extensions/composer/e-html-editor-view-dom-functions.h
+++ b/web-extensions/composer/e-html-editor-view-dom-functions.h
@@ -173,6 +173,10 @@ gboolean dom_fix_structure_after_delete_before_quoted_content
void dom_disable_quote_marks_select (WebKitDOMDocument *document);
void dom_remove_node_and_parents_if_empty
(WebKitDOMNode *node);
+gboolean return_pressed_in_empty_list_item
+ (WebKitDOMDocument *document,
+ EHTMLEditorWebExtension *extension,
+ gboolean save_history);
G_END_DECLS
diff --git a/web-extensions/e-dom-utils.c b/web-extensions/e-dom-utils.c
index dd245e6..627c99d 100644
--- a/web-extensions/e-dom-utils.c
+++ b/web-extensions/e-dom-utils.c
@@ -1622,6 +1622,257 @@ remove_node_if_empty (WebKitDOMNode *node)
}
}
+WebKitDOMNode *
+split_list_into_two (WebKitDOMNode *item)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDocumentFragment *fragment;
+ WebKitDOMNode *parent, *prev_parent, *tmp;
+
+ document = webkit_dom_node_get_owner_document (item);
+ fragment = webkit_dom_document_create_document_fragment (document);
+
+ tmp = item;
+ parent = webkit_dom_node_get_parent_node (item);
+ while (!WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ WebKitDOMNode *clone, *first_child, *insert_before = NULL, *sibling;
+
+ first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
+ clone = webkit_dom_node_clone_node (parent, FALSE);
+ webkit_dom_node_insert_before (
+ WEBKIT_DOM_NODE (fragment), clone, first_child, NULL);
+
+ if (first_child)
+ insert_before = webkit_dom_node_get_first_child (first_child);
+
+ while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child)))
+ webkit_dom_node_insert_before (first_child, sibling, insert_before, NULL);
+
+ while ((sibling = webkit_dom_node_get_next_sibling (tmp)))
+ webkit_dom_node_append_child (clone, sibling, NULL);
+
+ webkit_dom_node_insert_before (
+ clone, tmp, webkit_dom_node_get_first_child (clone), NULL);
+
+ prev_parent = parent;
+ tmp = webkit_dom_node_get_next_sibling (parent);
+ parent = webkit_dom_node_get_parent_node (parent);
+ if (WEBKIT_DOM_IS_HTML_BODY_ELEMENT (parent)) {
+ first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment));
+ insert_before = webkit_dom_node_get_first_child (first_child);
+ while (first_child && (sibling = webkit_dom_node_get_next_sibling (first_child))) {
+ webkit_dom_node_insert_before (
+ first_child, sibling, insert_before, NULL);
+ }
+ }
+ }
+
+ tmp = webkit_dom_node_insert_before (
+ parent,
+ webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (fragment)),
+ webkit_dom_node_get_next_sibling (prev_parent),
+ NULL);
+ remove_node_if_empty (prev_parent);
+
+ return tmp;
+}
+
+WebKitDOMElement *
+dom_create_selection_marker (WebKitDOMDocument *document,
+ gboolean selection_start_marker)
+{
+ WebKitDOMElement *element;
+
+ element = webkit_dom_document_create_element (
+ document, "SPAN", NULL);
+ webkit_dom_element_set_id (
+ element,
+ selection_start_marker ?
+ "-x-evo-selection-start-marker" :
+ "-x-evo-selection-end-marker");
+
+ return element;
+}
+
+void
+dom_remove_selection_markers (WebKitDOMDocument *document)
+{
+ WebKitDOMElement *marker;
+
+ marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-start-marker");
+ if (marker)
+ remove_node (WEBKIT_DOM_NODE (marker));
+ marker = webkit_dom_document_get_element_by_id (
+ document, "-x-evo-selection-end-marker");
+ if (marker)
+ remove_node (WEBKIT_DOM_NODE (marker));
+}
+
+void
+dom_add_selection_markers_into_element_start (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ dom_remove_selection_markers (document);
+ marker = dom_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 = dom_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;
+}
+
+void
+dom_add_selection_markers_into_element_end (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker)
+{
+ WebKitDOMElement *marker;
+
+ dom_remove_selection_markers (document);
+ marker = dom_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 = dom_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;
+}
+
+gboolean
+node_is_list_or_item (WebKitDOMNode *node)
+{
+ return node && (
+ WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_LI_ELEMENT (node));
+}
+
+gboolean
+node_is_list (WebKitDOMNode *node)
+{
+ return node && (
+ WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node) ||
+ WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node));
+}
+
+/**
+ * e_html_editor_selection_get_list_format_from_node:
+ * @node: an #WebKitDOMNode
+ *
+ * Returns block format of given list.
+ *
+ * Returns: #EHTMLEditorSelectionBlockFormat
+ */
+EHTMLEditorSelectionBlockFormat
+dom_get_list_format_from_node (WebKitDOMNode *node)
+{
+ EHTMLEditorSelectionBlockFormat format =
+ E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST;
+
+ if (WEBKIT_DOM_IS_HTML_LI_ELEMENT (node))
+ return -1;
+
+ if (WEBKIT_DOM_IS_HTML_U_LIST_ELEMENT (node))
+ return format;
+
+ if (WEBKIT_DOM_IS_HTML_O_LIST_ELEMENT (node)) {
+ gchar *type_value = webkit_dom_element_get_attribute (
+ WEBKIT_DOM_ELEMENT (node), "type");
+
+ if (!type_value)
+ return E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
+
+ if (!*type_value)
+ format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST;
+ else if (g_ascii_strcasecmp (type_value, "A") == 0)
+ format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA;
+ else if (g_ascii_strcasecmp (type_value, "I") == 0)
+ format = E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN;
+ g_free (type_value);
+
+ return format;
+ }
+
+ return -1;
+}
+
+void
+merge_list_into_list (WebKitDOMNode *from,
+ WebKitDOMNode *to,
+ gboolean insert_before)
+{
+ WebKitDOMNode *item, *insert_before_node;
+
+ if (!(to && from))
+ return;
+
+ insert_before_node = webkit_dom_node_get_first_child (to);
+ while ((item = webkit_dom_node_get_first_child (from)) != NULL) {
+ if (insert_before)
+ webkit_dom_node_insert_before (
+ to, item, insert_before_node, NULL);
+ else
+ webkit_dom_node_append_child (to, item, NULL);
+ }
+
+ if (!webkit_dom_node_has_child_nodes (from))
+ remove_node (from);
+
+}
+
+void
+merge_lists_if_possible (WebKitDOMNode *list)
+{
+ EHTMLEditorSelectionBlockFormat format, prev, next;
+ gint ii, length;
+ WebKitDOMNode *prev_sibling, *next_sibling;
+ WebKitDOMNodeList *lists;
+
+ prev_sibling = webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (list));
+ next_sibling = webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (list));
+
+ format = dom_get_list_format_from_node (list),
+ prev = dom_get_list_format_from_node (prev_sibling);
+ next = dom_get_list_format_from_node (next_sibling);
+
+ if (format == prev && format != -1 && prev != -1)
+ merge_list_into_list (prev_sibling, list, TRUE);
+
+ if (format == next && format != -1 && next != -1)
+ merge_list_into_list (next_sibling, list, FALSE);
+
+ lists = webkit_dom_element_query_selector_all (
+ WEBKIT_DOM_ELEMENT (list), "ol + ol, ul + ul", NULL);
+ length = webkit_dom_node_list_get_length (lists);
+ for (ii = 0; ii < length; ii++) {
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (lists, ii);
+ merge_lists_if_possible (node);
+ }
+}
+
WebKitDOMElement *
get_parent_block_element (WebKitDOMNode *node)
{
diff --git a/web-extensions/e-dom-utils.h b/web-extensions/e-dom-utils.h
index 94b0140..45fd5cb 100644
--- a/web-extensions/e-dom-utils.h
+++ b/web-extensions/e-dom-utils.h
@@ -19,6 +19,8 @@
#ifndef E_DOM_UTILS_H
#define E_DOM_UTILS_H
+#include <e-util/e-util-enums.h>
+
#include <webkitdom/webkitdom.h>
#include <gtk/gtk.h>
@@ -122,6 +124,38 @@ void element_remove_class (WebKitDOMElement *element,
const gchar* class);
void remove_node (WebKitDOMNode *node);
void remove_node_if_empty (WebKitDOMNode *node);
+WebKitDOMNode * split_list_into_two (WebKitDOMNode *item);
+
+WebKitDOMElement *
+ dom_create_selection_marker (WebKitDOMDocument *document,
+ gboolean start);
+
+void dom_add_selection_markers_into_element_start
+ (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker);
+
+void dom_add_selection_markers_into_element_end
+ (WebKitDOMDocument *document,
+ WebKitDOMElement *element,
+ WebKitDOMElement **selection_start_marker,
+ WebKitDOMElement **selection_end_marker);
+
+void dom_remove_selection_markers (WebKitDOMDocument *document);
+
+gboolean node_is_list (WebKitDOMNode *node);
+
+gboolean node_is_list_or_item (WebKitDOMNode *node);
+
+EHTMLEditorSelectionBlockFormat
+ dom_get_list_format_from_node (WebKitDOMNode *node);
+
+void merge_list_into_list (WebKitDOMNode *from,
+ WebKitDOMNode *to,
+ gboolean insert_before);
+
+void merge_lists_if_possible (WebKitDOMNode *list);
WebKitDOMElement *
get_parent_block_element (WebKitDOMNode *node);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]