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();
}
Beispiel #5
0
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++;
}
Beispiel #6
0
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);
}