static void test_dom_node_hierarchy_navigation(DomNodeFixture* fixture, gconstpointer data) { WebKitDOMDocument* document; WebKitDOMHTMLHeadElement* head; WebKitDOMHTMLBodyElement* body; WebKitDOMNodeList* list; WebKitDOMNode* ptr; gulong i, length; document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView)); g_assert(document); g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); head = webkit_dom_document_get_head(document); g_assert(head); g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head)); /* Title, head's child */ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(head))); list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head)); g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); ptr = webkit_dom_node_list_item(list, 0); g_assert(ptr); g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(ptr)); g_object_unref(list); /* Body, Head sibling */ ptr = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head)); g_assert(ptr); body = WEBKIT_DOM_HTML_BODY_ELEMENT(ptr); g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(body)); /* There is no third sibling */ ptr = webkit_dom_node_get_next_sibling(ptr); g_assert(ptr == NULL); /* Body's previous sibling is Head */ ptr = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body)); g_assert(ptr); g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(ptr)); /* Body has 3 children */ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); length = webkit_dom_node_list_get_length(list); g_assert_cmpint(length, ==, 3); /* The three of them are P tags */ for (i = 0; i < length; i++) { ptr = webkit_dom_node_list_item(list, i); g_assert(ptr); g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(ptr)); } /* Go backwards */ for (i = 0; ptr; ptr = webkit_dom_node_get_previous_sibling(ptr), i++) /* Nothing */; g_assert_cmpint(i, ==, 3); g_object_unref(list); }
static void test_dom_node_insertion(DomNodeFixture* fixture, gconstpointer data) { WebKitDOMDocument* document; WebKitDOMHTMLElement* body; WebKitDOMElement* p, *div; WebKitDOMNodeList* list; WebKitDOMNode* node; document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView)); g_assert(document); body = webkit_dom_document_get_body(document); g_assert(body); g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body)); /* Body shouldn't have any children at this point */ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)) == FALSE); /* Insert one P element */ p = webkit_dom_document_create_element(document, "P", NULL); webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), NULL); /* Now it should have one, the same that we inserted */ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); node = webkit_dom_node_list_item(list, 0); g_assert(node); g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); g_object_unref(list); /* Replace the P tag with a DIV tag */ div = webkit_dom_document_create_element(document, "DIV", NULL); webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), NULL); g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1); node = webkit_dom_node_list_item(list, 0); g_assert(node); g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); g_object_unref(list); /* Now remove the tag */ webkit_dom_node_remove_child(WEBKIT_DOM_NODE(body), node, NULL); list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body)); g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 0); g_object_unref(list); /* TODO: insert_before, which does not seem to be working correctly */ }
/** * e_html_editor_dom_node_find_child_element: * @node: Start node * @tagname: Tag name of element to search. * * Recursively searches for first occurrence of element with given @tagname that * is a child of @node. * * Returns: A #WebKitDOMElement with @tagname representing a child of @node or * @NULL when @node has no child with given @tagname. When @node matches @tagname, * then the @node is returned. */ WebKitDOMElement * e_html_editor_dom_node_find_child_element (WebKitDOMNode *node, const gchar *tagname) { WebKitDOMNode *start_node = node; gint taglen = strlen (tagname); do { if (WEBKIT_DOM_IS_ELEMENT (node)) { gchar *node_tagname; node_tagname = webkit_dom_element_get_tag_name ( WEBKIT_DOM_ELEMENT (node)); if (node_tagname && (strlen (node_tagname) == taglen) && (g_ascii_strncasecmp (node_tagname, tagname, taglen) == 0)) { g_free (node_tagname); return WEBKIT_DOM_ELEMENT (node); } g_free (node_tagname); } if (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 { node = webkit_dom_node_get_parent_node (node); } } while (!webkit_dom_node_is_same_node (node, start_node)); return NULL; }
void wgp_util_remove_all_children (WebKitDOMNode* parent) { WebKitDOMNode* node; while (webkit_dom_node_has_child_nodes (parent)) { node = webkit_dom_node_get_first_child (parent); webkit_dom_node_remove_child (parent, node, NULL); } }
static gulong walk_dom (WebKitDOMNode *node) { WebKitDOMNodeList *list; gulong i, length, count; if (! webkit_dom_node_has_child_nodes(node)) { return 1; } list = webkit_dom_node_get_child_nodes(node); length = webkit_dom_node_list_get_length(list); count = 1; for (i = 0; i < length; ++i) { WebKitDOMNode *child_node; child_node = webkit_dom_node_list_item(list, i); count += walk_dom(child_node); } g_object_unref(list); return count; }
gboolean e_editor_selection_has_text (EEditorSelection *selection) { WebKitDOMRange *range; WebKitDOMNode *node; g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE); range = editor_selection_get_current_range (selection); node = webkit_dom_range_get_start_container (range, NULL); if (webkit_dom_node_get_node_type (node) == 3) { return TRUE; } node = webkit_dom_range_get_end_container (range, NULL); if (webkit_dom_node_get_node_type (node) == 3) { return TRUE; } node = WEBKIT_DOM_NODE (webkit_dom_range_clone_contents (range, NULL)); while (node) { if (webkit_dom_node_get_node_type (node) == 3) { return TRUE; } if (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 { node = webkit_dom_node_get_parent_node (node); if (node) { node = webkit_dom_node_get_next_sibling (node); } } } return FALSE; }
void e_editor_selection_wrap_lines (EEditorSelection *selection) { WebKitDOMRange *range; WebKitDOMNode *node, *start_node; WebKitDOMDocument *document; WebKitDOMElement *element; WebKitDOMDocumentFragment *fragment; gint len; gchar *html; g_return_if_fail (E_IS_EDITOR_SELECTION (selection)); document = webkit_web_view_get_dom_document (selection->priv->webview); range = editor_selection_get_current_range (selection); /* Extend the range to include entire nodes */ webkit_dom_range_select_node_contents ( range, webkit_dom_range_get_common_ancestor_container (range, NULL), NULL); /* Copy the selection from DOM, wrap the lines and then paste it back * using the DOM command which will overwrite the selection, and * record it as an undoable action */ fragment = webkit_dom_range_clone_contents (range, NULL); node = WEBKIT_DOM_NODE (fragment); start_node = node; len = 0; while (node) { /* Find nearest text node */ if (webkit_dom_node_get_node_type (node) != 3) { if (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 { if (webkit_dom_node_is_equal_node (node, start_node)) { break; } node = webkit_dom_node_get_parent_node (node); if (node) { node = webkit_dom_node_get_next_sibling (node); } } continue; } /* If length of this node + what we already have is still less * then 71 characters, then just join it and continue to next * node */ if ((webkit_dom_character_data_get_length ( (WebKitDOMCharacterData *) node) + len) < WORD_WRAP_LENGTH) { len += webkit_dom_character_data_get_length ( (WebKitDOMCharacterData *) node); } else { gint offset; /* Find where we can line-break the node so that it * effectively fills the rest of current row */ offset = find_where_to_break_line (node, WORD_WRAP_LENGTH - len); if (offset > 0) { /* Split the node and append <BR> tag to it */ webkit_dom_text_split_text ( (WebKitDOMText *) node, len + offset, NULL); element = webkit_dom_document_create_element ( document, "BR", NULL); /* WebKit throws warning when ref_child is NULL */ if (webkit_dom_node_get_next_sibling (node)) { webkit_dom_node_insert_before ( webkit_dom_node_get_parent_node (node), WEBKIT_DOM_NODE (element), webkit_dom_node_get_next_sibling (node), NULL); } else { webkit_dom_node_append_child ( webkit_dom_node_get_parent_node (node), WEBKIT_DOM_NODE (element), NULL); } len = 0; } } /* Skip to next node */ if (webkit_dom_node_get_next_sibling (node)) { node = webkit_dom_node_get_next_sibling (node); } else { if (webkit_dom_node_is_equal_node (node, start_node)) { break; } node = webkit_dom_node_get_parent_node (node); if (node) { node = webkit_dom_node_get_next_sibling (node); } } } /* Create a wrapper DIV and put the processed content into it */ element = webkit_dom_document_create_element (document, "DIV", NULL); webkit_dom_node_append_child ( WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (start_node), NULL); /* Get HTML code of the processed content */ html = webkit_dom_html_element_get_inner_html ( WEBKIT_DOM_HTML_ELEMENT (element)); /* Overwrite the current selection be the processed content, so that * "UNDO" and "REDO" buttons work as expected */ e_editor_selection_insert_html (selection, html); g_free (html); }