/** * Indicates if the given dom element is an editable element like text input, * password or textarea. */ gboolean dom_is_editable(Element *element) { gboolean result = false; char *tagname, *type; if (!element) { return result; } tagname = webkit_dom_element_get_tag_name(element); type = webkit_dom_element_get_attribute(element, "type"); /* element is editable if it's a text area or input with no type, text or * pasword */ if (!g_ascii_strcasecmp(tagname, "textarea")) { result = true; } else if (!g_ascii_strcasecmp(tagname, "input") && (!*type || !g_ascii_strcasecmp(type, "text") || !g_ascii_strcasecmp(type, "password")) ) { result = true; } else { result = false; } g_free(tagname); g_free(type); return result; }
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 gboolean plugins_before_load_cb(WebKitDOMDOMWindow *win, WebKitDOMEvent *event, GList *gl) { WebKitDOMElement *element = (void*)webkit_dom_event_get_src_element(event); char *tagname = webkit_dom_element_get_tag_name(element); char *type = webkit_dom_element_get_attribute(element, "type"); if ( (!g_strcmp0(type, "application/x-shockwave-flash") && (! g_ascii_strcasecmp(tagname, "object") || ! g_ascii_strcasecmp(tagname, "embed")) ) && ! g_slist_find(ALLOWED(gl), element) ) { VIEW(gl)->plugins->status |= PLUGIN_STATUS_HAS_PLUGIN; webkit_dom_event_prevent_default(event); webkit_dom_event_stop_propagation(event); plugins_create_click_element(element, gl); } g_object_unref(element); g_free(tagname); g_free(type); return true; }
static void html_editor_image_dialog_show (GtkWidget *widget) { EHTMLEditorImageDialog *dialog; EHTMLEditor *editor; EHTMLEditorSelection *selection; EHTMLEditorView *view; WebKitDOMElement *link; gchar *tmp; glong val; dialog = E_HTML_EDITOR_IMAGE_DIALOG (widget); if (!dialog->priv->image) { return; } 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_IMAGE_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); ev->data.dom.from = webkit_dom_node_clone_node ( WEBKIT_DOM_NODE (dialog->priv->image), FALSE); dialog->priv->history_event = ev; } tmp = webkit_dom_element_get_attribute ( WEBKIT_DOM_ELEMENT (dialog->priv->image), "data-uri"); if (tmp && *tmp) { gtk_file_chooser_set_uri ( GTK_FILE_CHOOSER (dialog->priv->file_chooser), tmp); gtk_widget_set_sensitive ( GTK_WIDGET (dialog->priv->file_chooser), TRUE); } else { gtk_file_chooser_set_uri ( GTK_FILE_CHOOSER (dialog->priv->file_chooser), ""); gtk_widget_set_sensitive ( GTK_WIDGET (dialog->priv->file_chooser), FALSE); } g_free (tmp); tmp = webkit_dom_html_image_element_get_alt (dialog->priv->image); gtk_entry_set_text (GTK_ENTRY (dialog->priv->description_edit), tmp ? tmp : ""); g_free (tmp); val = webkit_dom_html_image_element_get_width (dialog->priv->image); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->width_edit), val); gtk_combo_box_set_active_id ( GTK_COMBO_BOX (dialog->priv->width_units), "units-px"); val = webkit_dom_html_image_element_get_height (dialog->priv->image); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->height_edit), val); gtk_combo_box_set_active_id ( GTK_COMBO_BOX (dialog->priv->height_units), "units-px"); tmp = webkit_dom_html_image_element_get_border (dialog->priv->image); gtk_combo_box_set_active_id ( GTK_COMBO_BOX (dialog->priv->alignment), (tmp && *tmp) ? tmp : "bottom"); g_free (tmp); val = webkit_dom_html_image_element_get_hspace (dialog->priv->image); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->x_padding_edit), val); val = webkit_dom_html_image_element_get_vspace (dialog->priv->image); gtk_spin_button_set_value ( GTK_SPIN_BUTTON (dialog->priv->y_padding_edit), val); link = e_html_editor_dom_node_find_parent_element ( WEBKIT_DOM_NODE (dialog->priv->image), "A"); if (link) { tmp = webkit_dom_html_anchor_element_get_href ( WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link)); gtk_entry_set_text (GTK_ENTRY (dialog->priv->url_edit), tmp); g_free (tmp); } /* Chain up to parent implementation */ GTK_WIDGET_CLASS (e_html_editor_image_dialog_parent_class)->show (widget); }
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 composer_load_signature_cb (EMailSignatureComboBox *combo_box, GAsyncResult *result, EMsgComposer *composer) { GString *html_buffer = NULL; gchar *contents = NULL; gsize length = 0; const gchar *active_id; gboolean top_signature, is_html, html_mode; gboolean start_bottom, is_message_from_edit_as_new; GError *error = NULL; EHTMLEditor *editor; EHTMLEditorView *view; WebKitDOMDocument *document; WebKitDOMElement *element = NULL; WebKitDOMNodeList *signatures; gulong list_length, ii; GSettings *settings; e_mail_signature_combo_box_load_selected_finish ( combo_box, result, &contents, &length, &is_html, &error); /* FIXME Use an EAlert here. */ if (error != NULL) { g_warning ("%s: %s", G_STRFUNC, error->message); g_error_free (error); goto exit; } if (composer->priv->ignore_next_signature_change) { composer->priv->ignore_next_signature_change = FALSE; goto exit; } editor = e_msg_composer_get_editor (composer); view = e_html_editor_get_view (editor); is_message_from_edit_as_new = e_html_editor_view_is_message_from_edit_as_new (view); /* "Edit as New Message" sets is_message_from_edit_as_new. * Always put the signature at the bottom for that case. */ top_signature = use_top_signature (composer) && !is_message_from_edit_as_new && !composer->priv->is_from_new_message; settings = e_util_ref_settings ("org.gnome.evolution.mail"); start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom"); g_object_unref (settings); document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); html_mode = e_html_editor_view_get_html_mode (view); if (contents == NULL) goto insert; /* If inserting HTML signature in plain text composer we have to convert it. */ if (is_html && !html_mode) { WebKitDOMElement *tmp_element; gchar *inner_text; tmp_element = webkit_dom_document_create_element (document, "div", NULL); webkit_dom_html_element_set_inner_html ( WEBKIT_DOM_HTML_ELEMENT (tmp_element), contents, NULL); inner_text = webkit_dom_html_element_get_inner_text ( WEBKIT_DOM_HTML_ELEMENT (tmp_element)); g_free (contents); contents = inner_text ? g_strstrip (inner_text) : g_strdup (""); is_html = FALSE; } if (!is_html) { gchar *html; html = camel_text_to_html (contents, 0, 0); if (html) { g_free (contents); contents = html; length = strlen (contents); } } /* Generate HTML code for the signature. */ html_buffer = g_string_sized_new (1024); /* The combo box active ID is the signature's ESource UID. */ active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)); g_string_append_printf ( html_buffer, "<SPAN class=\"-x-evo-signature\" id=\"1\" name=\"%s\">", (active_id != NULL) ? active_id : ""); if (!is_html) g_string_append (html_buffer, "<PRE>"); /* The signature dash convention ("-- \n") is specified * in the "Son of RFC 1036", section 4.3.2. * http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html */ if (add_signature_delimiter (composer)) { const gchar *delim; const gchar *delim_nl; if (is_html) { delim = "-- <BR>"; delim_nl = "\n-- <BR>"; } else { delim = "-- \n"; delim_nl = "\n-- \n"; } /* Skip the delimiter if the signature already has one. */ if (g_ascii_strncasecmp (contents, delim, strlen (delim)) == 0) ; /* skip */ else if (e_util_strstrcase (contents, delim_nl) != NULL) ; /* skip */ else g_string_append (html_buffer, delim); } g_string_append_len (html_buffer, contents, length); if (!is_html) g_string_append (html_buffer, "</PRE>"); g_string_append (html_buffer, "</SPAN>"); g_free (contents); insert: /* Remove the old signature and insert the new one. */ signatures = webkit_dom_document_get_elements_by_class_name ( document, "-x-evo-signature-wrapper"); list_length = webkit_dom_node_list_get_length (signatures); for (ii = 0; ii < list_length; ii++) { WebKitDOMNode *wrapper, *signature; gchar *id; wrapper = webkit_dom_node_list_item (signatures, ii); signature = webkit_dom_node_get_first_child (wrapper); /* When we are editing a message with signature, we need to unset the * active signature id as if the signature in the message was edited * by the user we would discard these changes. */ if (composer->priv->set_signature_from_message && (is_message_from_edit_as_new || e_html_editor_view_is_message_from_draft (view))) { if (composer->priv->check_if_signature_is_changed) { if (html_buffer && *html_buffer->str) { gchar *body_signature_text, *signature_text; element = webkit_dom_document_create_element (document, "div", NULL); webkit_dom_html_element_set_inner_html ( WEBKIT_DOM_HTML_ELEMENT (element), html_buffer->str, NULL); body_signature_text = webkit_dom_html_element_get_inner_text ( WEBKIT_DOM_HTML_ELEMENT (signature)); signature_text = webkit_dom_html_element_get_inner_text ( WEBKIT_DOM_HTML_ELEMENT (element)); /* Signature in the body is different than the one with the * same id, so set the active signature to None and leave * the signature that is in the body. */ if (g_strcmp0 (body_signature_text, signature_text) != 0) { gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); composer->priv->ignore_next_signature_change = TRUE; } g_free (body_signature_text); g_free (signature_text); } else { gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); composer->priv->ignore_next_signature_change = TRUE; } composer->priv->check_if_signature_is_changed = FALSE; composer->priv->set_signature_from_message = FALSE; } else { gchar *name; /* Load the signature and check if is it the same * as the signature in body or the user previously * changed it. */ name = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (signature), "name"); gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), name); g_free (name); composer->priv->check_if_signature_is_changed = TRUE; } g_object_unref (wrapper); g_object_unref (signatures); g_object_unref (composer); return; } id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (signature)); if (id && (strlen (id) == 1) && (*id == '1')) { /* If the top signature was set we have to remove the NL * that was inserted after it */ if (top_signature) { WebKitDOMElement *spacer; spacer = webkit_dom_document_query_selector ( document, ".-x-evo-top-signature-spacer", NULL); if (spacer) remove_node_if_empty (WEBKIT_DOM_NODE (spacer)); } /* We have to remove the div containing the span with signature */ remove_node (wrapper); g_object_unref (wrapper); g_free (id); break; } g_object_unref (wrapper); g_free (id); } g_object_unref (signatures); if (html_buffer != NULL) { if (*html_buffer->str) { WebKitDOMHTMLElement *body; body = webkit_dom_document_get_body (document); if (!element) { element = webkit_dom_document_create_element (document, "DIV", NULL); webkit_dom_html_element_set_inner_html ( WEBKIT_DOM_HTML_ELEMENT (element), html_buffer->str, NULL); } webkit_dom_element_set_class_name (element, "-x-evo-signature-wrapper"); if (top_signature) { WebKitDOMNode *child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)); if (start_bottom) { webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), child, NULL); } else { /* When we are using signature on top the caret * should be before the signature */ webkit_dom_node_insert_before ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), child, NULL); } } else { webkit_dom_node_append_child ( WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (element), NULL); } } g_string_free (html_buffer, TRUE); } if (is_html && html_mode) e_html_editor_view_fix_file_uri_images (view); composer_move_caret (composer); exit: /* Make sure the flag will be unset and won't influence user's choice */ composer->priv->set_signature_from_message = FALSE; g_object_unref (composer); }