[webkit-gtk] rendering page from gresource

Michael Trimarchi michael at amarulasolutions.com
Mon Mar 22 08:01:38 PDT 2021


Hi

On Mon, Mar 22, 2021 at 12:42:42PM +0200, Adrian Perez de Castro wrote:
> Hi again,
> 
> On Mon, 22 Mar 2021 11:28:54 +0100 Michael Nazzareno Trimarchi <michael at amarulasolutions.com> wrote:
> > Hi
> > 
> > On Mon, Mar 22, 2021 at 11:19 AM Adrian Perez de Castro
> > <aperez at igalia.com> wrote:
> > >
> > > Hello Michael,
> > >
> > > On Sun, 21 Mar 2021 20:28:44 +0100 Michael Nazzareno Trimarchi <michael at amarulasolutions.com> wrote:
> > >
> > > > I'm playing a bit with Alexa and gtkmm and I'm trying to do really
> > > > simple things. Read from the resource index.html and main...js
> > > >
> > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > <gresources>
> > > >   <gresource prefix="@APPLICATION_PREFIX@">
> > > >     <file preprocess="xml-stripblanks">ui/window.glade</file>
> > > >     <file preprocess="xml-stripblanks">ui/headerbar.glade</file>
> > > >     <file preprocess="xml-stripblanks">ui/preferences.glade</file>
> > > >     <file preprocess="xml-stripblanks">ui/menu.glade</file>
> > > >     <file>alexa/index.html</file>
> > > >     <file>alexa/main.bundle.js</file>
> > > >     <file>icons/48x48/icon.png</file>
> > > >   </gresource>
> > > > </gresources>
> > > >
> > > > Things are inside the resource and
> > > >
> > > > webview->load_uri(projectdefinitions::getApplicationPrefix() +
> > > > "alexa/index.html");
> > > > webview->set_visible();
> > > >
> > > > This does not fail but:
> > > > gtk_on_load_changed(WebKitWebView* webView, WebKitLoadEvent loadEvent,
> > > > gpointer userData)
> > > >
> > > > this is not triggered. If I load from a local file things are ok. Can
> > > > anyone knows what is going on?
> > >
> > > What does “getApplicationPrefix()” return? I suspect that the load-changed
> > > signal is not being emitted because there is a load error caused by an invalid
> > > URI, or an URI that has a scheme that is unknown to WebKit.
> > >
> > > The best option to make WebKit load content from a GResource bundle is to
> > > use “webkit_web_context_register_uri_scheme()” to install a custom URI scheme
> > > handler for resources. You can find the documentation here:
> > >
> > >   https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebContext.html#webkit-web-context-register-uri-scheme
> > >
> > 

>From cf3cc10ace2de2dec9e4d1637e8a8ef5ef8ea0a3 Mon Sep 17 00:00:00 2001
From: Michael Trimarchi <michael at amarulasolutions.com>
Date: Mon, 22 Mar 2021 15:27:50 +0100
Subject: [PATCH] Add loading of alexa resources

Add a way to load alexa resource from the resource file

Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
---
 data/gresource.xml.in |  3 +++
 src/gtkwebview.cpp    | 29 +++++++++++++++++++++++++++++
 src/window.cpp        |  3 ++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/data/gresource.xml.in b/data/gresource.xml.in
index 84a2c58..c387e8b 100644
--- a/data/gresource.xml.in
+++ b/data/gresource.xml.in
@@ -5,6 +5,9 @@
     <file preprocess="xml-stripblanks">ui/headerbar.glade</file>
     <file preprocess="xml-stripblanks">ui/preferences.glade</file>
     <file preprocess="xml-stripblanks">ui/menu.glade</file>
+    <file>alexa/index.html</file>
+    <file>alexa/main.bundle.js</file>
+    <file>alexa/4444bbbc2f4dd0a9586f053308ab9a1a.png</file>
     <file>icons/48x48/icon.png</file>
   </gresource>
 </gresources>
diff --git a/src/gtkwebview.cpp b/src/gtkwebview.cpp
index 58ad1c6..cdf2333 100644
--- a/src/gtkwebview.cpp
+++ b/src/gtkwebview.cpp
@@ -21,9 +21,38 @@ static void gtk_on_load_changed(WebKitWebView* webView, WebKitLoadEvent loadEven
     }
 }
 
