static void composer_move_caret (EMsgComposer *composer) { EHTMLEditor *editor; EHTMLEditorView *view; EHTMLEditorSelection *editor_selection; GSettings *settings; gboolean start_bottom, top_signature; gboolean is_message_from_draft; gboolean is_message_from_edit_as_new; gboolean has_paragraphs_in_body = TRUE; WebKitDOMDocument *document; WebKitDOMElement *element, *signature; WebKitDOMHTMLElement *body; WebKitDOMNodeList *list; /* When there is an option composer-reply-start-bottom set we have * to move the caret between reply and signature. */ settings = e_util_ref_settings ("org.gnome.evolution.mail"); start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom"); g_object_unref (settings); editor = e_msg_composer_get_editor (composer); view = e_html_editor_get_view (editor); editor_selection = e_html_editor_view_get_selection (view); is_message_from_draft = e_html_editor_view_is_message_from_draft (view); is_message_from_edit_as_new = e_html_editor_view_is_message_from_edit_as_new (view); top_signature = use_top_signature (composer) && !is_message_from_edit_as_new && !composer->priv->is_from_new_message; 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-message", "", NULL); /* If editing message as new don't handle with caret */ if (is_message_from_edit_as_new || is_message_from_draft) { if (is_message_from_edit_as_new) webkit_dom_element_set_attribute ( WEBKIT_DOM_ELEMENT (body), "data-edit-as-new", "", NULL); if (is_message_from_edit_as_new && !is_message_from_draft) { element = WEBKIT_DOM_ELEMENT (body); e_html_editor_selection_block_selection_changed (editor_selection); goto move_caret; } else e_html_editor_selection_scroll_to_caret (editor_selection); return; } e_html_editor_selection_block_selection_changed (editor_selection); /* When the new message is written from the beginning - note it into body */ if (composer->priv->is_from_new_message) webkit_dom_element_set_attribute ( WEBKIT_DOM_ELEMENT (body), "data-new-message", "", NULL); list = webkit_dom_document_get_elements_by_class_name (document, "-x-evo-paragraph"); signature = webkit_dom_document_query_selector (document, ".-x-evo-signature-wrapper", NULL); /* Situation when wrapped paragraph is just in signature and not in message body */ if (webkit_dom_node_list_get_length (list) == 1) if (signature && webkit_dom_element_query_selector (signature, ".-x-evo-paragraph", NULL)) has_paragraphs_in_body = FALSE; /* * * Keeping Signatures in the beginning of composer * ------------------------------------------------ * * Purists are gonna blast me for this. * But there are so many people (read Outlook users) who want this. * And Evo is an exchange-client, Outlook-replacement etc. * So Here it goes :( * * -- Sankar * */ if (signature && top_signature) { WebKitDOMElement *spacer; spacer = prepare_top_signature_spacer (editor_selection, document); webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (spacer), webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (signature)), NULL); } if (webkit_dom_node_list_get_length (list) == 0) has_paragraphs_in_body = FALSE; element = webkit_dom_document_get_element_by_id (document, "-x-evo-input-start"); if (!signature) { if (start_bottom) { if (!element) { element = prepare_paragraph (editor_selection, document); webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } } else element = WEBKIT_DOM_ELEMENT (body); g_object_unref (list); goto move_caret; } if (!has_paragraphs_in_body) { element = prepare_paragraph (editor_selection, document); if (top_signature) { if (start_bottom) { webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } else { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } } else { if (start_bottom) webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); else element = WEBKIT_DOM_ELEMENT (body); } } else { if (!element && top_signature) { element = prepare_paragraph (editor_selection, document); if (start_bottom) { webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } else { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } } else if (element && top_signature && !start_bottom) { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } else if (element && start_bottom) { /* Leave it how it is */ } else element = WEBKIT_DOM_ELEMENT (body); } g_object_unref (list); move_caret: if (element) { WebKitDOMDOMSelection *dom_selection; WebKitDOMDOMWindow *dom_window; WebKitDOMRange *range; dom_window = webkit_dom_document_get_default_view (document); dom_selection = webkit_dom_dom_window_get_selection (dom_window); range = webkit_dom_document_create_range (document); webkit_dom_range_select_node_contents ( range, WEBKIT_DOM_NODE (element), NULL); webkit_dom_range_collapse (range, TRUE, NULL); webkit_dom_dom_selection_remove_all_ranges (dom_selection); webkit_dom_dom_selection_add_range (dom_selection, range); g_clear_object (&dom_selection); g_clear_object (&dom_window); g_clear_object (&range); if (start_bottom) e_html_editor_selection_scroll_to_caret (editor_selection); } if (start_bottom) g_signal_connect ( view, "size-allocate", G_CALLBACK (composer_size_allocate_cb), NULL); e_html_editor_view_force_spell_check_in_viewport (view); e_html_editor_selection_unblock_selection_changed (editor_selection); }
void wxWebViewWebKit::ClearSelection() { WebKitDOMDocument* doc; WebKitDOMDOMWindow* win; WebKitDOMDOMSelection* sel; doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view)); win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc)); sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win)); webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel)); }
wxString wxWebViewWebKit::GetSelectedText() const { WebKitDOMDocument* doc; WebKitDOMDOMWindow* win; WebKitDOMDOMSelection* sel; WebKitDOMRange* range; doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view)); win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc)); sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win)); range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel), 0, NULL); return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range)), wxConvUTF8); }
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; }
static WebKitDOMRange * editor_selection_get_current_range (EEditorSelection *selection) { WebKitDOMDocument *document; WebKitDOMDOMWindow *window; WebKitDOMDOMSelection *dom_selection; document = webkit_web_view_get_dom_document (selection->priv->webview); window = webkit_dom_document_get_default_view (document); if (!window) return NULL; dom_selection = webkit_dom_dom_window_get_selection (window); if (webkit_dom_dom_selection_get_range_count (dom_selection) < 1) return NULL; return webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL); }
void e_editor_selection_replace_caret_word (EEditorSelection *selection, const gchar *replacement) { WebKitDOMDocument *document; WebKitDOMDOMWindow *window; WebKitDOMDOMSelection *dom_selection; WebKitDOMRange *range; g_return_if_fail (E_IS_EDITOR_SELECTION (selection)); g_return_if_fail (replacement); range = editor_selection_get_current_range (selection); document = webkit_web_view_get_dom_document (selection->priv->webview); window = webkit_dom_document_get_default_view (document); dom_selection = webkit_dom_dom_window_get_selection (window); webkit_dom_range_expand (range, "word", NULL); webkit_dom_dom_selection_add_range (dom_selection, range); e_editor_selection_insert_html (selection, replacement); }
wxString wxWebViewWebKit::GetSelectedSource() const { WebKitDOMDocument* doc; WebKitDOMDOMWindow* win; WebKitDOMDOMSelection* sel; WebKitDOMRange* range; WebKitDOMElement* div; WebKitDOMDocumentFragment* clone; WebKitDOMHTMLElement* html; doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view)); win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc)); sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win)); range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel), 0, NULL); div = webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc), "div", NULL); clone = webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range), NULL); webkit_dom_node_append_child(&div->parent_instance, &clone->parent_instance, NULL); html = (WebKitDOMHTMLElement*)div; return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html)), wxConvUTF8); }
static void move_caret_after_signature_inserted (EEditorPage *editor_page) { WebKitDOMDocument *document; WebKitDOMElement *element, *signature; WebKitDOMHTMLElement *body; WebKitDOMNodeList *paragraphs = NULL; gboolean top_signature; gboolean start_bottom; gboolean has_paragraphs_in_body = TRUE; g_return_if_fail (E_IS_EDITOR_PAGE (editor_page)); document = e_editor_page_get_document (editor_page); top_signature = use_top_signature (); start_bottom = start_typing_at_bottom (); body = webkit_dom_document_get_body (document); e_editor_page_block_selection_changed (editor_page); paragraphs = webkit_dom_document_query_selector_all (document, "[data-evo-paragraph]", NULL); signature = webkit_dom_document_query_selector (document, ".-x-evo-signature-wrapper", NULL); /* Situation when wrapped paragraph is just in signature and not in message body */ if (webkit_dom_node_list_get_length (paragraphs) == 1) { WebKitDOMNode *node; node = webkit_dom_node_list_item (paragraphs, 0); if (signature && webkit_dom_element_query_selector (signature, "[data-evo-paragraph]", NULL)) has_paragraphs_in_body = FALSE; /* Don't take the credentials into account. */ if (!webkit_dom_node_get_previous_sibling (node) && !element_has_id (WEBKIT_DOM_ELEMENT (node), "-x-evo-input-start")) has_paragraphs_in_body = FALSE; } /* * * Keeping Signatures in the beginning of composer * ------------------------------------------------ * * Purists are gonna blast me for this. * But there are so many people (read Outlook users) who want this. * And Evo is an exchange-client, Outlook-replacement etc. * So Here it goes :( * * -- Sankar * */ if (signature && top_signature) { WebKitDOMElement *spacer; spacer = prepare_top_signature_spacer (editor_page); webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (spacer), webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (signature)), NULL); } if (webkit_dom_node_list_get_length (paragraphs) == 0) has_paragraphs_in_body = FALSE; element = webkit_dom_document_get_element_by_id (document, "-x-evo-input-start"); if (!signature) { if (start_bottom) { if (!element) { element = e_editor_dom_prepare_paragraph (editor_page, FALSE); webkit_dom_element_set_id (element, "-x-evo-input-start"); webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } } else element = WEBKIT_DOM_ELEMENT (body); goto move_caret; } /* When there is an option composer-reply-start-bottom set we have * to move the caret between reply and signature. */ if (!has_paragraphs_in_body) { element = e_editor_dom_prepare_paragraph (editor_page, FALSE); webkit_dom_element_set_id (element, "-x-evo-input-start"); if (top_signature) { if (start_bottom) { webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } else { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } } else { if (start_bottom) webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); else element = WEBKIT_DOM_ELEMENT (body); } } else { if (!element && top_signature) { element = e_editor_dom_prepare_paragraph (editor_page, FALSE); webkit_dom_element_set_id (element, "-x-evo-input-start"); if (start_bottom) { webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } else { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } } else if (element && top_signature && !start_bottom) { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), WEBKIT_DOM_NODE (signature), NULL); } else if (element && start_bottom) { /* Leave it how it is */ } else element = WEBKIT_DOM_ELEMENT (body); } move_caret: if (element) { WebKitDOMDOMSelection *dom_selection = NULL; WebKitDOMDOMWindow *dom_window = NULL; WebKitDOMRange *range = NULL; dom_window = webkit_dom_document_get_default_view (document); dom_selection = webkit_dom_dom_window_get_selection (dom_window); range = webkit_dom_document_create_range (document); webkit_dom_range_select_node_contents ( range, WEBKIT_DOM_NODE (element), NULL); webkit_dom_range_collapse (range, TRUE, NULL); webkit_dom_dom_selection_remove_all_ranges (dom_selection); webkit_dom_dom_selection_add_range (dom_selection, range); g_clear_object (&dom_selection); g_clear_object (&dom_window); g_clear_object (&range); } if (start_bottom) e_editor_dom_scroll_to_caret (editor_page); g_clear_object (¶graphs); e_editor_dom_force_spell_check_in_viewport (editor_page); e_editor_page_unblock_selection_changed (editor_page); }
static void html_editor_link_dialog_show (GtkWidget *widget) { EHTMLEditor *editor; EHTMLEditorView *view; EHTMLEditorLinkDialog *dialog; WebKitDOMDocument *document; WebKitDOMDOMWindow *dom_window; WebKitDOMDOMSelection *dom_selection; WebKitDOMRange *range; WebKitDOMElement *link; dialog = E_HTML_EDITOR_LINK_DIALOG (widget); editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); view = e_html_editor_get_view (editor); document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); dom_window = webkit_dom_document_get_default_view (document); dom_selection = webkit_dom_dom_window_get_selection (dom_window); g_object_unref (dom_window); /* Reset to default values */ gtk_entry_set_text (GTK_ENTRY (dialog->priv->url_edit), "http://"); gtk_entry_set_text (GTK_ENTRY (dialog->priv->label_edit), ""); gtk_widget_set_sensitive (dialog->priv->label_edit, TRUE); gtk_widget_set_sensitive (dialog->priv->remove_link_button, TRUE); dialog->priv->label_autofill = TRUE; /* No selection at all */ if (!dom_selection || webkit_dom_dom_selection_get_range_count (dom_selection) < 1) { gtk_widget_set_sensitive (dialog->priv->remove_link_button, FALSE); goto chainup; } range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL); link = e_html_editor_dom_node_find_parent_element ( webkit_dom_range_get_start_container (range, NULL), "A"); if (!link) { if ((webkit_dom_range_get_start_container (range, NULL) != webkit_dom_range_get_end_container (range, NULL)) || (webkit_dom_range_get_start_offset (range, NULL) != webkit_dom_range_get_end_offset (range, NULL))) { WebKitDOMDocumentFragment *fragment; fragment = webkit_dom_range_clone_contents (range, NULL); link = e_html_editor_dom_node_find_child_element ( WEBKIT_DOM_NODE (fragment), "A"); } else { WebKitDOMNode *node; node = webkit_dom_range_get_common_ancestor_container (range, NULL); if (node && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) { link = e_html_editor_dom_node_find_parent_element (node, "A"); if (link && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (link)) link = NULL; } else link = WEBKIT_DOM_ELEMENT (node); } } if (link) { gchar *href, *text; href = webkit_dom_html_anchor_element_get_href ( WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link)); text = webkit_dom_html_element_get_inner_text ( WEBKIT_DOM_HTML_ELEMENT (link)); gtk_entry_set_text ( GTK_ENTRY (dialog->priv->url_edit), href); gtk_entry_set_text ( GTK_ENTRY (dialog->priv->label_edit), text); g_free (text); g_free (href); } else { gchar *text; text = webkit_dom_range_get_text (range); if (text && *text) { gtk_entry_set_text ( GTK_ENTRY (dialog->priv->label_edit), text); gtk_widget_set_sensitive ( dialog->priv->label_edit, FALSE); gtk_widget_set_sensitive ( dialog->priv->remove_link_button, FALSE); } g_free (text); } g_object_unref (range); chainup: g_object_unref (dom_selection); /* Chain up to parent implementation */ GTK_WIDGET_CLASS (e_html_editor_link_dialog_parent_class)->show (widget); }
static void html_editor_link_dialog_ok (EHTMLEditorLinkDialog *dialog) { EHTMLEditor *editor; EHTMLEditorView *view; EHTMLEditorSelection *selection; WebKitDOMDocument *document; WebKitDOMDOMWindow *dom_window; WebKitDOMDOMSelection *dom_selection; WebKitDOMRange *range; WebKitDOMElement *link; 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); document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); dom_window = webkit_dom_document_get_default_view (document); dom_selection = webkit_dom_dom_window_get_selection (dom_window); g_object_unref (dom_window); if (!dom_selection || (webkit_dom_dom_selection_get_range_count (dom_selection) == 0)) { gtk_widget_hide (GTK_WIDGET (dialog)); g_object_unref (dom_selection); return; } range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL); link = e_html_editor_dom_node_find_parent_element ( webkit_dom_range_get_start_container (range, NULL), "A"); if (!link) { if ((webkit_dom_range_get_start_container (range, NULL) != webkit_dom_range_get_end_container (range, NULL)) || (webkit_dom_range_get_start_offset (range, NULL) != webkit_dom_range_get_end_offset (range, NULL))) { WebKitDOMDocumentFragment *fragment; fragment = webkit_dom_range_extract_contents (range, NULL); link = e_html_editor_dom_node_find_child_element ( WEBKIT_DOM_NODE (fragment), "A"); webkit_dom_range_insert_node ( range, WEBKIT_DOM_NODE (fragment), NULL); webkit_dom_dom_selection_set_base_and_extent ( dom_selection, webkit_dom_range_get_start_container (range, NULL), webkit_dom_range_get_start_offset (range, NULL), webkit_dom_range_get_end_container (range, NULL), webkit_dom_range_get_end_offset (range, NULL), NULL); } else { WebKitDOMNode *node; /* get element that was clicked on */ node = webkit_dom_range_get_common_ancestor_container (range, NULL); if (node && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) { link = e_html_editor_dom_node_find_parent_element (node, "A"); if (link && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (link)) link = NULL; } else link = WEBKIT_DOM_ELEMENT (node); } } if (link) { webkit_dom_html_anchor_element_set_href ( WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link), gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit))); webkit_dom_html_element_set_inner_html ( WEBKIT_DOM_HTML_ELEMENT (link), gtk_entry_get_text (GTK_ENTRY (dialog->priv->label_edit)), NULL); } else { gchar *text; /* Check whether a text is selected or not */ text = webkit_dom_range_get_text (range); if (text && *text) { e_html_editor_selection_create_link ( selection, gtk_entry_get_text ( GTK_ENTRY (dialog->priv->url_edit))); } else { gchar *html = g_strdup_printf ( "<a href=\"%s\">%s</a>", gtk_entry_get_text ( GTK_ENTRY (dialog->priv->url_edit)), gtk_entry_get_text ( GTK_ENTRY (dialog->priv->label_edit))); e_html_editor_view_exec_command ( view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html); g_free (html); } g_free (text); } g_object_unref (range); g_object_unref (dom_selection); gtk_widget_hide (GTK_WIDGET (dialog)); }