Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libgepub for openSUSE:Factory checked in at 2022-09-21 14:42:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libgepub (Old) and /work/SRC/openSUSE:Factory/.libgepub.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libgepub" Wed Sep 21 14:42:04 2022 rev:7 rq:1003197 version:0.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libgepub/libgepub.changes 2018-03-26 12:36:07.023694509 +0200 +++ /work/SRC/openSUSE:Factory/.libgepub.new.2083/libgepub.changes 2022-09-21 14:42:55.453836791 +0200 @@ -1,0 +2,25 @@ +Thu Sep 1 06:35:49 UTC 2022 - Bj??rn Lie <bjorn....@gmail.com> + +- Update to version 0.7.0: + + Make gepub-widget configurable with "-Dwidget=false" + + Use libsoup 3.0 + + Fix memory leak + + Remove absolute external resources from gepub + + widget + - Disable a number of "Web" features + - Fix ePubs not rendering after the first one + + Stop chapter number updates breaking navigation to anchor links + + Update the chapter number when the page changes + + Work with file paths, not URI substrings, in custom URI scheme + + Do not rewrite page-relative anchor links + + Use new JavaScriptCore GLib API instead of DOM API + + Use compiler.has_link_argument() for linker flags + + Unscape paths before get from the archive + + Add TOC parse to GepubDoc +- Replace pkgconfig(libsoup-2.4) and pkgconfig(webkit2gtk-4.0) with + pkgconfig(libsoup-3.0) and pkgconfig(webkit2gtk-4.1) + BuildRequires following uptream changes. +- Bump soname following upstreams bump in soname. +- Use ldconfig_scriptlets macro for post(un) handling. + +------------------------------------------------------------------- Old: ---- libgepub-0.6.0.tar.xz New: ---- libgepub-0.7.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libgepub.spec ++++++ --- /var/tmp/diff_new_pack.O7Mj3o/_old 2022-09-21 14:42:55.929838111 +0200 +++ /var/tmp/diff_new_pack.O7Mj3o/_new 2022-09-21 14:42:55.933838122 +0200 @@ -1,7 +1,7 @@ # # spec file for package libgepub # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,21 +12,21 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # -%define basever 0.6 -%define soname 0_6 +%define basever 0.7 +%define soname 0_7 %global sover 0 Name: libgepub -Version: 0.6.0 +Version: 0.7.0 Release: 0 Summary: EPUB document reader and render library License: LGPL-2.1-or-later Group: Development/Languages/C and C++ -URL: https://git.gnome.org/browse/libgepub +URL: https://gitlab.gnome.org/GNOME/libgepub Source0: https://download.gnome.org/sources/%{name}/%{basever}/%{name}-%{version}.tar.xz BuildRequires: meson @@ -37,9 +37,9 @@ BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.30.0 BuildRequires: pkgconfig(gtk+-3.0) BuildRequires: pkgconfig(libarchive) -BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(libsoup-3.0) BuildRequires: pkgconfig(libxml-2.0) -BuildRequires: pkgconfig(webkit2gtk-4.0) +BuildRequires: pkgconfig(webkit2gtk-4.1) %description A GObject-based library for handling and rendering EPUB documents. @@ -79,8 +79,7 @@ %install %meson_install -%post -n %{name}-%{soname}-%{sover} -p /sbin/ldconfig -%postun -n %{name}-%{soname}-%{sover} -p /sbin/ldconfig +%ldconfig_scriptlets -n %{name}-%{soname}-%{sover} %files -n %{name}-%{soname}-%{sover} %license COPYING ++++++ libgepub-0.6.0.tar.xz -> libgepub-0.7.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/.gitignore new/libgepub-0.7.0/.gitignore --- old/libgepub-0.6.0/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/libgepub-0.7.0/.gitignore 2022-08-30 10:59:21.000000000 +0200 @@ -0,0 +1,17 @@ +*.gir +*.typelib +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.* +configure +depcomp +libtool +*.pc +*.stamp +*.la +*.o +*.lo +.deps +.libs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/.gitlab-ci.yml new/libgepub-0.7.0/.gitlab-ci.yml --- old/libgepub-0.6.0/.gitlab-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/libgepub-0.7.0/.gitlab-ci.yml 2022-08-30 10:59:21.000000000 +0200 @@ -0,0 +1,25 @@ +stages: + - build + +variables: + FEDORA_DEPENDENCIES: + gcc + libsoup3-devel + glib2-devel + libxml2-devel + libarchive-devel + gobject-introspection-devel + meson + git + +build-fedora: + image: fedora:latest + stage: build + except: + - tags + before_script: + - dnf update -y --nogpgcheck + - dnf -y install --nogpgcheck $FEDORA_DEPENDENCIES + script: + - meson _build -Dwidget=false + - ninja -C _build dist diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/NEWS new/libgepub-0.7.0/NEWS --- old/libgepub-0.6.0/NEWS 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/NEWS 2022-08-30 10:59:21.000000000 +0200 @@ -1,3 +1,21 @@ +Version 0.7.0 +============= + + - Make gepub-widget configurable with "-Dwidget=false" + - Use libsoup 3.0 + - Fix memory leak + - Remove absolute external resources from gepub + - widget: Disable a number of "Web" features + - widget: Fix ePubs not rendering after the first one + - Stop chapter number updates breaking navigation to anchor links + - Update the chapter number when the page changes + - Work with file paths, not URI substrings, in custom URI scheme + - Do not rewrite page-relative anchor links + - Use new JavaScriptCore GLib API instead of DOM API + - Use compiler.has_link_argument() for linker flags + - Unscape paths before get from the archive + - Add TOC parse to GepubDoc + Version 0.6.0 ============= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub-archive.c new/libgepub-0.7.0/libgepub/gepub-archive.c --- old/libgepub-0.6.0/libgepub/gepub-archive.c 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub-archive.c 2022-08-30 10:59:21.000000000 +0200 @@ -135,12 +135,20 @@ struct archive_entry *entry; guchar *buffer; gint size; + const gchar *_path; + + if (path[0] == '/') { + _path = path + 1; + } + else { + _path = path; + } if (!gepub_archive_open (archive)) return NULL; while (archive_read_next_header (archive->archive, &entry) == ARCHIVE_OK) { - if (g_ascii_strcasecmp (path, archive_entry_pathname (entry)) == 0) + if (g_ascii_strcasecmp (_path, archive_entry_pathname (entry)) == 0) break; archive_read_data_skip (archive->archive); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub-doc.c new/libgepub-0.7.0/libgepub/gepub-doc.c --- old/libgepub-0.6.0/libgepub/gepub-doc.c 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub-doc.c 2022-08-30 10:59:21.000000000 +0200 @@ -51,7 +51,9 @@ static void gepub_doc_fill_resources (GepubDoc *doc); static void gepub_doc_fill_spine (GepubDoc *doc); +static void gepub_doc_fill_toc (GepubDoc *doc, gchar *toc_id); static void gepub_doc_initable_iface_init (GInitableIface *iface); +static gint navpoint_compare (GepubNavPoint *a, GepubNavPoint *b); struct _GepubDoc { GObject parent; @@ -64,6 +66,7 @@ GList *spine; GList *chapter; + GList *toc; }; struct _GepubDocClass { @@ -103,6 +106,8 @@ if (doc->spine) { g_list_foreach (doc->spine, (GFunc)g_free, NULL); g_clear_pointer (&doc->spine, g_list_free); + g_list_foreach (doc->toc, (GFunc)g_free, NULL); + g_clear_pointer (&doc->toc, g_list_free); } G_OBJECT_CLASS (gepub_doc_parent_class)->finalize (object); @@ -198,6 +203,7 @@ GepubDoc *doc = GEPUB_DOC (initable); gchar *file; gint i = 0, len; + g_autofree gchar *unescaped = NULL; g_assert (doc->path != NULL); @@ -210,7 +216,8 @@ } return FALSE; } - doc->content = gepub_archive_read_entry (doc->archive, file); + unescaped = g_uri_unescape_string (file, NULL); + doc->content = gepub_archive_read_entry (doc->archive, unescaped); if (!doc->content) { if (error != NULL) { g_set_error (error, gepub_error_quark (), GEPUB_ERROR_INVALID, @@ -309,12 +316,19 @@ const char *data; gsize size; GList *spine = NULL; + gchar *toc = NULL; data = g_bytes_get_data (doc->content, &size); xdoc = xmlRecoverMemory (data, size); root_element = xmlDocGetRootElement (xdoc); snode = gepub_utils_get_element_by_tag (root_element, "spine"); + toc = gepub_utils_get_prop (snode, "toc"); + if (toc) { + gepub_doc_fill_toc (doc, toc); + g_free (toc); + } + item = snode->children; while (item) { if (item->type != XML_ELEMENT_NODE ) { @@ -334,6 +348,104 @@ xmlFreeDoc (xdoc); } +static gint +navpoint_compare (GepubNavPoint *a, GepubNavPoint *b) +{ + return a->playorder - b->playorder; +} + +static void +gepub_doc_fill_toc (GepubDoc *doc, gchar *toc_id) +{ + xmlDoc *xdoc = NULL; + xmlNode *root_element = NULL; + xmlNode *mapnode = NULL; + xmlNode *item = NULL; + const char *data; + gsize size; + GList *toc = NULL; + GBytes *toc_data = NULL; + + doc->toc = toc; + + toc_data = gepub_doc_get_resource_by_id (doc, toc_id); + if (!toc_data) { + return; + } + + data = g_bytes_get_data (toc_data, &size); + xdoc = xmlRecoverMemory (data, size); + root_element = xmlDocGetRootElement (xdoc); + mapnode = gepub_utils_get_element_by_tag (root_element, "navMap"); + + // TODO: get docTitle + // TODO: parse metadata (dtb:totalPageCount, dtb:depth, dtb:maxPageNumber) + + item = mapnode->children; + while (item) { + GepubNavPoint *navpoint = NULL; + gchar *order; + xmlNode *navchilds = NULL; + + if (item->type != XML_ELEMENT_NODE || + g_strcmp0 ((const gchar *)item->name, "navPoint")) { + item = item->next; + continue; + } + + navpoint = g_malloc0 (sizeof (GepubNavPoint)); + + order = gepub_utils_get_prop (item, "playOrder"); + if (order) { + g_ascii_string_to_unsigned (order, 10, 0, INT_MAX, + &navpoint->playorder, NULL); + g_free (order); + } + + // parsing navPoint->navLabel->text and navPoint->content + navchilds = item->children; + while (navchilds) { + if (item->type != XML_ELEMENT_NODE) { + navchilds = navchilds->next; + continue; + } + + if (!g_strcmp0 ((const gchar *)navchilds->name, "content")) { + gchar **split; + gchar *tmpuri; + tmpuri = gepub_utils_get_prop (navchilds, "src"); + // removing # params. Maybe we should store the # params in the + // navpoint to use in the future if the doc references to a position + // inside the chapter + split = g_strsplit (tmpuri, "#", -1); + + // adding the base path + navpoint->content = g_strdup_printf ("%s%s", doc->content_base, split[0]); + + g_strfreev (split); + g_free (tmpuri); + } + + if (!g_strcmp0 ((const gchar *)navchilds->name, "navLabel")) { + xmlNode *text = gepub_utils_get_element_by_tag (navchilds, "text"); + if (text->children && text->children->type == XML_TEXT_NODE) { + navpoint->label = g_strdup ((gchar *)text->children->content); + } + } + + navchilds = navchilds->next; + } + + toc = g_list_prepend (toc, navpoint); + item = item->next; + } + + doc->toc = g_list_sort (toc, (GCompareFunc) navpoint_compare); + + xmlFreeDoc (xdoc); + g_bytes_unref (toc_data); +} + /** * gepub_doc_get_content: * @doc: a #GepubDoc @@ -410,6 +522,7 @@ gepub_doc_get_resource_by_id (GepubDoc *doc, const gchar *id) { GepubResource *gres; + g_autofree gchar *unescaped = NULL; g_return_val_if_fail (GEPUB_IS_DOC (doc), NULL); g_return_val_if_fail (id != NULL, NULL); @@ -420,7 +533,8 @@ return NULL; } - return gepub_archive_read_entry (doc->archive, gres->uri); + unescaped = g_uri_unescape_string (gres->uri, NULL); + return gepub_archive_read_entry (doc->archive, unescaped); } /** @@ -433,10 +547,16 @@ GBytes * gepub_doc_get_resource (GepubDoc *doc, const gchar *path) { + g_autofree gchar *unescaped = NULL; + g_return_val_if_fail (GEPUB_IS_DOC (doc), NULL); g_return_val_if_fail (path != NULL, NULL); - return gepub_archive_read_entry (doc->archive, path); + // we need to decode the path because we can get URL encoded paths + // like "some%20text.jpg" + unescaped = g_uri_unescape_string (path, NULL); + + return gepub_archive_read_entry (doc->archive, unescaped); } /** @@ -475,15 +595,23 @@ { GepubResource *gres; GList *keys; + const gchar *_path; g_return_val_if_fail (GEPUB_IS_DOC (doc), NULL); g_return_val_if_fail (path != NULL, NULL); + if (path[0] == '/') { + _path = path + 1; + } + else { + _path = path; + } + keys = g_hash_table_get_keys (doc->resources); while (keys) { gres = ((GepubResource*)g_hash_table_lookup (doc->resources, keys->data)); - if (!strcmp (gres->uri, path)) + if (!strcmp (gres->uri, _path)) break; keys = keys->next; } @@ -547,6 +675,7 @@ replaced = gepub_utils_replace_resources (content, base); + g_free (base); g_free (path); g_bytes_unref (content); @@ -803,3 +932,99 @@ return doc->chapter->data; } + +/** + * gepub_doc_get_toc: + * @doc: a #GepubDoc + * + + * Returns: (element-type Gepub.NavPoint) (transfer none): the navigation list in order + */ +GList * +gepub_doc_get_toc (GepubDoc *doc) +{ + g_return_val_if_fail (GEPUB_IS_DOC (doc), NULL); + return doc->toc; +} + +/** + * gepub_doc_resource_uri_to_chapter: + * @doc: a #GepubDoc + * @uri: The resource path + * + * This method tries to find the resource by path in the doc spine and + * will return the index in that list. If the resourse isn't there this method + * will return -1. + + * Returns: the chapter index to use with gepub_doc_set_chapter or -1 if the + * resource isn't found + */ +gint +gepub_doc_resource_uri_to_chapter (GepubDoc *doc, + const gchar *uri) +{ + GHashTableIter iter; + gchar *key; + GepubResource *res; + gchar *id = NULL; + const gchar *_uri; + + if (uri[0] == '/') { + _uri = uri + 1; + } + else { + _uri = uri; + } + + g_return_val_if_fail (GEPUB_IS_DOC (doc), -1); + g_return_val_if_fail (doc->spine != NULL, -1); + + g_hash_table_iter_init (&iter, doc->resources); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&res)) { + if (!g_strcmp0 (res->uri, _uri)) { + id = key; + break; + } + } + + if (!id) { + return -1; + } + + return gepub_doc_resource_id_to_chapter (doc, id); +} + +/** + * gepub_doc_resource_id_to_chapter: + * @doc: a #GepubDoc + * @id: The resource id + * + * This method tries to find the resource by id in the doc spine and + * will return the index in that list. If the resourse isn't there this method + * will return -1. + + * Returns: the chapter index to use with gepub_doc_set_chapter or -1 if the + * resource isn't found + */ +gint +gepub_doc_resource_id_to_chapter (GepubDoc *doc, + const gchar *id) +{ + GList *spine; + gint chapter = 0; + + g_return_val_if_fail (GEPUB_IS_DOC (doc), -1); + g_return_val_if_fail (doc->spine != NULL, -1); + + spine = g_list_first (doc->spine); + while (spine && spine->data) { + if (!g_strcmp0 (spine->data, id)) { + return chapter; + } + chapter++; + spine = spine->next; + } + + return -1; +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub-doc.h new/libgepub-0.7.0/libgepub/gepub-doc.h --- old/libgepub-0.6.0/libgepub/gepub-doc.h 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub-doc.h 2022-08-30 10:59:21.000000000 +0200 @@ -40,7 +40,14 @@ gchar *uri; }; +struct _GepubNavPoint { + gchar *label; + gchar *content; + guint64 playorder; +}; + typedef struct _GepubResource GepubResource; +typedef struct _GepubNavPoint GepubNavPoint; GType gepub_doc_get_type (void) G_GNUC_CONST; @@ -69,6 +76,12 @@ void gepub_doc_set_chapter (GepubDoc *doc, gint index); +GList *gepub_doc_get_toc (GepubDoc *doc); +gint gepub_doc_resource_uri_to_chapter (GepubDoc *doc, + const gchar *uri); +gint gepub_doc_resource_id_to_chapter (GepubDoc *doc, + const gchar *id); + G_END_DECLS /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub-utils.c new/libgepub-0.7.0/libgepub/gepub-utils.c --- old/libgepub-0.6.0/libgepub/gepub-utils.c 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub-utils.c 2022-08-30 10:59:21.000000000 +0200 @@ -42,10 +42,10 @@ gchar *attrname = NULL; - SoupURI *baseURI; + g_autoptr (GUri) baseURI = NULL; gchar *basepath = g_strdup_printf ("epub:///%s/", path); - baseURI = soup_uri_new (basepath); + baseURI = g_uri_parse (basepath, SOUP_HTTP_URI_FLAGS, NULL); g_free (basepath); if (ns) { @@ -58,13 +58,15 @@ if (cur_node->type == XML_ELEMENT_NODE ) { text = xmlGetProp (cur_node, BAD_CAST (attr)); - if (!strcmp ((const char *) cur_node->name, tagname) && text) { - SoupURI *uri = soup_uri_new_with_base (baseURI, (const char *) text); - gchar *value = soup_uri_to_string (uri, FALSE); + if (!strcmp ((const char *) cur_node->name, tagname) && text && text[0] != '#') { + g_autoptr (GUri) uri = g_uri_parse_relative (baseURI, (const char *) text, SOUP_HTTP_URI_FLAGS, NULL); + gchar *value = g_uri_to_string (uri); + + if (!g_str_equal (g_uri_get_scheme (uri), "epub")) + g_clear_pointer (&value, g_free); xmlSetProp (cur_node, BAD_CAST (attrname), BAD_CAST (value)); - soup_uri_free (uri); g_free (value); } if (text) { @@ -78,8 +80,6 @@ } g_free (attrname); - - soup_uri_free (baseURI); } static gboolean diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub-widget.c new/libgepub-0.7.0/libgepub/gepub-widget.c --- old/libgepub-0.6.0/libgepub/gepub-widget.c 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub-widget.c 2022-08-30 10:59:21.000000000 +0200 @@ -89,8 +89,7 @@ gpointer user_data) { WebKitJavascriptResult *js_result; - JSValueRef value; - JSGlobalContextRef context; + JSCValue *value; GError *error = NULL; GepubWidget *widget = GEPUB_WIDGET (user_data); @@ -101,12 +100,11 @@ return; } - context = webkit_javascript_result_get_global_context (js_result); - value = webkit_javascript_result_get_value (js_result); - if (JSValueIsNumber (context, value)) { + value = webkit_javascript_result_get_js_value (js_result); + if (jsc_value_is_number (value)) { double n; - n = JSValueToNumber (context, value, NULL); + n = jsc_value_to_double (value); widget->chapter_length = (int)n; if (widget->init_chapter_pos) { @@ -132,8 +130,7 @@ gpointer user_data) { WebKitJavascriptResult *js_result; - JSValueRef value; - JSGlobalContextRef context; + JSCValue *value; GError *error = NULL; GepubWidget *widget = GEPUB_WIDGET (user_data); @@ -144,12 +141,11 @@ return; } - context = webkit_javascript_result_get_global_context (js_result); - value = webkit_javascript_result_get_value (js_result); - if (JSValueIsNumber (context, value)) { + value = webkit_javascript_result_get_js_value (js_result); + if (jsc_value_is_number (value)) { double n; - n = JSValueToNumber (context, value, NULL); + n = jsc_value_to_double (value); widget->length = (int)n; } else { g_warning ("Error running javascript: unexpected return value"); @@ -231,6 +227,32 @@ } static void +set_current_chapter_by_uri (WebKitWebView *web_view) +{ + GepubWidget *widget = GEPUB_WIDGET (web_view); + const gchar *uri_string; + GUri *uri; + const gchar *path; + gint chapter; + + uri_string = webkit_web_view_get_uri (web_view); + + if (g_strcmp0 ("about:blank", uri_string)) { + uri = g_uri_parse (uri_string, SOUP_HTTP_URI_FLAGS, NULL); + path = g_uri_get_path (uri); + chapter = gepub_doc_resource_uri_to_chapter (widget->doc, path); + gepub_doc_set_chapter (widget->doc, chapter); + g_uri_unref (uri); + } + // Else we're on the cover or table of contents (and can't tell which) + // but we can only get there through setting the chapter number + // so we don't need to do anything here +} + +static void +reload_current_chapter (GepubWidget *widget); + +static void docready_cb (WebKitWebView *web_view, WebKitLoadEvent load_event, gpointer user_data) @@ -239,6 +261,11 @@ if (load_event == WEBKIT_LOAD_FINISHED) { reload_length_cb (GTK_WIDGET (widget), NULL, NULL); + g_signal_handlers_disconnect_by_func (widget->doc, + reload_current_chapter, widget); + set_current_chapter_by_uri (web_view); + g_signal_connect_swapped (widget->doc, "notify::chapter", + G_CALLBACK (reload_current_chapter), widget); } } @@ -247,7 +274,6 @@ { GInputStream *stream; gchar *path; - gchar *uri; gchar *mime; GepubWidget *widget = user_data; GBytes *contents; @@ -255,9 +281,7 @@ if (!widget->doc) return; - uri = g_strdup (webkit_uri_scheme_request_get_uri (request)); - // removing "epub:///" - path = uri + 8; + path = g_strdup (webkit_uri_scheme_request_get_path (request)); contents = gepub_doc_get_resource (widget->doc, path); mime = gepub_doc_get_resource_mime (widget->doc, path); @@ -279,7 +303,7 @@ g_object_unref (stream); g_bytes_unref (contents); g_free (mime); - g_free (uri); + g_free (path); } static void @@ -364,16 +388,45 @@ widget->line_height = 0; } +static GObject * +gepub_widget_constructor (GType gtype, + guint n_properties, + GObjectConstructParam *properties) +{ + GObject *object; + GObjectClass *parent_class; + + parent_class = G_OBJECT_CLASS (gepub_widget_parent_class); + object = parent_class->constructor (gtype, n_properties, properties); + + g_object_set (object, + "web-context", g_object_new (WEBKIT_TYPE_WEB_CONTEXT, NULL), + NULL); + + return object; +} + + static void gepub_widget_constructed (GObject *object) { WebKitWebContext *ctx; + WebKitSettings *settings; GepubWidget *widget = GEPUB_WIDGET (object); G_OBJECT_CLASS (gepub_widget_parent_class)->constructed (object); ctx = webkit_web_view_get_context (WEBKIT_WEB_VIEW (widget)); webkit_web_context_register_uri_scheme (ctx, "epub", resource_callback, widget, NULL); + + settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (widget)); + g_object_set (G_OBJECT (settings), + "enable-javascript-markup", FALSE, + "enable-java", FALSE, + "javascript-can-access-clipboard", FALSE, + "javascript-can-open-windows-automatically", FALSE, + NULL); + g_signal_connect (widget, "load-changed", G_CALLBACK (docready_cb), NULL); g_signal_connect (widget, "size-allocate", G_CALLBACK (reload_length_cb), NULL); } @@ -383,6 +436,7 @@ { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->constructor = gepub_widget_constructor; object_class->constructed = gepub_widget_constructed; object_class->finalize = gepub_widget_finalize; object_class->set_property = gepub_widget_set_property; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/gepub.h new/libgepub-0.7.0/libgepub/gepub.h --- old/libgepub-0.6.0/libgepub/gepub.h 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/gepub.h 2022-08-30 10:59:21.000000000 +0200 @@ -1,9 +1,14 @@ #ifndef _GEPUB__H_ #define _GEPUB__H_ +#include <config.h> + #include "gepub-archive.h" #include "gepub-text-chunk.h" #include "gepub-doc.h" + +#ifdef GEPUB_WIDGET_ENABLED #include "gepub-widget.h" +#endif #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/libgepub/meson.build new/libgepub-0.7.0/libgepub/meson.build --- old/libgepub-0.6.0/libgepub/meson.build 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/libgepub/meson.build 2022-08-30 10:59:21.000000000 +0200 @@ -2,7 +2,6 @@ 'gepub-archive.h', 'gepub-doc.h', 'gepub-text-chunk.h', - 'gepub-widget.h', 'gepub.h' ) @@ -18,15 +17,19 @@ 'gepub-doc.c', 'gepub-text-chunk.c', 'gepub-utils.c', - 'gepub-widget.c' ) +if get_option('widget') + sources += files('gepub-widget.c') + headers += files('gepub-widget.h') +endif + symbol_map = join_paths(meson.current_source_dir(), 'gepub.map') test_ldflag = '-Wl,--version-script,' + symbol_map ldflags = [] -if cc.has_argument(test_ldflag) +if cc.has_link_argument(test_ldflag) ldflags += test_ldflag endif @@ -69,9 +72,12 @@ gir_incs = [ 'GObject-2.0', 'libxml2-2.0', - 'WebKit2-4.0' ] + if get_option('widget') + gir_incs += ['WebKit2-4.1'] + endif + gir_extra_args = '--warn-all' gir_dir = join_paths(gepub_datadir, '@0@-@1@'.format('gir', gepub_gir_version)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/meson.build new/libgepub-0.7.0/meson.build --- old/libgepub-0.6.0/meson.build 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/meson.build 2022-08-30 10:59:21.000000000 +0200 @@ -1,9 +1,9 @@ project( 'libgepub', 'c', - version: '0.6.0', + version: '0.7.0', license: 'LGPL2+', default_options: 'buildtype=debugoptimized', - meson_version: '>= 0.41.0' + meson_version: '>= 0.46.0' ) gepub_version = meson.project_version() @@ -31,8 +31,7 @@ cc = meson.get_compiler('c') gepub_deps = [ - dependency('webkit2gtk-4.0'), - dependency('libsoup-2.4'), + dependency('libsoup-3.0'), dependency('glib-2.0'), dependency('gobject-2.0'), dependency('gio-2.0'), @@ -40,15 +39,29 @@ dependency('libarchive') ] +if get_option('widget') + webkit2gtk = dependency('webkit2gtk-4.1') + gepub_deps += [webkit2gtk] +endif + gnome = import('gnome') pkg = import('pkgconfig') top_inc = include_directories('.') subdir('libgepub') -subdir('tests') + +if get_option('widget') + subdir('tests') +endif + +config_h = configuration_data() + +if get_option('widget') + config_h.set('GEPUB_WIDGET_ENABLED', 1) +endif configure_file( output: 'config.h', - configuration: configuration_data() + configuration: config_h, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/meson_options.txt new/libgepub-0.7.0/meson_options.txt --- old/libgepub-0.6.0/meson_options.txt 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/meson_options.txt 2022-08-30 10:59:21.000000000 +0200 @@ -1 +1,2 @@ option('introspection', type: 'boolean', value: true, description: 'Enable GObject Introspection (depends on GObject)') +option('widget', type: 'boolean', value: true, description: 'Build with GepubWidget based on Webkit') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.6.0/tests/test-gepub.c new/libgepub-0.7.0/tests/test-gepub.c --- old/libgepub-0.6.0/tests/test-gepub.c 2018-03-15 08:39:19.000000000 +0100 +++ new/libgepub-0.7.0/tests/test-gepub.c 2022-08-30 10:59:21.000000000 +0200 @@ -10,12 +10,13 @@ GtkTextBuffer *page_buffer; GtkWidget *PAGE_LABEL; -#define PTEST1(...) printf (__VA_ARGS__) -#define PTEST2(...) buf = g_strdup_printf (__VA_ARGS__);\ - tmpbuf = buf2;\ - buf2 = g_strdup_printf ("%s%s", buf2, buf);\ - g_free (buf);\ - g_free (tmpbuf) +#define PTEST1(...) { printf (__VA_ARGS__); } +#define PTEST2(...) { buf = g_strdup_printf (__VA_ARGS__);\ + tmpbuf = buf2;\ + buf2 = g_strdup_printf ("%s%s", buf2, buf);\ + g_free (buf);\ + g_free (tmpbuf);\ + } #define PTEST PTEST2 #define TEST(f,arg...) PTEST ("\n### TESTING " #f " ###\n\n"); f (arg); PTEST ("\n\n"); @@ -214,15 +215,20 @@ gchar *author = gepub_doc_get_metadata (doc, GEPUB_META_AUTHOR); gchar *description = gepub_doc_get_metadata (doc, GEPUB_META_DESC); gchar *cover = gepub_doc_get_cover (doc); - gchar *cover_mime = gepub_doc_get_resource_mime_by_id (doc, cover); + gchar *cover_mime = NULL; + + if (cover) + cover_mime = gepub_doc_get_resource_mime_by_id (doc, cover); PTEST ("title: %s\n", title); PTEST ("author: %s\n", author); PTEST ("id: %s\n", id); PTEST ("lang: %s\n", lang); PTEST ("desc: %s\n", description); - PTEST ("cover: %s\n", cover); - PTEST ("cover mime: %s\n", cover_mime); + if (cover) + PTEST ("cover: %s\n", cover); + if (cover_mime) + PTEST ("cover mime: %s\n", cover_mime); g_free (title); g_free (lang); @@ -254,7 +260,7 @@ ncx = gepub_doc_get_resource_by_id (doc, "ncx"); data = g_bytes_get_data (ncx, &size); - PTEST ("ncx:\n%s\n", data); + PTEST ("ncx:\n%.*s\n", size, data); g_bytes_unref (ncx); g_object_unref (G_OBJECT (doc)); @@ -274,6 +280,22 @@ } static void +test_doc_toc (const char *path) +{ + GepubDoc *doc = gepub_doc_new (path, NULL); + + GList *nav = gepub_doc_get_toc (doc); + while (nav && nav->data) { + GepubNavPoint *point = (GepubNavPoint*)nav->data; + PTEST ("%02d: %s -> %s\n", (gint)point->playorder, point->label, point->content); + PTEST (" -> Chapter: %d\n", gepub_doc_resource_uri_to_chapter (doc, point->content)); + nav = nav->next; + } + + g_object_unref (G_OBJECT (doc)); +} + +static void destroy_cb (GtkWidget *window, GtkWidget *view) { @@ -435,6 +457,7 @@ TEST(test_doc_name, argv[1]) TEST(test_doc_resources, argv[1]) TEST(test_doc_spine, argv[1]) + TEST(test_doc_toc, argv[1]) // Freeing the mallocs :P if (buf2) {