diff options
author | Phaedrus Leeds <mwleeds@protonmail.com> | 2022-03-30 11:49:07 -0700 |
---|---|---|
committer | Phaedrus Leeds <mwleeds@protonmail.com> | 2022-03-30 11:49:07 -0700 |
commit | b29e56b86f1548c88fc51200a252d534b3625a80 (patch) | |
tree | d01ca97c89a77c56f886a518a21783072727d2aa | |
parent | 9eda3c4c1f9ae41bcbd4a84a15e4bc01e3fe3569 (diff) | |
download | epiphany-mwleeds/webapp-manifest-support.tar.gz |
WIP: Copy Sonny's impl for manifest supportmwleeds/webapp-manifest-support
-rw-r--r-- | embed/ephy-web-view.c | 53 | ||||
-rw-r--r-- | embed/ephy-web-view.h | 8 | ||||
-rw-r--r-- | embed/web-process-extension/resources/js/ephy.js | 5 | ||||
-rw-r--r-- | src/window-commands.c | 130 |
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 * |