summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhaedrus Leeds <mwleeds@protonmail.com>2022-03-30 11:49:07 -0700
committerPhaedrus Leeds <mwleeds@protonmail.com>2022-03-30 11:49:07 -0700
commitb29e56b86f1548c88fc51200a252d534b3625a80 (patch)
treed01ca97c89a77c56f886a518a21783072727d2aa
parent9eda3c4c1f9ae41bcbd4a84a15e4bc01e3fe3569 (diff)
downloadepiphany-mwleeds/webapp-manifest-support.tar.gz
WIP: Copy Sonny's impl for manifest supportmwleeds/webapp-manifest-support
-rw-r--r--embed/ephy-web-view.c53
-rw-r--r--embed/ephy-web-view.h8
-rw-r--r--embed/web-process-extension/resources/js/ephy.js5
-rw-r--r--src/window-commands.c130
4 files changed, 196 insertions, 0 deletions
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index d8521a012..8812f1ddd 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -3507,6 +3507,59 @@ ephy_web_view_get_web_app_title_finish (EphyWebView *view,
}
static void
+get_web_app_manifest_url_cb (WebKitWebView *view,
+ GAsyncResult *result,
+ GTask *task)
+{
+ WebKitJavascriptResult *js_result;
+ GError *error = NULL;
+
+ js_result = webkit_web_view_run_javascript_in_world_finish (view, result, &error);
+ if (js_result) {
+ JSCValue *js_value;
+ char *retval = NULL;
+
+ js_value = webkit_javascript_result_get_js_value (js_result);
+ if (!jsc_value_is_null (js_value) && !jsc_value_is_undefined (js_value))
+ retval = jsc_value_to_string (js_value);
+ g_task_return_pointer (task, retval, (GDestroyNotify)g_free);
+ webkit_javascript_result_unref (js_result);
+ } else
+ g_task_return_error (task, error);
+
+ g_object_unref (task);
+}
+
+void
+ephy_web_view_get_web_app_manifest_url (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_assert (EPHY_IS_WEB_VIEW (view));
+
+ task = g_task_new (view, cancellable, callback, user_data);
+ webkit_web_view_run_javascript_in_world (WEBKIT_WEB_VIEW (view),
+ "Ephy.getWebAppManifestURL();",
+ ephy_embed_shell_get_guid (ephy_embed_shell_get_default ()),
+ cancellable,
+ (GAsyncReadyCallback)get_web_app_manifest_url_cb,
+ task);
+}
+
+char *
+ephy_web_view_get_web_app_manifest_url_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (g_task_is_valid (result, view));
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
get_web_app_mobile_capable_cb (WebKitWebView *view,
GAsyncResult *result,
GTask *task)
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index 5e45cb861..c4b2bf380 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -147,6 +147,14 @@ void ephy_web_view_get_web_app_title (EphyWebView
char *ephy_web_view_get_web_app_title_finish (EphyWebView *view,
GAsyncResult *result,
GError **error);
+
+void ephy_web_view_get_web_app_manifest_url (EphyWebView *view,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+char *ephy_web_view_get_web_app_manifest_url_finish (EphyWebView *view,
+ GAsyncResult *result,
+ GError **error);
void ephy_web_view_get_web_app_mobile_capable (EphyWebView *view,
GCancellable *cancellable,
GAsyncReadyCallback callback,
diff --git a/embed/web-process-extension/resources/js/ephy.js b/embed/web-process-extension/resources/js/ephy.js
index 38b806f7a..ea7da8b9e 100644
--- a/embed/web-process-extension/resources/js/ephy.js
+++ b/embed/web-process-extension/resources/js/ephy.js
@@ -18,6 +18,11 @@ Ephy.getAppleMobileWebAppCapable = function()
return false;
};
+Ephy.getWebAppManifestURL = function () {
+ const manifest = document.head.querySelector("link[rel=manifest]");
+ return manifest ? manifest.href : null;
+}
+
Ephy.getWebAppTitle = function()
{
const metas = document.getElementsByTagName('meta');
diff --git a/src/window-commands.c b/src/window-commands.c
index 8a7e52b91..779aa8447 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -23,6 +23,7 @@
#include "config.h"
+#include "ephy-web-view.h"
#include "window-commands.h"
#include "ephy-bookmarks-export.h"
@@ -1389,6 +1390,8 @@ typedef struct {
EphyWebApplicationOptions webapp_options;
gboolean webapp_options_set;
WebKitDownload *download;
+ char *manifest_url;
+ WebKitDownload *download_manifest;
EphyWindow *window;
} EphyApplicationDialogData;
@@ -1450,6 +1453,13 @@ ephy_application_dialog_data_free (EphyApplicationDialogData *data)
data->download = NULL;
}
+ if (data->download_manifest) {
+ g_signal_handlers_disconnect_by_func (data->download_manifest, download_manifest_finished_cb, data);
+ g_signal_handlers_disconnect_by_func (data->download_manifest, download_manifest_failed_cb, data);
+
+ data->download = NULL;
+ }
+
g_cancellable_cancel (data->cancellable);
g_object_unref (data->cancellable);
g_object_unref (data->window);
@@ -1458,6 +1468,7 @@ ephy_application_dialog_data_free (EphyApplicationDialogData *data)
if (data->icon_v)
g_variant_unref (data->icon_v);
g_free (data->icon_href);
+ g_free (data->manifest_url);
g_free (data->title);
g_free (data->chosen_name);
g_free (data->token);
@@ -1774,6 +1785,122 @@ fill_default_application_title_cb (GObject *source,
ephy_application_dialog_data_free (data);
}
+
+static void
+download_manifest_finished_cb (WebKitDownload *download,
+ EphyApplicationDialogData *data)
+{
+ char *filename;
+ GError *error = NULL;
+ JsonParser *parser = json_parser_new();
+ JsonNode *root;
+ JsonObject *manifest_object;
+ char *name;
+ char *short_name;
+
+ filename = g_filename_from_uri (webkit_download_get_destination (download), NULL, NULL);
+ json_parser_load_from_file(parser, filename, &error);
+ g_free (filename);
+ if (error) {
+ g_warning ("Unable to parse manifest");
+ g_error_free (error);
+ g_object_unref (parser);
+ return;
+ }
+
+ root = json_parser_get_root (parser);
+ manifest_object = json_node_get_object(root);
+
+ name = json_object_get_string_member(manifest_object, "name");
+ short_name = json_object_get_string_member(manifest_object, "short_name");
+
+ if (short_name) {
+ g_message (short_name);
+ // data->name = short_name;
+ } else if (name) {
+ g_message (name);
+ // data->name = name;
+ }
+
+ g_free (name);
+ g_free (short_name);
+
+ g_object_unref (parser);
+}
+
+static void
+download_manifest_failed_cb (WebKitDownload *download,
+ GError *error,
+ EphyApplicationDialogData *data)
+{
+ g_warning("failed");
+
+ g_signal_handlers_disconnect_by_func (download, download_manifest_finished_cb, data);
+
+ // TODO fallback to ephy.js stuff
+}
+
+static void
+download_and_use_manifest (EphyApplicationDialogData *data)
+{
+ char *destination, *destination_uri, *tmp_filename;
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
+
+ data->download_manifest = webkit_web_context_download_uri (ephy_embed_shell_get_web_context (shell),
+ data->manifest_url);
+ /* We do not want this download to show up in the UI, so let's
+ * set 'ephy-download-set' to make Epiphany think this is
+ * already there. */
+ /* FIXME: it's probably better to just do this in a clean way
+ * instead of using this workaround. */
+ g_object_set_data (G_OBJECT (data->download_manifest), "ephy-download-set", GINT_TO_POINTER (TRUE));
+ tmp_filename = ephy_file_tmp_filename (".ephy-download-XXXXXX", NULL);
+ destination = g_build_filename (ephy_file_tmp_dir (), tmp_filename, NULL);
+ destination_uri = g_filename_to_uri (destination, NULL, NULL);
+ g_message("%s", destination_uri);
+ webkit_download_set_destination (data->download_manifest, destination_uri);
+ g_free (destination);
+ g_free (destination_uri);
+ g_free (tmp_filename);
+
+ g_message("foobar!");
+
+
+ g_signal_connect (data->download_manifest, "finished",
+ G_CALLBACK (download_manifest_finished_cb), data);
+ g_signal_connect (data->download_manifest, "failed",
+ G_CALLBACK (download_manifest_failed_cb), data);
+}
+
+static void
+got_manifest_url_cb (GObject *source,
+ GAsyncResult *async_result,
+ gpointer user_data)
+{
+ EphyApplicationDialogData *data = user_data;
+ char *manifest_url;
+ GError *error = NULL;
+
+ manifest_url = ephy_web_view_get_web_app_manifest_url_finish (EPHY_WEB_VIEW (source), async_result, &error);
+ g_message("%s", manifest_url);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ data->manifest_url = manifest_url;
+ g_message("%s", manifest_url);
+ if (data->manifest_url != NULL)
+ download_and_use_manifest (data);
+
+ // TODO: fallback to ephy.js stuff
+}
+
+static void
+do_something_with_manifest (EphyApplicationDialogData *data)
+{
+ ephy_web_view_get_web_app_manifest_url (data->view, data->cancellable, got_manifest_url_cb, data);
+}
+
static void
fill_mobile_capable_cb (GObject *source,
GAsyncResult *async_result,
@@ -1957,6 +2084,9 @@ window_cmd_save_as_application (GSimpleAction *action,
ephy_web_view_get_best_web_app_icon (data->view, data->cancellable, fill_default_application_image_cb, data);
ephy_web_view_get_web_app_title (data->view, data->cancellable, fill_default_application_title_cb, data);
ephy_web_view_get_web_app_mobile_capable (data->view, data->cancellable, fill_mobile_capable_cb, data);
+ //TODO is this right
+ do_something_with_manifest (data);
+
}
static char *