[evolution/webkit: 180/196] Drop ESearchingTokenizer a reimplement highlighting directly in EWebView
- From: Dan VrÃtil <dvratil src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit: 180/196] Drop ESearchingTokenizer a reimplement highlighting directly in EWebView
- Date: Tue, 27 Mar 2012 16:15:51 +0000 (UTC)
commit ef9371618afccc348fa4db63c9f9dd04af997c3b
Author: Dan VrÃtil <dvratil redhat com>
Date: Tue Mar 6 17:04:34 2012 +0100
Drop ESearchingTokenizer a reimplement highlighting directly in EWebView
data/webview.css | 5 +
mail/e-mail-paned-view.c | 24 +-
widgets/misc/Makefile.am | 2 -
widgets/misc/e-search-bar.c | 6 -
widgets/misc/e-searching-tokenizer.c | 1210 ----------------------------------
widgets/misc/e-searching-tokenizer.h | 91 ---
widgets/misc/e-web-view.c | 190 ++++++
widgets/misc/e-web-view.h | 4 +
8 files changed, 209 insertions(+), 1323 deletions(-)
---
diff --git a/data/webview.css b/data/webview.css
index 30a37dc..687d06c 100644
--- a/data/webview.css
+++ b/data/webview.css
@@ -76,6 +76,11 @@ object { /* GtkWidgets */
margin-bottom: 2px;
}
+.__evo-highlight {
+ color: purple;
+ font-weight: bold;
+}
+
/***** PRINTING *******/
.printing-header {
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c
index 0902bbf..4b27b09 100644
--- a/mail/e-mail-paned-view.c
+++ b/mail/e-mail-paned-view.c
@@ -728,27 +728,23 @@ static void
mail_paned_view_set_search_strings (EMailView *view,
GSList *search_strings)
{
-#if 0 /* WEBKIT */
- EPreviewPane *preview_pane;
- ESearchBar *search_bar;
- ESearchingTokenizer *tokenizer;
+ EMailDisplay *display;
+ EWebView *web_view;
+ EMailReader *reader;
reader = E_MAIL_READER (view);
- preview_pane = e_mail_reader_get_preview_pane (reader);
- search_bar = e_preview_pane_get_search_bar (preview_pane);
- tokenizer = e_search_bar_get_tokenizer (search_bar);
+ display = e_mail_reader_get_mail_display (reader);
+ if (!display)
+ return;
+
+ web_view = E_WEB_VIEW (display);
- e_searching_tokenizer_set_secondary_case_sensitivity (tokenizer, FALSE);
- e_searching_tokenizer_set_secondary_search_string (tokenizer, NULL);
+ e_web_view_clear_highlights (web_view);
while (search_strings != NULL) {
- e_searching_tokenizer_add_secondary_search_string (
- tokenizer, search_strings->data);
+ e_web_view_add_highlight (web_view, search_strings->data);
search_strings = g_slist_next (search_strings);
}
-
- e_search_bar_changed (search_bar);
-#endif
}
static GalViewInstance *
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index 35155d1..ab7efa0 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -49,7 +49,6 @@ widgetsinclude_HEADERS = \
e-preview-pane.h \
e-printable.h \
e-search-bar.h \
- e-searching-tokenizer.h \
e-selectable.h \
e-selection-model.h \
e-selection-model-array.h \
@@ -132,7 +131,6 @@ libemiscwidgets_la_SOURCES = \
e-preview-pane.c \
e-printable.c \
e-search-bar.c \
- e-searching-tokenizer.c \
e-selectable.c \
e-selection-model.c \
e-selection-model-array.c \
diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c
index 17a3732..0e39aa1 100644
--- a/widgets/misc/e-search-bar.c
+++ b/widgets/misc/e-search-bar.c
@@ -510,12 +510,6 @@ e_search_bar_init (ESearchBar *search_bar)
search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar);
-#if 0 /* WEBKIT */
- g_signal_connect_swapped (
- search_bar->priv->tokenizer, "match",
- G_CALLBACK (search_bar_update_matches), search_bar);
-#endif
-
gtk_box_set_spacing (GTK_BOX (search_bar), 12);
container = GTK_WIDGET (search_bar);
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 4c766e0..319d6cb 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -58,6 +58,8 @@ struct _EWebViewPrivate {
GHashTable *js_callbacks;
+ GSList *highlights;
+
GtkAction *open_proxy;
GtkAction *print_proxy;
GtkAction *save_as_proxy;
@@ -349,6 +351,135 @@ web_view_menu_item_select_cb (EWebView *web_view,
}
static void
+replace_text (WebKitDOMNode *node,
+ const gchar *text,
+ WebKitDOMNode *replacement)
+{
+ /* NodeType 3 = TEXT_NODE */
+ if (webkit_dom_node_get_node_type (node) == 3) {
+
+ gint text_length = strlen (text);
+
+ while (node) {
+
+ WebKitDOMNode *current_node, *replacement_node;
+ const gchar *node_data, *offset;
+ goffset split_offset;
+ gint data_length;
+
+ current_node = node;
+
+ /* Don't use the WEBKIT_DOM_CHARACTER_DATA macro for
+ * casting. WebKit lies about type of the object and
+ * GLib will throw runtime warning about node not being
+ * WebKitDOMCharacterData, but the function will return
+ * correct and valid data.
+ * IMO it's bug in the Gtk bindings and WebKit internally
+ * handles it by the nodeType so therefor it works
+ * event for "invalid" objects. But really, who knows..?
+ */
+ node_data = webkit_dom_character_data_get_data (
+ (WebKitDOMCharacterData *) node);
+
+ offset = strstr (node_data, text);
+ if (!offset) {
+ node = NULL;
+ continue;
+ }
+
+ split_offset = offset - node_data + text_length;
+ replacement_node =
+ webkit_dom_node_clone_node (replacement, TRUE);
+
+ data_length = webkit_dom_character_data_get_length(
+ (WebKitDOMCharacterData *) node);
+ if (split_offset < data_length) {
+
+ WebKitDOMNode *parent_node;
+
+ node = WEBKIT_DOM_NODE (
+ webkit_dom_text_split_text (
+ (WebKitDOMText *) node,
+ offset - node_data + text_length,
+ NULL));
+ parent_node = webkit_dom_node_get_parent_node(node);
+ webkit_dom_node_insert_before (
+ parent_node, replacement_node,
+ node, NULL);
+
+ } else {
+ WebKitDOMNode *parent_node;
+
+ parent_node = webkit_dom_node_get_parent_node (node);
+ webkit_dom_node_append_child (
+ parent_node,
+ replacement_node, NULL);
+ }
+
+ webkit_dom_character_data_delete_data (
+ (WebKitDOMCharacterData *) (current_node),
+ offset - node_data, text_length, NULL);
+ }
+
+ } else {
+
+ WebKitDOMNode *child, *next_child;
+
+ /* Iframe? Let's traverse inside! */
+ if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (node)) {
+
+ WebKitDOMDocument *frame_document;
+
+ frame_document =
+ webkit_dom_html_iframe_element_get_content_document(
+ WEBKIT_DOM_HTML_IFRAME_ELEMENT (node));
+ replace_text (WEBKIT_DOM_NODE (frame_document),
+ text, replacement);
+
+ } else {
+
+ child = webkit_dom_node_get_first_child (node);
+ while (child) {
+ next_child = webkit_dom_node_get_next_sibling (child);
+ replace_text (child, text, replacement);
+ child = next_child;
+ }
+ }
+ }
+
+}
+
+
+static void
+web_view_update_document_highlights (EWebView *web_view)
+{
+ WebKitDOMDocument *document;
+ GSList *iter;
+
+ document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view));
+
+ for (iter = web_view->priv->highlights; iter; iter = iter->next) {
+
+ WebKitDOMDocumentFragment *frag;
+ WebKitDOMElement *span;
+
+ span = webkit_dom_document_create_element (document, "span", NULL);
+ webkit_dom_html_element_set_class_name (
+ WEBKIT_DOM_HTML_ELEMENT (span), "__evo-highlight");
+ webkit_dom_html_element_set_inner_text (
+ WEBKIT_DOM_HTML_ELEMENT (span), iter->data, NULL);
+
+ frag = webkit_dom_document_create_document_fragment (document);
+ webkit_dom_node_append_child (
+ WEBKIT_DOM_NODE (frag), WEBKIT_DOM_NODE (span), NULL);
+
+ replace_text(WEBKIT_DOM_NODE (document),
+ iter->data, WEBKIT_DOM_NODE (frag));
+ }
+}
+
+
+static void
web_view_menu_item_deselect_cb (EWebView *web_view)
{
e_web_view_status_message (web_view, NULL);
@@ -438,6 +569,20 @@ web_view_navigation_policy_decision_requested_cb (EWebView *web_view,
}
static void
+web_view_load_status_changed_cb (WebKitWebView *web_view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ WebKitLoadStatus status;
+
+ status = webkit_web_view_get_load_status (web_view);
+ if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ web_view_update_document_highlights (E_WEB_VIEW (web_view));
+}
+
+static void
web_view_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -657,6 +802,11 @@ web_view_dispose (GObject *object)
priv->js_callbacks = NULL;
}
+ if (priv->highlights != NULL) {
+ g_slist_free_full (priv->highlights, g_free);
+ priv->highlights = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -1538,6 +1688,8 @@ e_web_view_init (EWebView *web_view)
web_view->priv = E_WEB_VIEW_GET_PRIVATE (web_view);
+ web_view->priv->highlights = NULL;
+
g_signal_connect (
web_view, "create-plugin-widget",
G_CALLBACK (web_view_create_plugin_widget_cb), NULL);
@@ -1551,6 +1703,10 @@ e_web_view_init (EWebView *web_view)
G_CALLBACK (web_view_navigation_policy_decision_requested_cb),
NULL);
+ g_signal_connect (
+ web_view, "notify::load-status",
+ G_CALLBACK (web_view_load_status_changed_cb), NULL);
+
ui_manager = gtk_ui_manager_new ();
web_view->priv->ui_manager = ui_manager;
@@ -2387,6 +2543,40 @@ e_web_view_set_save_as_proxy (EWebView *web_view,
g_object_notify (G_OBJECT (web_view), "save-as-proxy");
}
+GSList*
+e_web_view_get_highlights (EWebView *web_view)
+{
+ g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL);
+
+ return web_view->priv->highlights;
+}
+
+void
+e_web_view_add_highlight (EWebView *web_view,
+ const gchar *highlight)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (highlight && *highlight);
+
+ web_view->priv->highlights =
+ g_slist_append (web_view->priv->highlights, g_strdup (highlight));
+
+ web_view_update_document_highlights (web_view);
+}
+
+void e_web_view_clear_highlights (EWebView *web_view)
+{
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+
+ if (!web_view->priv->highlights)
+ return;
+
+ g_slist_free_full (web_view->priv->highlights, g_free);
+ web_view->priv->highlights = NULL;
+
+ web_view_update_document_highlights (web_view);
+}
+
GtkAction *
e_web_view_get_action (EWebView *web_view,
const gchar *action_name)
diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h
index 6b32501..1562d84 100644
--- a/widgets/misc/e-web-view.h
+++ b/widgets/misc/e-web-view.h
@@ -186,6 +186,10 @@ void e_web_view_set_print_proxy (EWebView *web_view,
GtkAction * e_web_view_get_save_as_proxy (EWebView *web_view);
void e_web_view_set_save_as_proxy (EWebView *web_view,
GtkAction *save_as_proxy);
+GSList* e_web_view_get_highlights (EWebView *web_view);
+void e_web_view_add_highlight (EWebView *web_view,
+ const gchar *highlight);
+void e_web_view_clear_highlights (EWebView *web_view);
GtkAction * e_web_view_get_action (EWebView *web_view,
const gchar *action_name);
GtkActionGroup *e_web_view_get_action_group (EWebView *web_view,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]