summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2015-12-23 14:48:21 +0100
committerShaun McCance <shaunm@gnome.org>2016-01-14 12:35:25 -0500
commite5f3a147aec6aeb4629194e1d3a3eefc1d4716e9 (patch)
tree76883751f6bbac28edca06e82abdf20677712279
parente81cf1466881e08abb14b66793e21de3415c6364 (diff)
downloadyelp-e5f3a147aec6aeb4629194e1d3a3eefc1d4716e9.tar.gz
libyelp: fix handling of documents using local paths
Since we switched to use custom URI schemes we no longer support loading file URIs. We need to detect the document pointed by the given URI and build an appropriate URI (ghelp, man, info, ...). https://bugzilla.gnome.org/show_bug.cgi?id=753443
-rw-r--r--libyelp/web-extension/yelp-web-extension.c4
-rw-r--r--libyelp/yelp-uri.c282
2 files changed, 182 insertions, 104 deletions
diff --git a/libyelp/web-extension/yelp-web-extension.c b/libyelp/web-extension/yelp-web-extension.c
index 1d66a63b..770b3a75 100644
--- a/libyelp/web-extension/yelp-web-extension.c
+++ b/libyelp/web-extension/yelp-web-extension.c
@@ -79,6 +79,10 @@ web_page_send_request (WebKitWebPage *web_page,
if (!current_uri)
return FALSE;
+ /* Main resource */
+ if (strcmp (resource_uri, webkit_web_page_get_uri (web_page)) == 0)
+ return FALSE;
+
yelp_uri = build_yelp_uri (resource_uri);
file_path = get_resource_path (yelp_uri, current_uri);
if (file_path) {
diff --git a/libyelp/yelp-uri.c b/libyelp/yelp-uri.c
index 91479593..ca315641 100644
--- a/libyelp/yelp-uri.c
+++ b/libyelp/yelp-uri.c
@@ -55,6 +55,7 @@ static void resolve_xref_uri (YelpUri *uri);
static void resolve_page_and_frag (YelpUri *uri,
const gchar *arg);
static void resolve_gfile (YelpUri *uri,
+ const gchar *query,
const gchar *hash);
static gboolean is_man_path (const gchar *uri,
@@ -516,6 +517,13 @@ yelp_uri_locate_file_uri (YelpUri *uri,
gchar *fullpath;
gchar *returi = NULL;
gint i;
+
+ if (g_path_is_absolute (filename)) {
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ return g_filename_to_uri (filename, NULL, NULL);
+ return NULL;
+ }
+
for (i = 0; priv->search_path[i] != NULL; i++) {
fullpath = g_strconcat (priv->search_path[i],
G_DIR_SEPARATOR_S,
@@ -551,7 +559,7 @@ resolve_file_uri (YelpUri *uri)
priv->gfile = g_file_new_for_uri (uristr);
- resolve_gfile (uri, hash);
+ resolve_gfile (uri, NULL, hash);
}
static void
@@ -608,7 +616,7 @@ resolve_file_path (YelpUri *uri)
g_free (cur);
}
- resolve_gfile (uri, hash);
+ resolve_gfile (uri, NULL, hash);
}
static void
@@ -714,6 +722,22 @@ resolve_data_dirs (YelpUri *ret,
}
static void
+build_ghelp_fulluri (YelpUri *uri)
+{
+ YelpUriPrivate *priv = GET_PRIV (uri);
+
+ g_assert (priv->tmptype != YELP_URI_DOCUMENT_TYPE_UNRESOLVED);
+ g_assert (priv->docuri != NULL);
+ priv->fulluri = g_strconcat (priv->docuri,
+ priv->tmptype == YELP_URI_DOCUMENT_TYPE_MALLARD ? "/" : "",
+ priv->page_id ? "?" : "",
+ priv->page_id ? priv->page_id : "",
+ priv->frag_id ? "#" : "",
+ priv->frag_id ? priv->frag_id : "",
+ NULL);
+}
+
+static void
resolve_ghelp_uri (YelpUri *uri)
{
/* ghelp:/path/to/file
@@ -761,16 +785,32 @@ resolve_ghelp_uri (YelpUri *uri)
hash = g_strdup (hash + 1);
if (*(colon + 1) == '/') {
- gchar *newuri;
- newuri = g_strdup_printf ("file:/%s", slash);
- g_free (priv->res_arg);
- priv->res_arg = newuri;
- resolve_file_uri (uri);
- }
- else {
- resolve_data_dirs (uri, "gnome/help", document, slash ? slash : document, FALSE);
+ gchar *path;
+
+ path = g_build_filename ("/", slash, NULL);
+ if (g_file_test (path, G_FILE_TEST_EXISTS)) {
+ priv->gfile = g_file_new_for_path (path);
+ resolve_gfile (uri, query, hash);
+ } else {
+ gchar *dirname = g_path_get_dirname (path);
+ gchar *basename = g_path_get_basename (path);
+
+ priv->gfile = g_file_new_for_path (dirname);
+ g_free (dirname);
+ resolve_gfile (uri, basename, hash);
+ g_free (basename);
+ }
+ g_free (path);
+ g_free (slash);
+ g_free (query);
+ g_free (hash);
+ g_free (document);
+
+ return;
}
+ resolve_data_dirs (uri, "gnome/help", document, slash ? slash : document, FALSE);
+
if (query && hash) {
priv->page_id = query;
priv->frag_id = hash;
@@ -794,12 +834,7 @@ resolve_ghelp_uri (YelpUri *uri)
slash ? "/" : NULL,
slash, NULL);
- priv->fulluri = g_strconcat (priv->docuri,
- priv->page_id ? "?" : "",
- priv->page_id ? priv->page_id : "",
- priv->frag_id ? "#" : "",
- priv->frag_id ? priv->frag_id : "",
- NULL);
+ build_ghelp_fulluri (uri);
g_free (document);
g_free (slash);
@@ -959,6 +994,23 @@ find_man_path (gchar* name, gchar* section)
}
static void
+build_man_uris (YelpUri *uri, const char *name, const char *section)
+{
+ YelpUriPrivate *priv = GET_PRIV (uri);
+
+ g_assert (priv->tmptype == YELP_URI_DOCUMENT_TYPE_MAN);
+ priv->docuri = g_strdup ("man:");
+ priv->fulluri = g_strconcat ("man:", name,
+ section ? "." : "",
+ section ? section : "",
+ NULL);
+ priv->page_id = g_strconcat (name,
+ section ? "." : "",
+ section ? section : "",
+ NULL);
+}
+
+static void
resolve_man_uri (YelpUri *uri)
{
YelpUriPrivate *priv = GET_PRIV (uri);
@@ -998,15 +1050,12 @@ resolve_man_uri (YelpUri *uri)
if (!g_regex_match (man_not_path, priv->res_arg,
0, &match_info)) {
/* The regexp didn't match, so treat as a file name. */
- gchar *newuri;
guint i;
static const char *man_suffixes[] = { "gz", "bz2", "lzma", NULL };
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
- newuri = g_strdup_printf ("file:%s", priv->res_arg + 4);
- g_free (priv->res_arg);
- priv->res_arg = newuri;
- name = g_path_get_basename (newuri + 5);
+ priv->gfile = g_file_new_for_path (priv->res_arg + 4);
+ name = g_file_get_basename (priv->gfile);
for (i = 0; i < G_N_ELEMENTS (man_suffixes); i++) {
if (is_man_path (name, man_suffixes[i])) {
if (man_suffixes[i])
@@ -1014,10 +1063,7 @@ resolve_man_uri (YelpUri *uri)
break;
}
}
- priv->docuri = g_strdup ("man:");
- priv->fulluri = g_strconcat ("man:", name, NULL);
- priv->page_id = name;
- resolve_file_uri (uri);
+ build_man_uris (uri, name, NULL);
}
else {
/* The regexp matched, so we've got a name/section pair that
@@ -1042,10 +1088,7 @@ resolve_man_uri (YelpUri *uri)
}
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
priv->gfile = g_file_new_for_path (path);
- priv->docuri = g_strdup ("man:");
- priv->fulluri = g_strconcat ("man:", name, ".", section, NULL);
- priv->page_id = g_strconcat (name, ".", section, NULL);
- resolve_gfile (uri, NULL);
+ build_man_uris (uri, name, section);
if (hash && hash[0] != '\0')
resolve_page_and_frag (uri, hash + 1);
@@ -1056,6 +1099,21 @@ resolve_man_uri (YelpUri *uri)
}
static void
+build_info_uris (YelpUri *uri, const char *name, const char *section)
+{
+ YelpUriPrivate *priv = GET_PRIV (uri);
+
+ g_assert (priv->tmptype == YELP_URI_DOCUMENT_TYPE_INFO);
+ priv->docuri = g_strconcat ("info:", name, NULL);
+ priv->fulluri = g_strconcat (priv->docuri,
+ section ? "#" : "",
+ section ? section : "",
+ NULL);
+ priv->page_id = g_strdup (section);
+ priv->frag_id = g_strdup (section);
+}
+
+static void
resolve_info_uri (YelpUri *uri)
{
YelpUriPrivate *priv = GET_PRIV (uri);
@@ -1074,23 +1132,23 @@ resolve_info_uri (YelpUri *uri)
gint infopath_i, suffix_i;
if (g_str_has_prefix (priv->res_arg, "info:/")) {
- gchar *newuri, *basename;
const gchar *hash;
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- newuri = g_strdup_printf ("file:%s", priv->res_arg + 5);
- g_free (priv->res_arg);
- priv->res_arg = newuri;
- basename = g_path_get_basename (newuri + 5);
- hash = g_strrstr (basename, "#");
+
+ hash = strchr (priv->res_arg + 5, '#');
if (hash) {
- name = g_strndup (basename, hash - basename);
+ gchar *path;
+
+ path = g_strndup (priv->res_arg + 5, hash - (priv->res_arg + 5));
+ priv->gfile = g_file_new_for_path (path);
+ g_free (path);
sect = g_strdup (hash + 1);
- } else {
- name = g_strdup (basename);
- sect = NULL;
}
- g_free (basename);
+ else
+ priv->gfile = g_file_new_for_path (priv->res_arg + 5);
+
+ name = g_file_get_basename (priv->gfile);
for (suffix_i = 0; infosuffix[suffix_i]; suffix_i++) {
if (g_str_has_suffix (name, infosuffix[suffix_i])) {
name[strlen (name) - strlen (infosuffix[suffix_i])] = '\0';
@@ -1098,17 +1156,7 @@ resolve_info_uri (YelpUri *uri)
}
}
- priv->docuri = g_strconcat ("info:", name, NULL);
- if (sect) {
- priv->fulluri = g_strconcat ("info:", name, "#", sect, NULL);
- priv->page_id = g_strdup (sect);
- priv->frag_id = sect;
- sect = NULL; /* steal memory */
- } else {
- priv->fulluri = g_strdup (priv->docuri);
- }
- resolve_file_uri (uri);
-
+ build_info_uris (uri, name, sect);
g_free (name);
g_free (sect);
return;
@@ -1179,16 +1227,7 @@ resolve_info_uri (YelpUri *uri)
if (fullpath) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
priv->gfile = g_file_new_for_path (fullpath);
- priv->docuri = g_strconcat ("info:", name, NULL);
- if (sect) {
- priv->fulluri = g_strconcat ("info:", name, "#", sect, NULL);
- priv->page_id = g_strdup (sect);
- priv->frag_id = sect;
- sect = NULL; /* steal memory */
- }
- else
- priv->fulluri = g_strdup (priv->docuri);
- resolve_gfile (uri, NULL);
+ build_info_uris (uri, name, sect);
} else {
gchar *res_arg = priv->res_arg;
priv->res_arg = g_strconcat ("man:", name, NULL);
@@ -1255,12 +1294,7 @@ resolve_xref_uri (YelpUri *uri)
}
if (g_str_has_prefix (priv->docuri, "ghelp:"))
- priv->fulluri = g_strconcat (priv->docuri,
- priv->page_id ? "?" : "",
- priv->page_id ? priv->page_id : "",
- priv->frag_id ? "#" : "",
- priv->frag_id ? priv->frag_id : "",
- NULL);
+ build_ghelp_fulluri (uri);
else if (g_str_has_prefix (priv->docuri, "help:"))
priv->fulluri = g_strconcat (priv->docuri,
priv->page_id ? "/" : "",
@@ -1305,7 +1339,7 @@ resolve_page_and_frag (YelpUri *uri, const gchar *arg)
}
static void
-resolve_gfile (YelpUri *uri, const gchar *hash)
+resolve_gfile (YelpUri *uri, const gchar *query, const gchar *hash)
{
YelpUriPrivate *priv = GET_PRIV (uri);
GFileInfo *info;
@@ -1340,34 +1374,34 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
}
if (priv->tmptype == YELP_URI_DOCUMENT_TYPE_UNRESOLVED) {
- gchar **splithash = NULL;
- if (hash)
- splithash = g_strsplit (hash, "#", 2);
priv->tmptype = YELP_URI_DOCUMENT_TYPE_EXTERNAL;
if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) ==
G_FILE_TYPE_DIRECTORY) {
GFile *child = g_file_get_child (priv->gfile, "index.page");
if (g_file_query_exists (child, NULL)) {
+ char *path;
+
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MALLARD;
- if (splithash) {
- if (priv->page_id == NULL)
- priv->page_id = g_strdup (splithash[0]);
- if (priv->frag_id == NULL && splithash[0])
- priv->frag_id = g_strdup (splithash[1]);
- }
+ if (priv->page_id == NULL)
+ priv->page_id = g_strdup (query);
+ if (priv->frag_id == NULL)
+ priv->frag_id = g_strdup (hash);
+
+ path = g_file_get_path (priv->gfile);
+ priv->docuri = g_strconcat ("ghelp:", path, NULL);
+ build_ghelp_fulluri (uri);
+ g_free (path);
}
else if (yelp_settings_get_editor_mode (yelp_settings_get_default ())) {
g_object_unref (child);
child = g_file_get_child (priv->gfile, "index.page.stub");
if (g_file_query_exists (child, NULL)) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MALLARD;
- if (splithash) {
- if (priv->page_id == NULL)
- priv->page_id = g_strdup (splithash[0]);
- if (priv->frag_id == NULL && splithash[0])
- priv->frag_id = g_strdup (splithash[1]);
- }
+ if (priv->page_id == NULL)
+ priv->page_id = g_strdup (query);
+ if (priv->frag_id == NULL)
+ priv->frag_id = g_strdup (hash);
}
}
g_object_unref (child);
@@ -1379,6 +1413,8 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
basename = g_file_get_basename (priv->gfile);
if (g_str_has_suffix (basename, ".page")) {
GFile *old;
+ char *path;
+
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MALLARD;
old = priv->gfile;
priv->gfile = g_file_get_parent (old);
@@ -1391,20 +1427,31 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
priv->page_id = g_strconcat (G_DIR_SEPARATOR_S, tmp, NULL);
g_free (tmp);
}
+
if (priv->frag_id == NULL)
priv->frag_id = g_strdup (hash);
+ path = g_file_get_path (priv->gfile);
+ priv->docuri = g_strconcat ("ghelp:", path, NULL);
+ build_ghelp_fulluri (uri);
+ g_free (path);
g_object_unref (old);
}
else if (g_str_equal (mime_type, "text/xml") ||
g_str_equal (mime_type, "application/docbook+xml") ||
g_str_equal (mime_type, "application/xml")) {
+ char *path;
+
priv->tmptype = YELP_URI_DOCUMENT_TYPE_DOCBOOK;
- if (splithash) {
- if (priv->page_id == NULL)
- priv->page_id = g_strdup (splithash[0]);
- if (priv->frag_id == NULL && splithash[0])
- priv->frag_id = g_strdup (splithash[1]);
- }
+
+ if (priv->page_id == NULL)
+ priv->page_id = g_strdup (query);
+ if (priv->frag_id == NULL)
+ priv->frag_id = g_strdup (hash);
+
+ path = g_file_get_path (priv->gfile);
+ priv->docuri = g_strconcat ("ghelp:", path, NULL);
+ build_ghelp_fulluri (uri);
+ g_free (path);
}
else if (g_str_equal (mime_type, "text/html") ||
g_str_equal (mime_type, "application/xhtml+xml")) {
@@ -1413,7 +1460,7 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
g_object_unref (parent);
priv->tmptype = mime_type[0] == 't' ? YELP_URI_DOCUMENT_TYPE_HTML : YELP_URI_DOCUMENT_TYPE_XHTML;
if (priv->page_id == NULL)
- priv->page_id = g_file_get_basename (priv->gfile);
+ priv->page_id = g_strdup (basename);
if (priv->frag_id == NULL)
priv->frag_id = g_strdup (hash);
if (priv->fulluri == NULL) {
@@ -1426,36 +1473,64 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
g_free (fulluri);
}
}
- else if (g_str_equal (mime_type, "application/x-gzip")) {
- if (g_str_has_suffix (basename, ".info.gz"))
+ else if (g_str_equal (mime_type, "application/x-gzip") ||
+ g_str_equal (mime_type, "application/gzip")) {
+ if (g_str_has_suffix (basename, ".info.gz")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- else if (is_man_path (basename, "gz"))
+ basename[strlen (basename) - strlen (".info.gz")] = '\0';
+ build_info_uris (uri, basename, hash);
+ }
+ else if (is_man_path (basename, "gz")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
+ basename[strlen (basename) - strlen ("gz") - 1] = '\0';
+ build_man_uris (uri, basename, NULL);
+ }
}
else if (g_str_equal (mime_type, "application/x-bzip")) {
- if (g_str_has_suffix (basename, ".info.bz2"))
+ if (g_str_has_suffix (basename, ".info.bz2")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- else if (is_man_path (basename, "bz2"))
+ basename[strlen (basename) - strlen (".info.bz2")] = '\0';
+ build_info_uris (uri, basename, hash);
+ }
+ else if (is_man_path (basename, "bz2")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
+ basename[strlen (basename) - strlen ("bz2") - 1] = '\0';
+ build_man_uris (uri, basename, NULL);
+ }
}
else if (g_str_equal (mime_type, "application/x-lzma")) {
- if (g_str_has_suffix (basename, ".info.lzma"))
+ if (g_str_has_suffix (basename, ".info.lzma")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- else if (is_man_path (basename, "lzma"))
+ basename[strlen (basename) - strlen (".info.lzma")] = '\0';
+ build_info_uris (uri, basename, hash);
+ }
+ else if (is_man_path (basename, "lzma")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
+ basename[strlen (basename) - strlen ("lzma") - 1] = '\0';
+ build_man_uris (uri, basename, NULL);
+ }
}
else if (g_str_equal (mime_type, "application/octet-stream")) {
- if (g_str_has_suffix (basename, ".info"))
+ if (g_str_has_suffix (basename, ".info")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- else if (is_man_path (basename, NULL))
+ basename[strlen (basename) - strlen (".info")] = '\0';
+ build_info_uris (uri, basename, hash);
+ }
+ else if (is_man_path (basename, NULL)) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
+ build_man_uris (uri, basename, NULL);
+ }
}
else if (g_str_equal (mime_type, "text/plain")) {
- if (g_str_has_suffix (basename, ".info"))
+ if (g_str_has_suffix (basename, ".info")) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_INFO;
- else if (is_man_path (basename, NULL))
+ basename[strlen (basename) - strlen (".info")] = '\0';
+ build_info_uris (uri, basename, hash);
+ }
+ else if (is_man_path (basename, NULL)) {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_MAN;
- else
+ build_man_uris (uri, basename, NULL);
+ } else
priv->tmptype = YELP_URI_DOCUMENT_TYPE_TEXT;
if (priv->frag_id == NULL)
priv->frag_id = g_strdup (hash);
@@ -1466,9 +1541,8 @@ resolve_gfile (YelpUri *uri, const gchar *hash)
else {
priv->tmptype = YELP_URI_DOCUMENT_TYPE_EXTERNAL;
}
+ g_free (basename);
}
- if (splithash)
- g_strfreev (splithash);
}
if (priv->docuri == NULL)