static gboolean get_has_style (EEditorSelection *selection, const gchar *style_tag) { WebKitDOMNode *node; WebKitDOMElement *element; WebKitDOMRange *range; gboolean result; gint tag_len; range = editor_selection_get_current_range (selection); if (!range) return FALSE; node = webkit_dom_range_get_start_container (range, NULL); if (!WEBKIT_DOM_IS_ELEMENT (node)) element = webkit_dom_node_get_parent_element (node); else element = WEBKIT_DOM_ELEMENT (node); tag_len = strlen (style_tag); result = FALSE; while (!result && element) { gchar *element_tag; element_tag = webkit_dom_element_get_tag_name (element); result = ((tag_len == strlen (element_tag)) && (g_ascii_strncasecmp (element_tag, style_tag, tag_len) == 0)); /* Special case: <blockquote type=cite> marks quotation, while * just <blockquote> is used for indentation. If the <blockquote> * has type=cite, then ignore it */ if (result && g_ascii_strncasecmp (element_tag, "blockquote", 10) == 0) { if (webkit_dom_element_has_attribute (element, "type")) { gchar *type; type = webkit_dom_element_get_attribute ( element, "type"); if (g_ascii_strncasecmp (type, "cite", 4) == 0) { result = FALSE; } g_free (type); } } g_free (element_tag); if (result) { break; } element = webkit_dom_node_get_parent_element ( WEBKIT_DOM_NODE (element)); } return result; }
static CString dumpRange(WebKitDOMRange* range) { if (!range) return "(null)"; GOwnPtr<gchar> dump(g_strdup_printf("range from %li of %s to %li of %s", webkit_dom_range_get_start_offset(range, 0), dumpNodePath(webkit_dom_range_get_start_container(range, 0)).data(), webkit_dom_range_get_end_offset(range, 0), dumpNodePath(webkit_dom_range_get_end_container(range, 0)).data())); return dump.get(); }
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_set_block_format (EEditorSelection *selection, EEditorSelectionBlockFormat format) { EEditorSelectionBlockFormat current_format; WebKitDOMDocument *document; const gchar *command; const gchar *value; g_return_if_fail (E_IS_EDITOR_SELECTION (selection)); current_format = e_editor_selection_get_block_format (selection); if (current_format == format) { return; } document = webkit_web_view_get_dom_document (selection->priv->webview); switch (format) { case E_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE: command = "formatBlock"; value = "BLOCKQUOTE"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H1: command = "formatBlock"; value = "H1"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H2: command = "formatBlock"; value = "H2"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H3: command = "formatBlock"; value = "H3"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H4: command = "formatBlock"; value = "H4"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H5: command = "formatBlock"; value = "H5"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_H6: command = "formatBlock"; value = "H6"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH: command = "formatBlock"; value = "P"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_PRE: command = "formatBlock"; value = "PRE"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS: command = "formatBlock"; value = "ADDRESS"; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST: case E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA: case E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN: command = "insertOrderedList"; value = ""; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST: command = "insertUnorderedList"; value = ""; break; case E_EDITOR_SELECTION_BLOCK_FORMAT_NONE: default: command = "removeFormat"; value = ""; break; } /* First remove (un)ordered list before changing formatting */ if (current_format == E_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST) { webkit_dom_document_exec_command ( document, "insertUnorderedList", FALSE, ""); /* ^-- not a typo, "insert" toggles the formatting * if already present */ } else if (current_format >= E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST) { webkit_dom_document_exec_command ( document, "insertOrderedList", FALSE ,""); } webkit_dom_document_exec_command ( document, command, FALSE, value); /* Fine tuning - set the specific marker type for ordered lists */ if ((format == E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA) || (format == E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN)) { WebKitDOMRange *range = editor_selection_get_current_range (selection); WebKitDOMNode *node; WebKitDOMElement *list; node = webkit_dom_range_get_start_container (range, NULL); list = e_editor_dom_node_find_child_element (node, "OL"); if (!list) { list = e_editor_dom_node_find_parent_element (node, "OL"); } if (list) { webkit_dom_element_set_attribute ( list, "type", (format == E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA) ? "A" : "I", NULL); } } g_object_notify (G_OBJECT (selection), "block-format"); }
EEditorSelectionBlockFormat e_editor_selection_get_block_format (EEditorSelection *selection) { WebKitDOMNode *node; WebKitDOMRange *range; WebKitDOMElement *element; EEditorSelectionBlockFormat result; g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH); range = editor_selection_get_current_range (selection); if (!range) { return E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH; } node = webkit_dom_range_get_start_container (range, NULL); if (e_editor_dom_node_find_parent_element (node, "UL")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST; } else if ((element = e_editor_dom_node_find_parent_element (node, "OL")) != NULL) { if (webkit_dom_element_has_attribute (element, "type")) { gchar *type; type = webkit_dom_element_get_attribute(element, "type"); if (type && ((*type == 'a') || (*type == 'A'))) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA; } else if (type && ((*type == 'i') || (*type == 'I'))) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN; } else { result = E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST; } g_free (type); } else { result = E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST; } } else if (e_editor_dom_node_find_parent_element (node, "BLOCKQUOTE")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE; } else if (e_editor_dom_node_find_parent_element (node, "PRE")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_PRE; } else if (e_editor_dom_node_find_parent_element (node, "ADDRESS")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS; } else if (e_editor_dom_node_find_parent_element (node, "H1")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H1; } else if (e_editor_dom_node_find_parent_element (node, "H2")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H2; } else if (e_editor_dom_node_find_parent_element (node, "H3")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H3; } else if (e_editor_dom_node_find_parent_element (node, "H4")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H4; } else if (e_editor_dom_node_find_parent_element (node, "H5")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H5; } else if (e_editor_dom_node_find_parent_element (node, "H6")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_H6; } else if (e_editor_dom_node_find_parent_element (node, "P")) { result = E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH; } else { result = E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH; } return result; }
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)); }