summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2021-07-29 14:02:51 -0400
committerShaun McCance <shaunm@gnome.org>2021-07-29 14:02:51 -0400
commit02bb34ef43035a9a6cd6e51ad139478fa7a50b1d (patch)
tree44ea2e12b549c92866e5f56ca53b6aa91de8d7a1
parent677e8f09c7af1859b8dcf0492da0fda6826bf9c6 (diff)
downloadyelp-02bb34ef43035a9a6cd6e51ad139478fa7a50b1d.tar.gz
Make search results go thru XSLT too
One step color to removing color computation and complex HTML formatting from C.
-rw-r--r--.gitignore1
-rw-r--r--data/xslt/links2html.xsl.in32
-rw-r--r--libyelp/yelp-document.c279
-rw-r--r--libyelp/yelp-transform.c8
-rw-r--r--libyelp/yelp-transform.h2
-rw-r--r--libyelp/yelp-view.c24
6 files changed, 178 insertions, 168 deletions
diff --git a/.gitignore b/.gitignore
index ea86d02e..dca49027 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,7 @@ yelp
/data/dtd/catalog
/data/xslt/db2html.xsl
/data/xslt/info2html.xsl
+/data/xslt/links2html.xsl
/data/xslt/mal2html.xsl
/data/xslt/man2html.xsl
/data/xslt/yelp-common.xsl
diff --git a/data/xslt/links2html.xsl.in b/data/xslt/links2html.xsl.in
index e5b8c1d2..eed32407 100644
--- a/data/xslt/links2html.xsl.in
+++ b/data/xslt/links2html.xsl.in
@@ -55,28 +55,44 @@
<xsl:with-param name="right" select="$right"/>
</xsl:call-template>
<xsl:text>
-.ex-yelp-panel-icon {
- display: flex;
-}
</xsl:text>
</xsl:template>
+<xsl:template mode="html.header.mode" match="links">
+ <xsl:if test="@docref and @doctitle">
+ <div class="trails" role="navigation">
+ <div class="trail">
+ <a class="trail" href="{@docref}">
+ <xsl:value-of select="@doctitle"/>
+ </a>
+ <xsl:text>&#x00A0; » </xsl:text>
+ </div>
+ </div>
+ </xsl:if>
+</xsl:template>
+
<xsl:template mode="html.body.mode" match="links">
<div class="hgroup pagewide">
<h1><span class="title"><xsl:value-of select="title"/></span></h1>
</div>
+ <xsl:variable name="hasicons" select="count(link/thumb/@src) > 0"/>
<div class="region">
<div class="contents pagewide">
+ <xsl:for-each select="p">
+ <p><xsl:value-of select="."/></p>
+ </xsl:for-each>
<div class="links-divs">
<xsl:for-each select="link">
<div class="linkdiv">
<a class="linkdiv" href="{@href}" title="{title}">
<span style="display:flex;">
- <span class="thumb" style="min-width:48px;padding-right:10px;">
- <xsl:if test="thumb/@src != ''">
- <img src="{thumb/@src}" width="48" height="48"/>
- </xsl:if>
- </span>
+ <xsl:if test="$hasicons">
+ <span class="thumb" style="min-width:48px;padding-right:10px;">
+ <xsl:if test="thumb/@src != ''">
+ <img src="{thumb/@src}" width="48" height="48"/>
+ </xsl:if>
+ </span>
+ </xsl:if>
<span>
<span class="title">
<xsl:value-of select="title"/>
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index 346c411d..cfac7291 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -25,6 +25,7 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <libxml/parser.h>
#include "yelp-debug.h"
#include "yelp-document.h"
@@ -37,6 +38,9 @@
#include "yelp-settings.h"
#include "yelp-simple-document.h"
#include "yelp-storage.h"
+#include "yelp-transform.h"
+
+#define LINKS_STYLESHEET DATADIR"/yelp/xslt/links2html.xsl"
enum {
PROP_0,
@@ -822,18 +826,116 @@ yelp_document_set_page_icon (YelpDocument *document,
g_mutex_unlock (&document->priv->mutex);
}
+
+static void
+search_transform_chunk_ready (YelpTransform *transform,
+ gchar *chunk_id,
+ YelpDocument *document)
+{
+ gchar *content;
+ content = yelp_transform_take_chunk (transform, chunk_id);
+ yelp_document_give_contents (document,
+ chunk_id,
+ content,
+ "application/xhtml+xml");
+ yelp_document_signal (document,
+ chunk_id,
+ YELP_DOCUMENT_SIGNAL_CONTENTS,
+ NULL);
+}
+
+
+static void
+search_transform_finished (YelpTransform *transform,
+ YelpDocument *document)
+{
+ xmlFreeDoc (yelp_transform_get_xmldoc (transform));
+ g_object_unref (transform);
+}
+
+
static gboolean
document_indexed (YelpDocument *document)
{
g_mutex_lock (&document->priv->mutex);
+
while (document->priv->reqs_search != NULL) {
+ xmlDocPtr resultsdoc;
+ xmlNodePtr rootnode;
+ gchar *term, *text;
+ GVariant *value;
+ GVariantIter *iter;
+ YelpTransform *transform;
+ gchar **params = NULL;
Request *request = (Request *) document->priv->reqs_search->data;
- request->idle_funcs++;
- g_idle_add ((GSourceFunc) request_idle_info, request);
- g_idle_add ((GSourceFunc) request_idle_contents, request);
+
+ resultsdoc = xmlNewDoc (BAD_CAST "1.0");
+ rootnode = xmlNewDocNode (resultsdoc, NULL, BAD_CAST "links", NULL);
+ xmlDocSetRootElement (resultsdoc, rootnode);
+ xmlSetProp (rootnode, BAD_CAST "id", BAD_CAST request->page_id);
+
+ xmlSetProp (rootnode, BAD_CAST "docref", BAD_CAST request->page_id);
+
+ text = yelp_storage_get_root_title (yelp_storage_get_default (),
+ document->priv->doc_uri);
+ if (text) {
+ xmlSetProp (rootnode, BAD_CAST "docref", BAD_CAST "xref:");
+ xmlSetProp (rootnode, BAD_CAST "doctitle", BAD_CAST text);
+ g_free (text);
+ }
+
+ term = g_uri_unescape_string (request->page_id + 7, "");
+ text = g_strdup_printf (_("Search results for “%s”"), term);
+ xmlNewTextChild (rootnode, NULL, BAD_CAST "title", BAD_CAST text);
+ g_free (text);
+
+ value = yelp_storage_search (yelp_storage_get_default (),
+ document->priv->doc_uri,
+ term);
+ iter = g_variant_iter_new (value);
+ if (g_variant_iter_n_children (iter) == 0) {
+ xmlNewTextChild (rootnode, NULL, BAD_CAST "p",
+ BAD_CAST _("No matching help pages found."));
+ }
+ else {
+ gchar *url, *title, *desc, *icon; /* do not free */
+ while (g_variant_iter_loop (iter, "(&s&s&s&s)", &url, &title, &desc, &icon)) {
+ xmlNodePtr linknode;
+ gchar *xref_uri = NULL;
+
+ if (g_str_has_prefix (url, document->priv->doc_uri)) {
+ gchar *urloffset = url + strlen(document->priv->doc_uri) + 1; /* do not free */
+ if (urloffset[0] == '?')
+ urloffset += 1; /* handle oddity of old ghelp URIs */
+ xref_uri = g_strdup_printf ("xref:%s", urloffset);
+ }
+ linknode = xmlNewChild (rootnode, NULL, BAD_CAST "link", NULL);
+ xmlSetProp (linknode, BAD_CAST "href", BAD_CAST xref_uri);
+ xmlNewTextChild (linknode, NULL, BAD_CAST "title", BAD_CAST title);
+ xmlNewTextChild (linknode, NULL, BAD_CAST "desc", BAD_CAST desc);
+ g_free (xref_uri);
+ }
+ }
+ g_variant_iter_free (iter);
+ g_variant_unref (value);
+ g_free (term);
+
+ params = yelp_settings_get_all_params (yelp_settings_get_default (), 0, NULL);
+ transform = yelp_transform_new (LINKS_STYLESHEET);
+ g_signal_connect (transform, "chunk-ready",
+ (GCallback) search_transform_chunk_ready,
+ document);
+ g_signal_connect (transform, "finished",
+ (GCallback) search_transform_finished,
+ document);
+ yelp_transform_start (transform, resultsdoc, NULL,
+ (const gchar * const *) params);
+ g_strfreev (params);
+
document->priv->reqs_search = g_slist_delete_link (document->priv->reqs_search,
document->priv->reqs_search);
}
+
g_mutex_unlock (&document->priv->mutex);
return FALSE;
@@ -852,7 +954,13 @@ yelp_document_request_page (YelpDocument *document,
g_return_val_if_fail (YELP_IS_DOCUMENT (document), FALSE);
g_return_val_if_fail (YELP_DOCUMENT_GET_CLASS (document)->request_page != NULL, FALSE);
- debug_print (DB_FUNCTION, "entering\n");
+ if (page_id && g_str_has_prefix (page_id, "search="))
+ return document_request_page (document,
+ page_id,
+ cancellable,
+ callback,
+ user_data,
+ notify);
return YELP_DOCUMENT_GET_CLASS (document)->request_page (document,
page_id,
@@ -905,8 +1013,6 @@ document_request_page (YelpDocument *document,
g_idle_add ((GSourceFunc) document_indexed, document);
else
yelp_document_index (document);
- g_mutex_unlock (&document->priv->mutex);
- return TRUE;
}
hash_slist_insert (document->priv->reqs_by_page_id,
@@ -914,7 +1020,11 @@ document_request_page (YelpDocument *document,
request);
document->priv->reqs_all = g_slist_prepend (document->priv->reqs_all, request);
- document->priv->reqs_pending = g_slist_prepend (document->priv->reqs_pending, request);
+ if (page_id && g_str_has_prefix (page_id, "search=")) {
+ }
+ else {
+ document->priv->reqs_pending = g_slist_prepend (document->priv->reqs_pending, request);
+ }
if (hash_lookup (document->priv->titles, request->page_id)) {
request->idle_funcs++;
@@ -976,6 +1086,9 @@ yelp_document_read_contents (YelpDocument *document,
g_return_val_if_fail (YELP_IS_DOCUMENT (document), NULL);
g_return_val_if_fail (YELP_DOCUMENT_GET_CLASS (document)->read_contents != NULL, NULL);
+ if (page_id != NULL && g_str_has_prefix (page_id, "search="))
+ return document_read_contents (document, page_id);
+
return YELP_DOCUMENT_GET_CLASS (document)->read_contents (document, page_id);
}
@@ -983,143 +1096,14 @@ static const gchar *
document_read_contents (YelpDocument *document,
const gchar *page_id)
{
- gchar *real, *str, **colors;
+ gchar *real, *str; /* do not free real */
g_mutex_lock (&document->priv->mutex);
- real = hash_lookup (document->priv->page_ids, page_id);
-
- if (page_id != NULL && g_str_has_prefix (page_id, "search=")) {
- gchar *tmp, *tmp2, *txt;
- GVariant *value;
- GVariantIter *iter;
- gchar *url, *title, *desc, *icon; /* do not free */
- gchar *index_title;
- GString *ret = g_string_new ("<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><style type='text/css'>");
-
- colors = yelp_settings_get_colors (yelp_settings_get_default ());
- g_string_append_printf (ret,
- "html { height: 100%%; } "
- "body { margin: 0; padding: 0;"
- " background-color: %s; color: %s;"
- " direction: %s; } "
- "div.header { margin-bottom: 1em; } "
- "div.trails { "
- " margin: 0; padding: 0.2em 12px 0 12px;"
- " background-color: %s;"
- " border-bottom: solid 1px %s; } "
- "div.trail { text-indent: -1em;"
- " margin: 0 1em 0.2em 1em; padding: 0; color: %s; } "
- "div.body { margin: 0 12px 0 12px; padding: 0 0 12px 0; max-width: 60em; } "
- "div, p { margin: 1em 0 0 0; padding: 0; } "
- "div:first-child, p:first-child { margin-top: 0; } "
- "h1 { margin: 0; padding: 0; color: %s; font-size: 1.44em; } "
- "a { color: %s; text-decoration: none; } "
- "a.linkdiv { display: block; } "
- "div.linkdiv { margin: 0; padding: 0.5em; }"
- "a:hover div.linkdiv {"
- " outline: solid 1px %s;"
- " background: -webkit-gradient(linear, left top, left 80, from(%s), to(%s)); } "
- "div.title { margin-bottom: 0.2em; font-weight: bold; } "
- "div.desc { margin: 0; color: %s; } "
- "</style></head><body><div class='header'>",
- colors[YELP_SETTINGS_COLOR_BASE],
- colors[YELP_SETTINGS_COLOR_TEXT],
- (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL ? "rtl" : "ltr"),
- colors[YELP_SETTINGS_COLOR_GRAY_BASE],
- colors[YELP_SETTINGS_COLOR_GRAY_BORDER],
- colors[YELP_SETTINGS_COLOR_TEXT_LIGHT],
- colors[YELP_SETTINGS_COLOR_TEXT_LIGHT],
- colors[YELP_SETTINGS_COLOR_LINK],
- colors[YELP_SETTINGS_COLOR_BLUE_BASE],
- colors[YELP_SETTINGS_COLOR_BLUE_BASE],
- colors[YELP_SETTINGS_COLOR_BASE],
- colors[YELP_SETTINGS_COLOR_TEXT_LIGHT]
- );
-
- index_title = yelp_storage_get_root_title (yelp_storage_get_default (),
- document->priv->doc_uri);
- if (index_title != NULL) {
- tmp = g_markup_printf_escaped ("<div class='trails'><div class='trail'>"
- "<a href='xref:'>%s</a>&#x00A0;%s "
- "</div></div>",
- index_title,
- (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL ? "«" : "»")
- );
- g_string_append (ret, tmp);
- g_free (tmp);
- }
-
- g_string_append (ret, "</div><div class='body'>");
- g_strfreev (colors);
-
- str = hash_lookup (document->priv->contents, real);
- if (str) {
- str_ref (str);
- g_mutex_unlock (&document->priv->mutex);
- return (const gchar *) str;
- }
-
- txt = g_uri_unescape_string (page_id + 7, NULL);
- tmp2 = g_strdup_printf (_("Search results for “%s”"), txt);
- tmp = g_markup_printf_escaped ("<h1>%s</h1>", tmp2);
- g_string_append (ret, tmp);
- g_free (tmp2);
- g_free (tmp);
-
- value = yelp_storage_search (yelp_storage_get_default (),
- document->priv->doc_uri,
- txt);
- iter = g_variant_iter_new (value);
- if (g_variant_iter_n_children (iter) == 0) {
- if (index_title != NULL) {
- gchar *t = g_strdup_printf (_("No matching help pages found in “%s”."), index_title);
- tmp = g_markup_printf_escaped ("<p>%s</p>", t);
- g_free (t);
- }
- else {
- tmp = g_markup_printf_escaped ("<p>%s</p>",
- _("No matching help pages found."));
- }
- g_string_append (ret, tmp);
- g_free (tmp);
- }
- else {
- while (g_variant_iter_loop (iter, "(&s&s&s&s)", &url, &title, &desc, &icon)) {
- gchar *xref_uri = NULL;
-
- if (g_str_has_prefix (url, document->priv->doc_uri)) {
- gchar *urloffset = url + strlen(document->priv->doc_uri) + 1; /* do not free */
- if (urloffset[0] == '?')
- urloffset += 1; /* handle oddity of old ghelp URIs */
- xref_uri = g_strdup_printf ("xref:%s", urloffset);
- }
-
- tmp = g_markup_printf_escaped ("<div><a class='linkdiv' href='%s'><div class='linkdiv'>"
- "<div class='title'>%s</div>"
- "<div class='desc'>%s</div>"
- "</div></a></div>",
- xref_uri && xref_uri[0] != '\0' ? xref_uri : url,
- title, desc);
- g_string_append (ret, tmp);
- g_free (xref_uri);
- g_free (tmp);
- }
- }
- g_variant_iter_free (iter);
- g_variant_unref (value);
-
- if (index_title != NULL)
- g_free (index_title);
- g_free (txt);
- g_string_append (ret, "</div></body></html>");
-
- hash_replace (document->priv->contents, page_id, g_string_free (ret, FALSE));
- str = hash_lookup (document->priv->contents, page_id);
- str_ref (str);
- g_mutex_unlock (&document->priv->mutex);
- return (const gchar *) str;
- }
+ if (page_id != NULL && g_str_has_prefix (page_id, "search="))
+ real = (gchar *) page_id;
+ else
+ real = hash_lookup (document->priv->page_ids, page_id);
str = hash_lookup (document->priv->contents, real);
if (str)
@@ -1155,9 +1139,6 @@ yelp_document_give_contents (YelpDocument *document,
{
g_return_if_fail (YELP_IS_DOCUMENT (document));
- debug_print (DB_FUNCTION, "entering\n");
- debug_print (DB_ARG, " page_id = \"%s\"\n", page_id);
-
g_mutex_lock (&document->priv->mutex);
hash_replace (document->priv->contents,
@@ -1185,13 +1166,13 @@ static gchar *
document_get_mime_type (YelpDocument *document,
const gchar *page_id)
{
- gchar *real, *ret = NULL;
-
- if (page_id != NULL && g_str_has_prefix (page_id, "search="))
- return g_strdup ("application/xhtml+xml");
+ gchar *real, *ret = NULL; /* do not free real */
g_mutex_lock (&document->priv->mutex);
- real = hash_lookup (document->priv->page_ids, page_id);
+ if (page_id != NULL && g_str_has_prefix (page_id, "search="))
+ real = (gchar *) page_id;
+ else
+ real = hash_lookup (document->priv->page_ids, page_id);
if (real) {
ret = hash_lookup (document->priv->mime_types, real);
if (ret)
diff --git a/libyelp/yelp-transform.c b/libyelp/yelp-transform.c
index 0107db9a..e74eb463 100644
--- a/libyelp/yelp-transform.c
+++ b/libyelp/yelp-transform.c
@@ -273,6 +273,14 @@ yelp_transform_set_property (GObject *object,
}
}
+
+xmlDocPtr
+yelp_transform_get_xmldoc (YelpTransform *transform)
+{
+ YelpTransformPrivate *priv = yelp_transform_get_instance_private (transform);
+ return priv->input;
+}
+
/******************************************************************************/
YelpTransform *
diff --git a/libyelp/yelp-transform.h b/libyelp/yelp-transform.h
index 8e71b59d..c62b5aad 100644
--- a/libyelp/yelp-transform.h
+++ b/libyelp/yelp-transform.h
@@ -53,4 +53,6 @@ gchar * yelp_transform_take_chunk (YelpTransform *transform,
void yelp_transform_cancel (YelpTransform *transform);
GError * yelp_transform_get_error (YelpTransform *transform);
+xmlDocPtr yelp_transform_get_xmldoc (YelpTransform *transform);
+
#endif /* __YELP_TRANSFORM_H__ */
diff --git a/libyelp/yelp-view.c b/libyelp/yelp-view.c
index 1f10000c..9b2e5fb2 100644
--- a/libyelp/yelp-view.c
+++ b/libyelp/yelp-view.c
@@ -780,17 +780,19 @@ document_callback (YelpDocument *document,
contents = yelp_document_read_contents (document, data->page_id);
- content_length = strlen (contents);
-
- stream = g_memory_input_stream_new_from_data (g_strdup (contents), content_length, g_free);
- yelp_document_finish_read (document, contents);
-
- webkit_uri_scheme_request_finish (data->request,
- stream,
- content_length,
- mime_type);
- g_free (mime_type);
- g_object_unref (stream);
+ if (contents) {
+ content_length = strlen (contents);
+
+ stream = g_memory_input_stream_new_from_data (g_strdup (contents), content_length, g_free);
+ yelp_document_finish_read (document, contents);
+
+ webkit_uri_scheme_request_finish (data->request,
+ stream,
+ content_length,
+ mime_type);
+ g_free (mime_type);
+ g_object_unref (stream);
+ }
}
static void