static void html_editor_image_dialog_set_url (EHTMLEditorImageDialog *dialog) { WebKitDOMElement *link; const gchar *url; url = gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit)); link = e_html_editor_dom_node_find_parent_element ( WEBKIT_DOM_NODE (dialog->priv->image), "A"); if (link) { if (!url || !*url) { webkit_dom_node_insert_before ( webkit_dom_node_get_parent_node ( WEBKIT_DOM_NODE (link)), WEBKIT_DOM_NODE (dialog->priv->image), WEBKIT_DOM_NODE (link), NULL); webkit_dom_node_remove_child ( webkit_dom_node_get_parent_node ( WEBKIT_DOM_NODE (link)), WEBKIT_DOM_NODE (link), NULL); } else { webkit_dom_html_anchor_element_set_href ( WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link), url); } } else { if (url && *url) { WebKitDOMDocument *document; document = webkit_dom_node_get_owner_document ( WEBKIT_DOM_NODE (dialog->priv->image)); link = webkit_dom_document_create_element ( document, "A", NULL); webkit_dom_html_anchor_element_set_href ( WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link), url); webkit_dom_node_insert_before ( webkit_dom_node_get_parent_node ( WEBKIT_DOM_NODE (dialog->priv->image)), WEBKIT_DOM_NODE (link), WEBKIT_DOM_NODE (dialog->priv->image), NULL); webkit_dom_node_append_child ( WEBKIT_DOM_NODE (link), WEBKIT_DOM_NODE (dialog->priv->image), NULL); } } }
gboolean e_editor_selection_get_superscript (EEditorSelection *selection) { WebKitDOMNode *node; WebKitDOMRange *range; g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE); range = editor_selection_get_current_range (selection); node = webkit_dom_range_get_common_ancestor_container (range, NULL); while (node) { gchar *tag_name; tag_name = webkit_dom_element_get_tag_name (WEBKIT_DOM_ELEMENT (node)); if (g_ascii_strncasecmp (tag_name, "sup", 3) == 0) { g_free (tag_name); break; } g_free (tag_name); node = webkit_dom_node_get_parent_node (node); } return (node != NULL); }
/** * 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; }
static CString dumpNodePath(WebKitDOMNode* node) { GOwnPtr<gchar> nodeName(webkit_dom_node_get_node_name(node)); GString* path = g_string_new(nodeName.get()); WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); while (parent) { GOwnPtr<gchar> parentName(webkit_dom_node_get_node_name(parent)); g_string_append(path, " > "); g_string_append(path, parentName.get()); parent = webkit_dom_node_get_parent_node(parent); } GOwnPtr<gchar> pathBuffer(g_string_free(path, FALSE)); return pathBuffer.get(); }
void plugins_create_click_element(WebKitDOMElement *element, GList *gl) { WebKitDOMNode *parent = webkit_dom_node_get_parent_node(WEBKIT_DOM_NODE(element)); View *v = VIEW(gl); WebKitDOMElement *div; if (parent == NULL) return; WebKitDOMDocument *doc = webkit_dom_node_get_owner_document(WEBKIT_DOM_NODE(element)); WebKitDOMDOMWindow *win = webkit_dom_document_get_default_view(doc); WebKitDOMCSSStyleDeclaration *style = webkit_dom_dom_window_get_computed_style(win, element, ""); char *width = webkit_dom_css_style_declaration_get_property_value(style, "width"); char *height = webkit_dom_css_style_declaration_get_property_value(style, "height"); char *top = webkit_dom_css_style_declaration_get_property_value(style, "top"); char *left = webkit_dom_css_style_declaration_get_property_value(style, "left"); char *position = webkit_dom_css_style_declaration_get_property_value(style, "position"); int w, h; if (sscanf(width, "%dpx", &w) == 1 && w<72) w = 72; if (sscanf(height, "%dpx", &h) == 1 && h<24) h = 24; if (v->plugins->max <= v->plugins->created) { div = webkit_dom_document_create_element(doc, "div", NULL); v->plugins->clicks = g_slist_prepend(v->plugins->clicks, div); v->plugins->max++; } else div = g_slist_nth_data(v->plugins->clicks, v->plugins->created); webkit_dom_html_element_set_inner_html(WEBKIT_DOM_HTML_ELEMENT(div), "<div style='display:table-cell;vertical-align:middle;text-align:center;color:#fff;background:#000;border:1px solid #666;font:11px monospace bold'>click to enable flash</div>", NULL); char *new_style = g_strdup_printf("position:%s;width:%dpx;height:%dpx;top:%s;left:%s;display:table;z-index:37000;", position, w, h, top, left); webkit_dom_element_set_attribute(div, "style", new_style, NULL); g_free(new_style); webkit_dom_element_set_attribute(div, "onclick", "return", NULL); g_object_set_data((gpointer)div, "dwb-plugin-element", element); webkit_dom_node_remove_child(parent, WEBKIT_DOM_NODE(element), NULL); webkit_dom_node_append_child(parent, WEBKIT_DOM_NODE(div), NULL); v->plugins->elements = g_slist_prepend(v->plugins->elements, element); webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(div), "click", G_CALLBACK(plugins_onclick_cb), true, gl); g_object_unref(style); g_object_unref(parent); v->plugins->created++; }
static void plugins_onclick_cb(WebKitDOMElement *element, WebKitDOMEvent *event, GList *gl) { WebKitDOMElement *e = g_object_get_data((gpointer)element, "dwb-plugin-element"); ALLOWED(gl) = g_slist_append(ALLOWED(gl), e); WebKitDOMNode *parent = webkit_dom_node_get_parent_node(WEBKIT_DOM_NODE(element)); WebKitDOMNode *child = webkit_dom_node_get_first_child(WEBKIT_DOM_NODE(element)); webkit_dom_node_remove_child(WEBKIT_DOM_NODE(parent), child, NULL); webkit_dom_node_remove_child(parent, WEBKIT_DOM_NODE(element), NULL); webkit_dom_node_append_child(parent, WEBKIT_DOM_NODE(e), NULL); g_object_unref(parent); }
static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) { WebKitLoadStatus status = webkit_web_view_get_load_status(webView); TestInfo* info = (TestInfo*)data; if (status == WEBKIT_LOAD_FINISHED) { WebKitHitTestResult* result; guint context; GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); WebKitDOMNode* node; gint x, y; /* Close enough to 0,0 */ event->button.x = 5; event->button.y = 5; result = webkit_web_view_get_hit_test_result(webView, (GdkEventButton*) event); gdk_event_free(event); g_assert(result); g_object_get(result, "context", &context, NULL); g_assert(context & info->flag); g_object_get(result, "inner-node", &node, NULL); g_assert(node); g_assert(WEBKIT_DOM_IS_NODE(node)); g_object_get(result, "x", &x, "y", &y, NULL); g_assert_cmpint(x, ==, 5); g_assert_cmpint(y, ==, 5); /* We can only test these node types at the moment. In the * input case there seems to be an extra layer with a DIV on * top of the input, which gets assigned to the inner-node. * tag */ if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT) g_assert(WEBKIT_DOM_IS_HTML_HTML_ELEMENT(node)); else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) g_assert(WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT(node)); else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { /* The hit test will give us the inner text node, we want * the A tag */ WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); g_assert(WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT(parent)); } g_object_unref(result); g_main_loop_quit(loop); }
WebKitDOMNode * e_html_editor_get_parent_block_node_from_child (WebKitDOMNode *node) { WebKitDOMNode *parent = node; if (!WEBKIT_DOM_IS_ELEMENT (parent) || e_html_editor_node_is_selection_position_node (parent)) parent = webkit_dom_node_get_parent_node (parent); if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-temp-text-wrapper") || element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted") || element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quote-character") || element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-signature") || 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); if (element_has_class (WEBKIT_DOM_ELEMENT (parent), "-x-evo-quoted")) parent = webkit_dom_node_get_parent_node (parent); return parent; }
static gint get_caret_position (EHTMLEditorView *view) { WebKitDOMDocument *document; WebKitDOMDOMWindow *window; WebKitDOMDOMSelection *selection; WebKitDOMRange *range; gint range_count; WebKitDOMNodeList *nodes; gulong ii, length; 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); if (webkit_dom_dom_selection_get_range_count (selection) < 1) return 0; range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL); range_count = 0; nodes = webkit_dom_node_get_child_nodes ( webkit_dom_node_get_parent_node ( webkit_dom_dom_selection_get_anchor_node ( selection))); length = webkit_dom_node_list_get_length (nodes); for (ii = 0; ii < length; ii++) { WebKitDOMNode *node; node = webkit_dom_node_list_item (nodes, ii); if (webkit_dom_node_is_same_node ( node, webkit_dom_dom_selection_get_anchor_node (selection))) { break; } else if (WEBKIT_DOM_IS_TEXT (node)) { gchar *text = webkit_dom_node_get_text_content (node); range_count += strlen (text); g_free (text); } } g_object_unref (nodes); return webkit_dom_range_get_start_offset (range, NULL) + range_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; }
static void html_editor_hrule_dialog_show (GtkWidget *widget) { EHTMLEditorHRuleDialog *dialog; EHTMLEditor *editor; EHTMLEditorSelection *selection; EHTMLEditorView *view; WebKitDOMDocument *document; dialog = E_HTML_EDITOR_HRULE_DIALOG (widget); editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); view = e_html_editor_get_view (editor); selection = e_html_editor_view_get_selection (view); if (!e_html_editor_view_is_undo_redo_in_progress (view)) { EHTMLEditorViewHistoryEvent *ev; ev = g_new0 (EHTMLEditorViewHistoryEvent, 1); ev->type = HISTORY_HRULE_DIALOG; e_html_editor_selection_get_selection_coordinates ( selection, &ev->before.start.x, &ev->before.start.y, &ev->before.end.x, &ev->before.end.y); if (dialog->priv->hr_element) ev->data.dom.from = webkit_dom_node_clone_node ( WEBKIT_DOM_NODE (dialog->priv->hr_element), FALSE); else ev->data.dom.from = NULL; dialog->priv->history_event = ev; } if (!dialog->priv->hr_element) { WebKitDOMElement *selection_start, *parent, *rule; document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); e_html_editor_selection_save (selection); selection_start = webkit_dom_document_get_element_by_id ( document, "-x-evo-selection-start-marker"); parent = get_parent_block_element (WEBKIT_DOM_NODE (selection_start)); rule = webkit_dom_document_create_element (document, "HR", NULL); /* Insert horizontal rule into body below the caret */ webkit_dom_node_insert_before ( webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (parent)), WEBKIT_DOM_NODE (rule), webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (parent)), NULL); e_html_editor_selection_restore (selection); dialog->priv->hr_element = WEBKIT_DOM_HTMLHR_ELEMENT (rule); /* For new rule reset the values to default */ gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->width_edit), 100.0); gtk_combo_box_set_active_id ( GTK_COMBO_BOX (dialog->priv->unit_combo), "units-percent"); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->size_edit), 2.0); gtk_combo_box_set_active_id ( GTK_COMBO_BOX (dialog->priv->alignment_combo), "left"); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (dialog->priv->shaded_check), FALSE); html_editor_hrule_dialog_set_alignment (dialog); html_editor_hrule_dialog_set_size (dialog); html_editor_hrule_dialog_set_alignment (dialog); html_editor_hrule_dialog_set_shading (dialog); e_html_editor_view_set_changed (view, TRUE); } else { html_editor_hrule_dialog_get_alignment (dialog); html_editor_hrule_dialog_get_size (dialog); html_editor_hrule_dialog_get_width (dialog); html_editor_hrule_dialog_get_shading (dialog); } /* Chain up to parent implementation */ GTK_WIDGET_CLASS (e_html_editor_hrule_dialog_parent_class)->show (widget); }
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); }