[epiphany/pgriffis/web-extension-fixes-2: 9/11] WebExtensions: Fix translation support
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/pgriffis/web-extension-fixes-2: 9/11] WebExtensions: Fix translation support
- Date: Wed, 18 May 2022 18:59:32 +0000 (UTC)
commit e6212d987f773c4cef9c39232bf3495f070425d9
Author: Patrick Griffis <pgriffis igalia com>
Date: Wed May 18 13:30:18 2022 -0500
WebExtensions: Fix translation support
embed/ephy-embed-shell.c | 5 +-
.../ephy-web-process-extension-main.c | 3 +-
.../ephy-web-process-extension.c | 59 ++++++++++++++++++----
.../web-process-extension/ephy-webextension-api.c | 52 ++++++++++++++-----
.../ephy-webextension-common.c | 20 +++++++-
.../ephy-webextension-common.h | 5 +-
src/webextension/ephy-web-extension-manager.c | 37 ++++++++------
src/webextension/ephy-web-extension.c | 1 +
8 files changed, 136 insertions(+), 46 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 97caf1f14..b4a904bff 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -783,12 +783,13 @@ initialize_web_process_extensions (WebKitWebContext *web_context,
#endif
private_profile = priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE || priv->mode ==
EPHY_EMBED_SHELL_MODE_INCOGNITO || priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION;
- user_data = g_variant_new ("(smsbbb)",
+ user_data = g_variant_new ("(smsbbbs)",
priv->guid,
ephy_profile_dir_is_default () ? NULL : ephy_profile_dir (),
g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS),
private_profile,
- FALSE);
+ FALSE,
+ "");
webkit_web_context_set_web_extensions_initialization_user_data (web_context, g_steal_pointer (&user_data));
}
diff --git a/embed/web-process-extension/ephy-web-process-extension-main.c
b/embed/web-process-extension/ephy-web-process-extension-main.c
index 63fee6605..cfb2584ec 100644
--- a/embed/web-process-extension/ephy-web-process-extension-main.c
+++ b/embed/web-process-extension/ephy-web-process-extension-main.c
@@ -37,12 +37,13 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
{
const char *guid;
const char *profile_dir;
+ const char *webextension_translations;
gboolean private_profile;
gboolean should_remember_passwords;
gboolean is_webextension;
g_autoptr (GError) error = NULL;
- g_variant_get (user_data, "(&sm&sbbb)", &guid, &profile_dir, &should_remember_passwords, &private_profile,
&is_webextension);
+ g_variant_get (user_data, "(&sm&sbbb&s)", &guid, &profile_dir, &should_remember_passwords,
&private_profile, &is_webextension, &webextension_translations);
if (!ephy_file_helpers_init (profile_dir, 0, &error))
g_warning ("Failed to initialize file helpers: %s", error->message);
diff --git a/embed/web-process-extension/ephy-web-process-extension.c
b/embed/web-process-extension/ephy-web-process-extension.c
index fe216a589..cbe4f15fe 100644
--- a/embed/web-process-extension/ephy-web-process-extension.c
+++ b/embed/web-process-extension/ephy-web-process-extension.c
@@ -64,12 +64,6 @@ struct _EphyWebProcessExtension {
G_DEFINE_TYPE (EphyWebProcessExtension, ephy_web_process_extension, G_TYPE_OBJECT)
-GHashTable *
-ephy_web_process_extension_get_translations (EphyWebProcessExtension *extension)
-{
- return extension->translation_table;
-}
-
static void
web_page_will_submit_form (WebKitWebPage *web_page,
WebKitDOMHTMLFormElement *dom_form,
@@ -233,10 +227,15 @@ content_script_window_object_cleared_cb (WebKitScriptWorld *world,
WebKitFrame *frame,
gpointer user_data)
{
+ EphyWebProcessExtension *extension = user_data;
g_autoptr (JSCContext) js_context = NULL;
+ JsonObject *translations;
+ const char *guid;
+ guid = webkit_script_world_get_name (world);
js_context = webkit_frame_get_js_context_for_script_world (frame, world);
- ephy_webextension_install_common_apis (js_context, webkit_script_world_get_name (world));
+ translations = g_hash_table_lookup (extension->translation_table, guid);
+ ephy_webextension_install_common_apis (js_context, guid, translations);
}
static void
@@ -250,7 +249,7 @@ create_content_script_world (EphyWebProcessExtension *extension,
g_signal_connect (world,
"window-object-cleared",
G_CALLBACK (content_script_window_object_cleared_cb),
- NULL);
+ extension);
}
static gboolean
@@ -299,6 +298,34 @@ ephy_web_process_extension_page_created_cb (EphyWebProcessExtension *extension,
extension);
}
+static void
+ephy_web_process_extension_add_translations (GHashTable *translation_table,
+ const char *guid,
+ const char *data)
+{
+ g_autoptr (JsonParser) parser = NULL;
+ JsonNode *root;
+ JsonObject *root_object;
+ g_autoptr (GError) error = NULL;
+
+ g_hash_table_remove (translation_table, guid);
+
+ if (!data || !*data)
+ return;
+
+ parser = json_parser_new ();
+ if (json_parser_load_from_data (parser, data, -1, &error)) {
+ root = json_parser_get_root (parser);
+ g_assert (root);
+ root_object = json_node_get_object (root);
+ g_assert (root_object);
+
+ g_hash_table_insert (translation_table, g_strdup (guid), json_object_ref (root_object));
+ } else {
+ g_warning ("Could not read translation json data: %s. '%s'", error->message, data);
+ }
+}
+
static void
ephy_web_process_extension_user_message_received_cb (EphyWebProcessExtension *extension,
WebKitUserMessage *message)
@@ -387,8 +414,17 @@ ephy_web_process_extension_user_message_received_cb (EphyWebProcessExtension *ex
return;
g_variant_get (parameters, "b", &extension->should_remember_passwords);
- } else {
- g_warning ("Unhandled user-message: %s", name);
+ } else if (g_strcmp0 (name, "WebExtension.UpdateTranslations") == 0) {
+ GVariant *parameters;
+ const char *guid;
+ const char *data;
+
+ parameters = webkit_user_message_get_parameters (message);
+ if (!parameters)
+ return;
+
+ g_variant_get (parameters, "(&s&s)", &guid, &data);
+ ephy_web_process_extension_add_translations (extension->translation_table, guid, data);
}
}
@@ -867,7 +903,8 @@ ephy_web_process_extension_initialize (EphyWebProcessExtension *extension,
extension->frames_map = g_hash_table_new_full (g_int64_hash, g_int64_equal,
g_free, NULL);
- extension->translation_table = g_hash_table_new (g_str_hash, NULL);
+ extension->translation_table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)json_object_unref);
extension->content_script_worlds = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
diff --git a/embed/web-process-extension/ephy-webextension-api.c
b/embed/web-process-extension/ephy-webextension-api.c
index 9499899f6..02302abc6 100644
--- a/embed/web-process-extension/ephy-webextension-api.c
+++ b/embed/web-process-extension/ephy-webextension-api.c
@@ -35,7 +35,7 @@ struct _EphyWebExtensionExtension {
WebKitScriptWorld *script_world;
- GHashTable *translation_table;
+ JsonObject *translations;
int counter;
};
@@ -43,12 +43,6 @@ G_DEFINE_TYPE (EphyWebExtensionExtension, ephy_web_extension_extension, G_TYPE_O
static EphyWebExtensionExtension *extension = NULL;
-static GHashTable *
-ephy_web_extension_extension_get_translations (EphyWebExtensionExtension *extension)
-{
- return extension->translation_table;
-}
-
static void
ephy_web_extension_page_user_message_received_cb (WebKitWebPage *page,
WebKitUserMessage *message)
@@ -114,7 +108,7 @@ ephy_web_extension_dispose (GObject *object)
g_clear_object (&extension->extension);
g_clear_pointer (&extension->guid, g_free);
- g_clear_pointer (&extension->translation_table, g_hash_table_destroy);
+ g_clear_pointer (&extension->translations, json_object_unref);
G_OBJECT_CLASS (ephy_web_extension_extension_parent_class)->dispose (object);
}
@@ -163,7 +157,7 @@ window_object_cleared_cb (WebKitScriptWorld *world,
js_context = webkit_frame_get_js_context_for_script_world (frame, world);
- ephy_webextension_install_common_apis (js_context, extension->guid);
+ ephy_webextension_install_common_apis (js_context, extension->guid, extension->translations);
js_browser = jsc_context_get_value (js_context, "browser");
g_assert (jsc_value_is_object (js_browser));
@@ -174,10 +168,38 @@ window_object_cleared_cb (WebKitScriptWorld *world,
g_clear_object (&result);
}
+static void
+ephy_web_extension_extension_update_translations (EphyWebExtensionExtension *extension,
+ const char *data)
+{
+ g_autoptr (JsonParser) parser = NULL;
+ JsonNode *root;
+ JsonObject *root_object;
+ g_autoptr (GError) error = NULL;
+
+ g_clear_pointer (&extension->translations, json_object_unref);
+
+ if (!data || !*data)
+ return;
+
+ parser = json_parser_new ();
+ if (json_parser_load_from_data (parser, data, -1, &error)) {
+ root = json_parser_get_root (parser);
+ g_assert (root);
+ root_object = json_node_get_object (root);
+ g_assert (root_object);
+
+ extension->translations = json_object_ref (root_object);
+ } else {
+ g_warning ("Could not read translation json data: %s. '%s'", error->message, data);
+ }
+}
+
void
ephy_web_extension_extension_initialize (EphyWebExtensionExtension *extension,
WebKitWebExtension *wk_extension,
- const char *guid)
+ const char *guid,
+ const char *translations)
{
g_assert (EPHY_IS_WEB_EXTENSION_EXTENSION (extension));
@@ -197,11 +219,11 @@ ephy_web_extension_extension_initialize (EphyWebExtensionExtension *extension,
extension->extension = g_object_ref (wk_extension);
+ ephy_web_extension_extension_update_translations (extension, translations);
+
g_signal_connect_swapped (extension->extension, "page-created",
G_CALLBACK (ephy_web_extension_extension_page_created_cb),
extension);
-
- extension->translation_table = g_hash_table_new (g_str_hash, NULL);
}
G_MODULE_EXPORT void
@@ -210,11 +232,12 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
{
const char *guid;
const char *profile_dir;
+ const char *webextension_translations;
gboolean private_profile;
gboolean should_remember_passwords;
gboolean is_webextension;
- g_variant_get (user_data, "(&sm&sbbb)", &guid, &profile_dir, &should_remember_passwords, &private_profile,
&is_webextension);
+ g_variant_get (user_data, "(&sm&sbbb&s)", &guid, &profile_dir, &should_remember_passwords,
&private_profile, &is_webextension, &webextension_translations);
if (!is_webextension)
return;
@@ -223,7 +246,8 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
ephy_web_extension_extension_initialize (extension,
webkit_extension,
- guid);
+ guid,
+ webextension_translations);
}
static void __attribute__((destructor))
diff --git a/embed/web-process-extension/ephy-webextension-common.c
b/embed/web-process-extension/ephy-webextension-common.c
index 0854641bb..ce341c16e 100644
--- a/embed/web-process-extension/ephy-webextension-common.c
+++ b/embed/web-process-extension/ephy-webextension-common.c
@@ -26,6 +26,19 @@ static char *
js_getmessage (const char *message,
gpointer user_data)
{
+ JsonObject *translations = user_data;
+ g_autoptr (JsonObject) translation = NULL;
+
+ if (!translations)
+ return g_strdup (message);
+
+ translation = json_object_get_object_member (translations, message);
+ if (translation) {
+ /* FIXME: Implement placeholders:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization */
+ const char *translated_message = json_object_get_string_member (translation, "message");
+ return g_strdup (translated_message);
+ }
+
return g_strdup (message);
}
@@ -71,7 +84,8 @@ js_exception_handler (JSCContext *context,
void
ephy_webextension_install_common_apis (JSCContext *js_context,
- const char *guid)
+ const char *guid,
+ JsonObject *translations)
{
g_autoptr (JSCValue) result = NULL;
g_autoptr (JSCValue) js_browser = NULL;
@@ -103,7 +117,9 @@ ephy_webextension_install_common_apis (JSCContext *js_context,
js_function = jsc_value_new_function (js_context,
"getMessage",
- G_CALLBACK (js_getmessage), NULL, NULL,
+ G_CALLBACK (js_getmessage),
+ translations ? json_object_ref (translations) : NULL,
+ translations ? (GDestroyNotify)json_object_unref : NULL,
G_TYPE_STRING, 1,
G_TYPE_STRING);
jsc_value_object_set_property (js_i18n, "getMessage", js_function);
diff --git a/embed/web-process-extension/ephy-webextension-common.h
b/embed/web-process-extension/ephy-webextension-common.h
index d16cebab6..a37d0605f 100644
--- a/embed/web-process-extension/ephy-webextension-common.h
+++ b/embed/web-process-extension/ephy-webextension-common.h
@@ -22,9 +22,12 @@
#include <glib-object.h>
#include <jsc/jsc.h>
+#include <json-glib/json-glib.h>
G_BEGIN_DECLS
-void ephy_webextension_install_common_apis (JSCContext *js_context, const char *guid);
+void ephy_webextension_install_common_apis (JSCContext *js_context,
+ const char *guid,
+ JsonObject *translations);
G_END_DECLS
diff --git a/src/webextension/ephy-web-extension-manager.c b/src/webextension/ephy-web-extension-manager.c
index 3c859b37f..b7c9156e9 100644
--- a/src/webextension/ephy-web-extension-manager.c
+++ b/src/webextension/ephy-web-extension-manager.c
@@ -509,21 +509,24 @@ remove_custom_css (EphyWebExtension *self,
webkit_user_content_manager_remove_style_sheet (WEBKIT_USER_CONTENT_MANAGER (ucm),
ephy_web_extension_custom_css_style (self, list->data));
}
-static void
-update_translations (EphyWebExtension *web_extension)
+static char *
+get_translation_contents (EphyWebExtension *web_extension)
{
- /* TODO: Use current locale and fallback to default web_extension locale if necessary */
+ /* FIXME: Use current locale and fallback to default web_extension locale if necessary. */
g_autofree char *path = g_strdup_printf ("_locales/%s/messages.json", "en");
- g_autofree char *data = NULL;
- gint length = 0;
+ g_autofree char *data = ephy_web_extension_get_resource_as_string (web_extension, path);
+
+ return data ? g_steal_pointer (&data) : g_strdup ("");
+}
- data = ephy_web_extension_get_resource_as_string (web_extension, path);
- if (data)
- length = strlen (data);
+static void
+update_translations (EphyWebExtension *web_extension)
+{
+ g_autofree char *data = get_translation_contents (web_extension);
- webkit_web_context_send_message_to_all_extensions (ephy_embed_shell_get_web_context
(ephy_embed_shell_get_default ()),
- webkit_user_message_new ("WebExtension.Add",
- g_variant_new ("(sst)",
ephy_web_extension_get_name (web_extension), data ? (char *)data : "", length)));
+ webkit_web_context_send_message_to_all_extensions ( ephy_embed_shell_get_web_context
(ephy_embed_shell_get_default ()),
+ webkit_user_message_new
("WebExtension.UpdateTranslations",
+ g_variant_new ("(ss)",
ephy_web_extension_get_guid (web_extension), data)));
}
static void
@@ -589,6 +592,10 @@ web_extension_cb (WebKitURISchemeRequest *request,
path = webkit_uri_scheme_request_get_path (request);
+ /* FIXME: This may be the place to handle predefined messages and localized CSS:
+ *
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization#predefined_messages
+ */
+
data = ephy_web_extension_get_resource (web_extension, path + 1, &length);
if (!data) {
error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Resource not found: %s", path);
@@ -605,6 +612,7 @@ init_web_extension_api (WebKitWebContext *web_context,
EphyWebExtension *web_extension)
{
g_autoptr (GVariant) user_data = NULL;
+ g_autofree char *translations = get_translation_contents (web_extension);
#if DEVELOPER_MODE
webkit_web_context_set_web_extensions_directory (web_context, BUILD_ROOT "/embed/web-process-extension");
@@ -612,12 +620,13 @@ init_web_extension_api (WebKitWebContext *web_context,
webkit_web_context_set_web_extensions_directory (web_context, EPHY_WEB_PROCESS_EXTENSIONS_DIR);
#endif
- user_data = g_variant_new ("(smsbbb)",
+ user_data = g_variant_new ("(smsbbbs)",
ephy_web_extension_get_guid (web_extension),
ephy_profile_dir_is_default () ? NULL : ephy_profile_dir (),
FALSE,
FALSE,
- TRUE);
+ TRUE,
+ translations);
webkit_web_context_set_web_extensions_initialization_user_data (web_context, g_steal_pointer (&user_data));
}
@@ -650,8 +659,6 @@ create_web_extensions_webview (EphyWebExtension *web_extension)
settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view));
webkit_settings_set_enable_write_console_messages_to_stdout (settings, TRUE);
- update_translations (web_extension);
-
return web_view;
}
diff --git a/src/webextension/ephy-web-extension.c b/src/webextension/ephy-web-extension.c
index 878de29b9..1d9d75945 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -915,6 +915,7 @@ ephy_web_extension_load (GFile *target)
return NULL;
}
+ /* FIXME: Implement i18n:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization#retrieving_localized_strings_in_manifests
*/
self->manifest = g_strndup ((char *)manifest, length);
self->base_location = parent ? g_file_get_path (parent) : g_file_get_path (target);
self->description = ephy_web_extension_manifest_get_key (self, root_object, "description");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]