[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