+static void gtk_web_view_filter_resource(WebKitURISchemeRequest *request, gpointer user_data)
+{
+    std::string path;
+    gsize size;
+    g_autoptr (GInputStream) stream = NULL;
+    g_autoptr (GError) error = NULL;
+
+    path = webkit_uri_scheme_request_get_path(request);
+    path = "/org" + path;
+

This is the funny part. The org is removed and I need to add it in the
filter

+    if (!g_resources_get_info (path.c_str(), (GResourceLookupFlags) 0, &size, NULL, &error)) {
+        webkit_uri_scheme_request_finish_error(request, error);
+        return;
+    }
+
+    stream = g_resources_open_stream (path.c_str(), (GResourceLookupFlags)0, &error);
+    if (stream)
+        webkit_uri_scheme_request_finish(request, stream, size, NULL);
+    else
+        webkit_uri_scheme_request_finish_error(request, error);
+}
+
 GtkWebView::GtkWebView() : Gtk::Widget(webkit_web_view_new())
 {
+    WebKitWebContext *context = webkit_web_context_get_default();
     g_signal_connect(*this, "load-changed", G_CALLBACK(gtk_on_load_changed), this);
+
+    /* register to load gresource files */
+    webkit_web_context_register_uri_scheme(context, "alexa-org",
+		                           gtk_web_view_filter_resource, NULL, NULL);
+

resource is not a valid filter as uri. So I think that is valid in
webkit

Michael

+    webkit_security_manager_register_uri_scheme_as_secure(webkit_web_context_get_security_manager(context), "alexa-org");
 }
 
 GtkWebView::operator WebKitWebView*()
diff --git a/src/window.cpp b/src/window.cpp
index 6a2e666..ee0df30 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -22,7 +22,8 @@ Window::Window(Gtk::ApplicationWindow::BaseObjectType* cobject, const Glib::RefP
 
     GtkWebView  *webview = new GtkWebView;
     scrolledView->add(*webview);
-    webview->load_uri("https://www.amarulasolutions.com");
+
+    webview->load_uri("alexa-org:/" + projectdefinitions::getApplicationPrefix() + "alexa/index.html");
     webview->set_visible();
 
     settings = Gio::Settings::create(projectdefinitions::getApplicationID());
-- 
2.25.1

> > Yes, I know but ->
> > 
> > resources that are local inside the page need to be loaded so we need
> > to intercept load resource signals to get them
> > somehow.
> 
> Let's say you have this HTML:
> 
>   <html>
>     <head>
> 	  <script src="main.js" type="text/javascript"></script>
> 	<!-- ... -->
> 
> If you load that page using an URI like “resource:/index.html”, then the
> script resource will have “resource:/main.js” as its URI, and the custom URI
> scheme handler also takes care of it. The same will happen with all the other
> resources used by the page =)
> 
> (This is precisely the reason to use a custom URI scheme handler: everything
> will “just work” as expected.)
> 
> > > If you want a more complete code example, GNOME Web (a.k.a. Epiphany) uses
> > > this. You can see the code here:
> > >
> > >   https://gitlab.gnome.org/GNOME/epiphany/-/blob/701aa05d70bb206cee67bfc9e834784f88000a30/embed/ephy-embed-shell.c#L934
> > >   https://gitlab.gnome.org/GNOME/epiphany/-/blob/701aa05d70bb206cee67bfc9e834784f88000a30/embed/ephy-embed-shell.c#L711
> > >
> > > I hope this helps =)
> > 
> > I will give it a try. I think that the change should be landed inside
> > the webkit gtk component.
> 
> This features does not belong inside WebKitGTK, sorry: Not all the
> applications that use WebKitGTK are interested in allowing web views to load
> contents of their GResource bundles.
> 
> WebKitGTK provides support for custom URI scheme handlers so the applications
> which need this feature can provide it themselves with a few lines of code :)
> 
> Best regards,
> -Adrian




More information about the webkit-gtk mailing list