summaryrefslogtreecommitdiff
path: root/webhelper
diff options
context:
space:
mode:
authorPhilip Chimento <philip@endlessm.com>2017-04-12 15:24:48 -0700
committerPhilip Chimento <philip@endlessm.com>2017-04-12 16:14:06 -0700
commite54bec3feb08b09de64945f72885c8c37258de60 (patch)
treee86d9c5ff13eaf6b7b5498d68624a413a18b544d /webhelper
parent72694e1790f779edc8f8ac163a66af561bf14500 (diff)
build: Remove Webhelper
Webhelper is now in its own repository: https://github.com/endlessm/webhelper https://phabricator.endlessm.com/T16203
Diffstat (limited to 'webhelper')
-rw-r--r--webhelper/lib/wh2private.c36
-rw-r--r--webhelper/lib/wh2private.h20
-rw-r--r--webhelper/webextensions/wh2extension.c588
-rw-r--r--webhelper/webextensions/wh2jscutil.c65
-rw-r--r--webhelper/webextensions/wh2jscutil.h25
-rw-r--r--webhelper/webhelper.js290
-rw-r--r--webhelper/webhelper2.js529
-rw-r--r--webhelper/webhelper_private/config.js.in1
8 files changed, 0 insertions, 1554 deletions
diff --git a/webhelper/lib/wh2private.c b/webhelper/lib/wh2private.c
deleted file mode 100644
index 04a7710..0000000
--- a/webhelper/lib/wh2private.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Copyright 2015 Endless Mobile, Inc. */
-
-#include <glib.h>
-#include <webkit2/webkit2.h>
-
-#include "wh2private.h"
-
-/**
- * wh2_private_register_global_uri_scheme:
- * @scheme: the network scheme to register
- * @callback: a #WebKitURISchemeRequestCallback.
- * @user_data: (closure): user data for the @callback
- * @notify: destroy notify function for the @callback
- *
- * Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=729611
- *
- * Registers a URI scheme handler with the default WebContext. Does not pass the
- * GDestroyNotifyFunc, which GJS uses to shim a destructor for @callback, along
- * to the the web context.
- *
- * The default web context is a global object which does not get destroyed
- * until a atexit handler after the javascript runtime has been torn down.
- * Calling into the GJS function destructor at that point would be a
- * mistake.
- */
-void
-wh2_register_uri_scheme (const gchar *scheme,
- WebKitURISchemeRequestCallback callback,
- gpointer user_data,
- GDestroyNotify notify)
-{
- WebKitWebContext *context = webkit_web_context_get_default ();
- webkit_web_context_register_uri_scheme (context, scheme, callback, NULL, NULL);
-}
diff --git a/webhelper/lib/wh2private.h b/webhelper/lib/wh2private.h
deleted file mode 100644
index a20fe87..0000000
--- a/webhelper/lib/wh2private.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Copyright 2015 Endless Mobile, Inc. */
-
-#ifndef WH2_PRIVATE_H
-#define WH2_PRIVATE_H
-
-#include <glib.h>
-#include <webkit2/webkit2.h>
-
-G_BEGIN_DECLS
-
-void wh2_register_uri_scheme (const gchar *scheme,
- WebKitURISchemeRequestCallback callback,
- gpointer user_data,
- GDestroyNotify notify);
-
-G_END_DECLS
-
-#endif /* WH2_PRIVATE_H */
diff --git a/webhelper/webextensions/wh2extension.c b/webhelper/webextensions/wh2extension.c
deleted file mode 100644
index 8dd738b..0000000
--- a/webhelper/webextensions/wh2extension.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Copyright 2015 Endless Mobile, Inc. */
-
-#include <math.h>
-#include <string.h>
-
-#include <glib.h>
-#include <JavaScriptCore/JavaScript.h>
-#include <webkit2/webkit-web-extension.h>
-#include <webkitdom/webkitdom.h>
-
-#include "wh2jscutil.h"
-
-#define PRIVATE_NAME "_webhelper_private"
-#define WH2_DBUS_INTERFACE_NAME "com.endlessm.WebHelper2.Translation"
-#define MAIN_PROGRAM_OBJECT_PATH "/com/endlessm/gettext"
-#define MAIN_PROGRAM_INTERFACE_NAME "com.endlessm.WebHelper2.Gettext"
-
-/* Declaration of externally visible symbol */
-void webkit_web_extension_initialize_with_user_data (WebKitWebExtension *, const GVariant *);
-
-typedef struct {
- WebKitWebExtension *extension; /* unowned */
- GDBusConnection *connection; /* unowned */
- GDBusNodeInfo *node; /* owned */
- GDBusInterfaceInfo *interface; /* owned by node */
- GSList *bus_ids; /* GSList<guint>; owned */
- GArray *unregistered_pages; /* GArray<guint64>; owned */
- gchar *main_program_name; /* owned; well-known-name of main program */
-} Context;
-
-typedef struct {
- Context *ctxt; /* unowned */
- guint64 page_id;
-} PageContext;
-
-static const gchar introspection_xml[] =
- "<node>"
- "<interface name='" WH2_DBUS_INTERFACE_NAME "'>"
- "<method name='Translate'/>"
- "</interface>"
- "</node>";
-
-static void
-context_free (Context *ctxt)
-{
- g_clear_pointer (&ctxt->node, g_dbus_node_info_unref);
- g_clear_pointer (&ctxt->bus_ids, g_slist_free);
- if (ctxt->unregistered_pages != NULL)
- g_array_free (ctxt->unregistered_pages, TRUE);
- ctxt->unregistered_pages = NULL;
- g_clear_pointer (&ctxt->main_program_name, g_free);
- g_free (ctxt);
-}
-
-/* Spins the main loop until the DBus connection comes up. We need this since we
-define functions in JS, that JS code can potentially call before there is a
-connection. */
-static void
-wait_for_connection_sync (Context *ctxt)
-{
- g_return_if_fail (ctxt->connection == NULL);
-
- GMainContext *main = g_main_context_get_thread_default ();
- while (ctxt->connection == NULL)
- g_main_context_iteration (main, TRUE /* may block */);
-
- g_assert (ctxt->connection);
-}
-
-static gchar *
-translation_function (const gchar *message,
- Context *ctxt)
-{
- GError *error = NULL;
-
- if (ctxt->connection == NULL)
- wait_for_connection_sync (ctxt);
-
- GVariant *result =
- g_dbus_connection_call_sync (ctxt->connection, ctxt->main_program_name,
- MAIN_PROGRAM_OBJECT_PATH,
- MAIN_PROGRAM_INTERFACE_NAME, "Gettext",
- g_variant_new ("(s)", message),
- (GVariantType *) "(s)",
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1 /* timeout */, NULL /* cancellable */,
- &error);
- if (result == NULL)
- {
- g_warning ("No return value from gettext: %s", error->message);
- g_clear_error (&error);
- return g_strdup (message);
- }
-
- gchar *retval;
- g_variant_get (result, "(s)", &retval);
- g_variant_unref (result);
- return retval;
-}
-
-static gchar *
-ngettext_translation_function (const gchar *singular,
- const gchar *plural,
- guint64 number,
- Context *ctxt)
-{
- GError *error = NULL;
-
- if (ctxt->connection == NULL)
- wait_for_connection_sync (ctxt);
-
- GVariant *result =
- g_dbus_connection_call_sync (ctxt->connection, ctxt->main_program_name,
- MAIN_PROGRAM_OBJECT_PATH,
- MAIN_PROGRAM_INTERFACE_NAME, "NGettext",
- g_variant_new ("(sst)", singular, plural,
- number),
- (GVariantType *) "(s)",
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1 /* timeout */, NULL /* cancellable */,
- &error);
- if (result == NULL)
- {
- g_warning ("No return value from ngettext: %s", error->message);
- g_clear_error (&error);
- return g_strdup (number == 1 ? singular : plural);
- }
-
- gchar *retval;
- g_variant_get (result, "(s)", &retval);
- g_variant_unref (result);
- return retval;
-}
-
-static JSValueRef
-gettext_shim (JSContextRef js,
- JSObjectRef function,
- JSObjectRef this_object,
- size_t n_args,
- const JSValueRef args[],
- JSValueRef *exception)
-{
- if (n_args != 1)
- {
- gchar *errmsg = g_strdup_printf ("Expected one argument to gettext(),"
- "but got %"G_GSIZE_FORMAT".", n_args);
- *exception = throw_exception (js, errmsg);
- g_free (errmsg);
- return NULL;
- }
- if (!JSValueIsString (js, args[0]))
- {
- *exception = throw_exception (js,
- "Expected a string argument to gettext().");
- return NULL;
- }
-
- JSObjectRef window = JSContextGetGlobalObject (js);
- JSStringRef private_name = JSStringCreateWithUTF8CString (PRIVATE_NAME);
- JSValueRef private_data = JSObjectGetProperty (js, window, private_name,
- exception);
- if (JSValueIsUndefined (js, private_data))
- return NULL; /* propagate exception */
- Context *ctxt = (Context *) JSObjectGetPrivate ((JSObjectRef) private_data);
-
- JSStringRef message_ref = JSValueToStringCopy (js, args[0], exception);
- if (message_ref == NULL)
- return NULL; /* propagate exception */
- gchar *message = string_ref_to_string (message_ref);
- JSStringRelease (message_ref);
-
- gchar *translation = translation_function (message, ctxt);
- g_free (message);
-
- JSValueRef retval = string_to_value_ref (js, translation);
- g_free (translation);
- return retval;
-}
-
-static JSValueRef
-ngettext_shim (JSContextRef js,
- JSObjectRef function,
- JSObjectRef this_object,
- size_t n_args,
- const JSValueRef args[],
- JSValueRef *exception)
-{
- if (n_args != 3)
- {
- gchar *errmsg = g_strdup_printf ("Expected three arguments to ngettext(),"
- "but got %"G_GSIZE_FORMAT".", n_args);
- *exception = throw_exception (js, errmsg);
- g_free (errmsg);
- return NULL;
- }
- if (!JSValueIsString (js, args[0]))
- {
- *exception = throw_exception (js, "The first argument to ngettext() "
- "must be a string.");
- return NULL;
- }
- if (!JSValueIsString (js, args[1]))
- {
- *exception = throw_exception (js, "The second argument to ngettext() "
- "must be a string.");
- return NULL;
- }
- if (!JSValueIsNumber (js, args[2]))
- {
- *exception = throw_exception (js, "The third argument to ngettext() "
- "must be a number.");
- return NULL;
- }
-
- JSObjectRef window = JSContextGetGlobalObject (js);
- JSStringRef private_name = JSStringCreateWithUTF8CString (PRIVATE_NAME);
- JSValueRef private_data = JSObjectGetProperty (js, window, private_name,
- exception);
- if (JSValueIsUndefined (js, private_data))
- return NULL; /* propagate exception */
- Context *ctxt = (Context *) JSObjectGetPrivate ((JSObjectRef) private_data);
-
- JSStringRef singular_ref = JSValueToStringCopy (js, args[0], exception);
- if (singular_ref == NULL)
- return NULL; /* propagate exception */
- gchar *singular_msg = string_ref_to_string (singular_ref);
- JSStringRelease (singular_ref);
-
- JSStringRef plural_ref = JSValueToStringCopy (js, args[1], exception);
- if (plural_ref == NULL)
- {
- g_free (singular_msg);
- return NULL; /* propagate exception */
- }
- gchar *plural_msg = string_ref_to_string (plural_ref);
- JSStringRelease (plural_ref);
-
- double number = JSValueToNumber (js, args[2], exception);
- if (isnan (number))
- {
- g_free (singular_msg);
- g_free (plural_msg);
- return NULL; /* propagate exception */
- }
-
- gchar *translation = ngettext_translation_function (singular_msg, plural_msg,
- (guint64) number, ctxt);
- g_free (singular_msg);
- g_free (plural_msg);
-
- JSValueRef retval = string_to_value_ref (js, translation);
- g_free (translation);
- return retval;
-}
-
-static gchar *
-normalize_string (const gchar *string)
-{
- static GRegex *whitespace = NULL;
-
- if (g_once_init_enter (&whitespace))
- {
- GError *regex_error = NULL;
- GRegex *new_regex = g_regex_new ("\\s+", G_REGEX_OPTIMIZE, 0,
- &regex_error);
- // Don't free; will persist until exit
- if (new_regex == NULL)
- {
- g_critical ("Trouble creating regex: %s\n", regex_error->message);
- g_clear_error (&regex_error);
- }
-
- g_once_init_leave (&whitespace, new_regex);
- }
-
- GError *error = NULL;
- gchar *copy = g_strstrip (g_strdup (string));
- gchar *retval = g_regex_replace_literal (whitespace, copy, -1, 0, " ", 0, &error);
- if (retval == NULL)
- {
- g_critical ("Trouble normalizing string: %s\n", error->message);
- g_clear_error (&error);
- return copy;
- }
- g_free (copy);
- return retval;
-}
-
-static void
-translate_html (WebKitDOMDocument *dom,
- Context *ctxt)
-{
- WebKitDOMNodeList *translatable;
- GError *error = NULL;
-
- translatable = webkit_dom_document_get_elements_by_name (dom, "translatable");
-
- gulong index, length = webkit_dom_node_list_get_length (translatable);
- for (index = 0; index < length; index++)
- {
- WebKitDOMNode *element = webkit_dom_node_list_item (translatable, index);
-
- /* Translate the text */
- if (WEBKIT_DOM_IS_HTML_ELEMENT (element))
- {
- WebKitDOMHTMLElement *el_html = WEBKIT_DOM_HTML_ELEMENT (element);
- gchar *inner_html = webkit_dom_html_element_get_inner_html (el_html);
- gchar *normalized = normalize_string (inner_html);
- gchar *translated_html = translation_function (normalized, ctxt);
- webkit_dom_html_element_set_inner_html (el_html, translated_html,
- &error);
- if (error != NULL)
- {
- g_warning ("There was a problem translating '%s' to '%s': %s",
- inner_html, translated_html, error->message);
- g_clear_error (&error);
- }
-
- g_free (translated_html);
- g_free (inner_html);
- g_free (normalized);
- }
- else
- {
- gchar *text = webkit_dom_node_get_text_content (element);
- gchar *normalized = normalize_string (text);
- gchar *translated_text = translation_function (normalized, ctxt);
- webkit_dom_node_set_text_content (element, translated_text, &error);
- if (error != NULL)
- {
- g_warning ("There was a problem translating '%s' to '%s': %s",
- text, translated_text, error->message);
- g_clear_error (&error);
- }
-
- g_free (translated_text);
- g_free (text);
- g_free (normalized);
- }
- }
-
- g_object_unref (translatable);
-}
-
-static void
-on_wh2_method_call (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- PageContext *pctxt)
-{
- if (strcmp (method_name, "Translate") != 0)
- {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_METHOD,
- "Unknown method %s invoked on interface %s",
- method_name, interface_name);
- return;
- }
-
- WebKitWebPage *page = webkit_web_extension_get_page (pctxt->ctxt->extension,
- pctxt->page_id);
- if (page == NULL)
- return;
- /* The page may have been destroyed, but WebKit doesn't let us find out. */
-
- WebKitDOMDocument *document = webkit_web_page_get_dom_document (page);
- if (document == NULL)
- {
- g_dbus_method_invocation_return_error_literal (invocation, G_IO_ERROR,
- G_IO_ERROR_NOT_INITIALIZED,
- "The web page has not loaded a document yet");
- return;
- }
-
- translate_html (document, pctxt->ctxt);
-
- g_dbus_method_invocation_return_value (invocation, NULL);
-}
-
-static GDBusInterfaceVTable dbus_impl_vtable = {
- (GDBusInterfaceMethodCallFunc) on_wh2_method_call,
- NULL, /* get property */
- NULL /* set property */
-};
-
-static void
-register_object (guint64 page_id,
- Context *ctxt)
-{
- GError *error = NULL;
-
- g_assert (ctxt->connection != NULL);
-
- gchar *object_path = g_strdup_printf("/com/endlessm/webview/%"
- G_GUINT64_FORMAT, page_id);
-
- /* This struct is owned by the registered DBus object */
- PageContext *pctxt = g_new0 (PageContext, 1);
- pctxt->ctxt = ctxt;
- pctxt->page_id = page_id;
-
- guint bus_id =
- g_dbus_connection_register_object (ctxt->connection, object_path,
- ctxt->interface, &dbus_impl_vtable,
- pctxt, (GDestroyNotify) g_free, &error);
- g_free (object_path);
- if (bus_id == 0)
- {
- g_critical ("Failed to export webview object on bus: %s", error->message);
- g_clear_error (&error);
- goto fail;
- }
-
- ctxt->bus_ids = g_slist_prepend (ctxt->bus_ids, GUINT_TO_POINTER (bus_id));
- return;
-
-fail:
- g_free (pctxt);
-}
-
-static void
-on_page_created (WebKitWebExtension *extension,
- WebKitWebPage *page,
- Context *ctxt)
-{
- /* The ID is known to the main process and the web process. So we can address
- a specific web page over DBus. */
- guint64 id = webkit_web_page_get_id (page);
-
- if (ctxt->connection == NULL)
- {
- /* The connection is not ready yet. Save the page ID in a list of pages
- for which we need to register objects later. */
- g_array_append_val (ctxt->unregistered_pages, id);
- return;
- }
-
- register_object (id, ctxt);
-}
-
-/* window-object-cleared is the best time to define properties on the page's
-window object, according to the documentation. */
-static void
-on_window_object_cleared (WebKitScriptWorld *script_world,
- WebKitWebPage *page,
- WebKitFrame *frame,
- Context *ctxt)
-{
- JSGlobalContextRef js =
- webkit_frame_get_javascript_context_for_script_world (frame, script_world);
- JSObjectRef window = JSContextGetGlobalObject (js);
-
- /* First we need to create a custom class for a private data object to store
- our context in, because you can't pass callback data to JavaScriptCore
- callbacks. You also can't set private data on a Javascript object if it's not
- of a custom class, because the built-in classes don't allocate space for a
- private pointer. */
- JSClassDefinition class_def = {
- .className = "PrivateContextObject"
- };
- JSClassRef klass = JSClassCreate (&class_def);
- JSObjectRef private_data = JSObjectMake (js, klass, ctxt);
- JSClassRelease (klass);
-
- if (!set_object_property (js, window, PRIVATE_NAME, (JSValueRef) private_data,
- kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete))
- return;
-
- JSObjectRef gettext_func =
- JSObjectMakeFunctionWithCallback (js, NULL, gettext_shim);
- if (!set_object_property (js, window, "gettext", (JSValueRef) gettext_func,
- kJSPropertyAttributeNone))
- return;
-
- JSObjectRef ngettext_func =
- JSObjectMakeFunctionWithCallback (js, NULL, ngettext_shim);
- if (!set_object_property (js, window, "ngettext", (JSValueRef) ngettext_func,
- kJSPropertyAttributeNone))
- return;
-}
-
-static void
-on_bus_acquired (GDBusConnection *connection,
- const gchar *name,
- Context *ctxt)
-{
- GError *error = NULL;
-
- ctxt->connection = connection;
-
- /* Export our interface on the bus */
- ctxt->node = g_dbus_node_info_new_for_xml (introspection_xml, &error);
- if (ctxt->node == NULL)
- goto fail;
- ctxt->interface = g_dbus_node_info_lookup_interface (ctxt->node,
- WH2_DBUS_INTERFACE_NAME);
- if (ctxt->interface == NULL)
- goto fail;
-
- /* Register DBus objects for any pages that were created before we got here */
- guint ix;
- for (ix = 0; ix < ctxt->unregistered_pages->len; ix++)
- {
- guint64 id = g_array_index (ctxt->unregistered_pages, guint64, ix);
- register_object (id, ctxt);
- }
- g_array_remove_range (ctxt->unregistered_pages, 0,
- ctxt->unregistered_pages->len);
-
- return;
-
-fail:
- if (error != NULL)
- {
- g_critical ("Error hooking up web extension DBus interface: %s",
- error->message);
- g_clear_error (&error);
- }
- else
- {
- g_critical ("Unknown error hooking up web extension DBus interface");
- }
-}
-
-static void
-unregister_object (gpointer data,
- GDBusConnection *connection)
-{
- guint bus_id = GPOINTER_TO_UINT (data);
- if (!g_dbus_connection_unregister_object (connection, bus_id))
- g_critical ("Trouble unregistering object");
-}
-
-static void
-on_name_lost (GDBusConnection *connection,
- const gchar *name,
- Context *ctxt)
-{
- if (connection == NULL)
- {
- g_warning ("Could not initialize DBus interface for WebHelper2 "
- "extension; the name %s was lost.", name);
- return;
- }
-
- g_slist_foreach (ctxt->bus_ids, (GFunc) unregister_object, connection);
-}
-
-/* Receives the main program's unique DBus name as user data. */
-G_MODULE_EXPORT void
-webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension,
- const GVariant *data_from_app)
-{
- const gchar *name = g_variant_get_string ((GVariant *) data_from_app, NULL);
-
- Context *ctxt = g_new0 (Context, 1);
- ctxt->extension = extension;
- ctxt->unregistered_pages = g_array_new (FALSE, FALSE, sizeof (guint64));
- ctxt->main_program_name = g_strdup (name);
- gchar *well_known_name = g_strconcat (name, ".webhelper", NULL);
-
- g_signal_connect (extension, "page-created",
- G_CALLBACK (on_page_created), ctxt);
-
- g_bus_own_name (G_BUS_TYPE_SESSION, well_known_name,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- (GBusAcquiredCallback) on_bus_acquired,
- NULL, /* name acquired callback */
- (GBusNameLostCallback) on_name_lost,
- ctxt, (GDestroyNotify) context_free);
-
- g_free (well_known_name);
-
- /* Get a notification when Javascript is ready. In this callback it's possible
- that the DBus connection has not been acquired yet, so we have sync waits
- later if JS tries to call DBus. However, connecting to this signal later
- doesn't work because it will often already have been fired before the DBus
- connection is acquired. */
- WebKitScriptWorld *script_world = webkit_script_world_get_default ();
- g_signal_connect (script_world, "window-object-cleared",
- G_CALLBACK (on_window_object_cleared), ctxt);
-}
diff --git a/webhelper/webextensions/wh2jscutil.c b/webhelper/webextensions/wh2jscutil.c
deleted file mode 100644
index 34f325f..0000000
--- a/webhelper/webextensions/wh2jscutil.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Copyright 2015 Endless Mobile, Inc. */
-
-#include <glib.h>
-#include <JavaScriptCore/JavaScript.h>
-
-#include "wh2jscutil.h"
-
-G_GNUC_INTERNAL
-gboolean
-set_object_property (JSContextRef js,
- JSObjectRef object,
- const gchar *property_name,
- JSValueRef property_value,
- JSPropertyAttributes flags)
-{
- JSValueRef exception = NULL;
- JSStringRef property_name_ref = JSStringCreateWithUTF8CString (property_name);
- JSObjectSetProperty (js, object, property_name_ref, property_value, flags,
- &exception);
- JSStringRelease (property_name_ref);
- if (exception != NULL)
- {
- g_critical ("There was a problem setting the property '%s'.",
- property_name);
- return FALSE;
- }
- return TRUE;
-}
-
-/* Returns a newly allocated string. */
-G_GNUC_INTERNAL
-gchar *
-string_ref_to_string (JSStringRef string_ref)
-{
- size_t bufsize = JSStringGetMaximumUTF8CStringSize (string_ref);
- gchar *string = g_new0 (gchar, bufsize);
- JSStringGetUTF8CString (string_ref, string, bufsize);
- return string;
-}
-
-G_GNUC_INTERNAL
-JSValueRef
-string_to_value_ref (JSContextRef js,
- const gchar *string)
-{
- JSStringRef string_ref = JSStringCreateWithUTF8CString (string);
- JSValueRef value_ref = JSValueMakeString (js, string_ref);
- /* value_ref owns string_ref now */
- return value_ref;
-}
-
-G_GNUC_INTERNAL
-JSValueRef
-throw_exception (JSContextRef js,
- const gchar *message)
-{
- JSValueRef msgval = string_to_value_ref (js, message);
- JSValueRef inner_error = NULL;
- JSObjectRef exception = JSObjectMakeError (js, 1, &msgval, &inner_error);
- if (inner_error != NULL)
- return inner_error;
- return (JSValueRef) exception;
-}
diff --git a/webhelper/webextensions/wh2jscutil.h b/webhelper/webextensions/wh2jscutil.h
deleted file mode 100644
index af800e5..0000000
--- a/webhelper/webextensions/wh2jscutil.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/* Copyright 2015 Endless Mobile, Inc. */
-
-#ifndef WH2_JSC_UTIL_H
-#define WH2_JSC_UTIL_H
-
-#include <glib.h>
-#include <JavaScriptCore/JavaScript.h>
-
-gboolean set_object_property (JSContextRef js,
- JSObjectRef object,
- const gchar *property_name,
- JSValueRef property_value,
- JSPropertyAttributes flags);
-
-gchar *string_ref_to_string (JSStringRef string_ref);
-
-JSValueRef string_to_value_ref (JSContextRef js,
- const gchar *string);
-
-JSValueRef throw_exception (JSContextRef js,
- const gchar *message);
-
-#endif /* WH2_JSC_UTIL_H */
diff --git a/webhelper/webhelper.js b/webhelper/webhelper.js
deleted file mode 100644
index d4f6811..0000000
--- a/webhelper/webhelper.js
+++ /dev/null
@@ -1,290 +0,0 @@
-const Endless = imports.gi.Endless;
-const Format = imports.format;
-const GLib = imports.gi.GLib;
-const Gtk = imports.gi.Gtk;
-const Lang = imports.lang;
-const WebKit = imports.gi.WebKit;
-
-String.prototype.format = Format.format;
-
-const EOS_URI_SCHEME = 'endless://';
-
-/**
- * Namespace: WebHelper
- * Convenience library for running web applications
- *
- * WebHelper is a convenience library for displaying web applications inside a
- * GTK container running WebKitGTK (currently WebKit 1, not 2.)
- * Although WebKit provides an easy way of communicating from GTK code to
- * the in-browser Javascript, through the execute_script() method, it is not so
- * easy to communicate the other way around.
- *
- * WebHelper solves that problem by detecting when the web page navigates to a
- * custom action URI.
- * The custom URI corresponds to a function that you define using
- * <Application.define_web_action()>, and you can pass parameters to the
- * function.
- *
- * Another often-encountered problem is localizing text through the same API as
- * your main GTK program.
- * WebHelper solves this problem by allowing you to mark strings in your HTML
- * page and translating them through a function of your choice when you run
- * <Application.translate_html()>.
- */
-
-/**
- * Class: Application
- * Main application class for a WebHelper application
- *
- * The application class in GJS for your web application should extend
- * WebHelper.Application.
- *
- * You should set up any WebViews that you create, by connecting
- * <web_actions_handler()>, so that they can handle custom action URIs.
- */
-const Application = new Lang.Class({
- Name: 'WebApplication',
- Extends: Endless.Application,
-
- _init: function(props) {
- this._webActions = {};
- this._translationFunction = null;
- this.parent(props);
- },
-
- /**
- * Method: define_web_action
- * Define an action that may be invoked from a WebView
- *
- * Parameters:
- * name - a string, which must be a valid URI location.
- * implementation - a function (see Callback Parameters below.)
- *
- * Callback Parameters:
- * dict - object containing properties corresponding to the query
- * parameters that the web action was called with
- *
- * Sets up an action that may be invoked from an HTML document inside a
- * WebView, or from the in-browser Javascript environment inside a WebView.
- * If you set up an action "setVolume" as follows:
- * > app.define_web_action('setVolume', function(dict) { ... });
- * Then you can invoke the action inside the HTML document, e.g. as the
- * target of a link, as follows:
- * > <a href="endless://setVolume?volume=11">This one goes to 11</a>
- * Or from the in-browser Javascript, by navigating to the action URI, as
- * follows:
- * > window.location.href = 'endless://setVolume?volume=11';
- *
- * In both cases, the function would then be called with the _dict_
- * parameter equal to
- * > { "volume": "11" }
- *
- * If an action called _name_ is already defined, the new _implementation_
- * replaces the old one.
- */
- define_web_action: function(name, implementation) {
- if(typeof implementation != 'function') {
- throw new Error('The implementation of a web action must be a ' +
- 'function.');
- }
- this._webActions[name] = implementation;
- },
-
- /**
- * Method: define_web_actions
- * Define several web actions at once
- *
- * Parameters:
- * dict - an object, with web action names as property names, and their
- * implementations as values
- *
- * Convenience method to define more than one web action at once.
- * Calls <define_web_action()> on each property of _dict_.
- *
- * *Note* This API is Javascript-only. It will not be implemented in C.
- */
- define_web_actions: function(dict) {
- for(let key in dict) {
- if(dict.hasOwnProperty(key)) {
- this.define_web_action(key, dict[key]);
- }
- }
- },
-
- /**
- * Callback: web_actions_handler
- * Navigation callback which routes the custom URIs to actions
- *
- * When you create a web view in which you want to run a web application
- * that uses custom action URIs, remember to set it up by connecting this
- * callback to its "navigation-policy-decision-requested" signal. The
- * following code will do this:
- *
- * > webview.connect('navigation-policy-decision-requested',
- * > Lang.bind(app, app.web_actions_handler));
- *
- * where 'webview' is the web view, and 'app' is the WebHelper.Application
- * instance.
- */
- web_actions_handler: function(webview, frame, request, action, policy_decision) {
- let uri = request.get_uri();
-
- if(uri.indexOf(EOS_URI_SCHEME) !== 0) {
- // this is a regular URL, just navigate there
- return false;
- }
-
- // get the name and parameters for the desired function
- let f_call = uri.substring(EOS_URI_SCHEME.length, uri.length).split('?');
- var function_name = decodeURI(f_call[0]);
- var parameters = {};
-
- if(f_call[1]) {
- // there are parameters
- let params = f_call[1].split('&');
- params.forEach(function(entry) {
- let param = entry.split('=');
-
- if(param.length == 2) {
- param[0] = decodeURIComponent(param[0]);
- param[1] = decodeURIComponent(param[1]);
- // and now we add it...
- parameters[param[0]] = param[1];
- }
- });
- }
-
- if(this._webActions[function_name])
- Lang.bind(this, this._webActions[function_name])(parameters);
- else
- throw new Error("Undefined WebHelper action '%s'. Did you define " +
- "it with WebHelper.Application.define_web_action()?".format(
- function_name));
-
- policy_decision.ignore();
- return true;
- },
-
- // convenience function
-
- _getElementById: function(webview, id) {
- // WebKit.DOMDocument
- let dom = webview.get_dom_document();
-
- // WebKit.DOMElement
- return dom.get_element_by_id(id);
- },
-
- /**
- * Method: set_translation_function
- * Define function which transforms all translatable text
- *
- * Parameters:
- * translation_function - a function, or null
- *
- * When you plan to use the <translate_html()> function to translate text in
- * your web application, set this property to the translation function.
- * The function must take one parameter, a string, and also return a
- * string.
- * The canonical example is gettext().
- *
- * Pass null for _translation_function_ to unset the translation function.
- *
- * If this function has not been called, or has most recently been called
- * with null, then it is illegal to call <translate_html()>.
- */
- set_translation_function: function(translation_function) {
- if(translation_function !== null
- && typeof translation_function !== 'function') {
- throw new Error('The translation function must be a function, or ' +
- 'null.');
- }
- this._translationFunction = translation_function;
- },
-
- /**
- * Method: get_translation_function
- * Retrieve the currently set translation function
- *
- * Returns:
- * the translation function previously set with
- * <set_translation_function()>, or null if none is currently set.
- */
- get_translation_function: function() {
- return this._translationFunction;
- },
-
- /**
- * Method: translate_html
- * Translate all translatable text currently showing in a web view
- *
- * Parameters:
- * webview - the WebView containing the text to translate.
- *
- * Another problem with running web applications inside a GTK container is
- * keeping all the localization data in the same place.
- * For example, the most obvious way to do localization in a GTK application
- * is to use gettext(), but that does not work so easily inside a web view.
- *
- * In a <WebHelper.Application>, you can mark strings in your HTML for
- * translation by enclosing them in
- * > <span name="translatable">String to be translated</span>
- * or just putting the "translatable" name directly on the element
- * containing the string, e.g. <p> or <h1>.
- *
- * Then after the web view has finished loading, call <translate_html()> on
- * it, and each of the marked strings will be passed to the function that
- * you specify using <set_translation_function()> property.
- * The return value from the translation function will be substituted into
- * the HTML instead of the original string.
- *
- * Example:
- * > app.set_translation_function(_);
- * > webview.connect('notify::load-status',
- * > Lang.bind(app, function(webview) {
- * > if(webview.load_status == WebKit.LoadStatus.FINISHED)
- * > this.translate_html(webview);
- * > }));
- */
- translate_html: function(webview) {
- let dom = webview.get_dom_document();
-
- // WebKit.DOMNodeList
- let translatable = dom.get_elements_by_name('translatable');
-
- for (var i = 0 ; i < translatable.get_length() ; i++) {
- // WebKit.DOMNode
- let element = translatable.item(i);
-
- // Translate the text
- if(typeof this._translationFunction !== 'function')
- throw new Error("No suitable translation function was found. " +
- "Did you forget to call 'set_translation_function()' on " +
- "your app?");
- element.inner_html = this._translationFunction(element.inner_text);
- }
- },
-
- /**
- * Method: set_web_settings_font_resizable
- * Set an eos_window to update font size of web_settings
- *
- * Parameters:
- * eos_windw - an <Endless.Window>
- * web_settings - a <WebKit.WebSettings>
- *
- * The <Endless.Window> will be connected on its "size-allocate" signal
- * to the given <WebKit.WebSettings>. The <Endless.Window> will update the
- * "default-font-size" property of the <WebKit.WebSettings> calculated font size
- * to the <Endless.Window>'s calculated font size.
- */
- set_web_settings_font_resizable: function (eos_window, web_settings) {
- eos_window.connect('size-allocate',
- Lang.bind(this, function (widget, allocation) {
- if (eos_window.font_scaling_active) {
- web_settings.default_font_size = eos_window.font_scaling_calculated_font_size;
- }
- }
- ));
- }
-});
diff --git a/webhelper/webhelper2.js b/webhelper/webhelper2.js
deleted file mode 100644
index ea25bc1..0000000
--- a/webhelper/webhelper2.js
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2015 Endless Mobile, Inc.
-
-imports.gi.versions.WebKit2 = '4.0';
-
-const Format = imports.format;
-const Gio = imports.gi.Gio;
-const GLib = imports.gi.GLib;
-const GObject = imports.gi.GObject;
-const Lang = imports.lang;
-const WebHelper2Private = imports.gi.WebHelper2Private;
-const WebKit2 = imports.gi.WebKit2;
-const LIBEXEC_SUBDIR = 'webhelper2';
-
-const Config = imports.webhelper_private.config;
-
-String.prototype.format = Format.format;
-
-const WH2_URI_SCHEME = 'webhelper';
-const WH2_LOCAL_FILE_SCHEME = 'local';
-const DBUS_WEBVIEW_EXPORT_PATH = '/com/endlessm/webview/';
-const WH2_DBUS_EXTENSION_INTERFACE = '\
- <node> \
- <interface name="com.endlessm.WebHelper2.Translation"> \
- <method name="Translate"/> \
- </interface> \
- </node>';
-const WH2_DBUS_MAIN_PROGRAM_INTERFACE = '\
- <node> \
- <interface name="com.endlessm.WebHelper2.Gettext"> \
- <method name="Gettext"> \
- <arg name="message" type="s" direction="in"/> \
- <arg name="translation" type="s" direction="out"/> \
- </method> \
- <method name="NGettext"> \
- <arg name="message_singular" type="s" direction="in"/> \
- <arg name="message_plural" type="s" direction="in"/> \
- <arg name="number" type="t" direction="in"/> \
- <arg name="translation" type="s" direction="out"/> \
- </method> \
- </interface> \
- </node>';
-
-/**
- * Namespace: WebHelper2
- * Convenience library for running web applications
- *
- * WebHelper is a convenience library for displaying web applications inside a
- * GTK container running WebKitGTK.
- * WebHelper2 is the WebKit2 version.
- *
- * Although WebKit provides an easy way of communicating from GTK code to
- * the in-browser Javascript, through the execute_script() method, it is not so
- * easy to communicate the other way around.
- *
- * WebHelper solves that problem by detecting when the web page navigates to a
- * custom action URI.
- * The custom URI corresponds to a function that you define using
- * <WebHelper.define_web_action()>, and you can pass parameters to the
- * function.
- *
- * Another often-encountered problem is localizing text through the same API as
- * your main GTK program.
- * WebHelper solves this problem by allowing you to mark strings in your HTML
- * page and translating them through a function of your choice when you run
- * <WebHelper.translate_html()>.
- * It also exposes a *gettext()* function in the client-side Javascript.
- *
- * For cases where you need to load local files for your web applications,
- * WebHelper also provides the local:// URI scheme.
- * For this to work, you must also load your main page via the local:// URI
- * scheme.
- */
-
-/**
- * Class: WebHelper
- * Helper object for a WebKit2 web application
- *
- * Constructor parameters:
- * props - a dictionary of construction properties and values (default {})
- *
- * The application class for your web application should create <WebHelper> after
- * registering itself in the session bus (i.e. not inside *vfunc_dbus_register()*),
- * with appropriate <well-known-name> and <connection> parameters.
- * A good place to do this would be in your *vfunc_startup()* implementation, where
- * you can also do further setup on it, such as defining web actions.
- *
- * There is no need to set up specially any web views that you create, unlike
- * WebKit1 where you must set up <Application.web_actions_handler()>.
- *
- * Example:
- * > const TestApplication = new Lang.Class({
- * > Name: 'TestApplication',
- * > Extends: Gtk.Application,
- * >
- * > vfunc_dbus_register: function (connection, object_path) {
- * > this._webhelper = new WebHelper2.WebHelper({
- * > well_known_name: this.application_id,
- * > connection: connection,
- * > });
- * > return this.parent(connection, object_path);
- * > },
- * >
- * > vfunc_startup: function () {
- * > this.parent();
- * >
- * > this._webhelper.set_gettext(Gettext.dgettext.bind(null,
- * > GETTEXT_DOMAIN));
- * >
- * > let window = new Gtk.Window();
- * > let webview = new WebKit2.WebView();
- * > webview.connect('load-changed', (webview, event) => {
- * > if (event === WebKit2.LoadEvent.FINISHED)
- * > this._webhelper.translate_html(webview, null, (obj, res) => {
- * > this._webhelper.translate_html_finish(res);
- * > window.show_all();
- * > });
- * > });
- * > window.add(webview);
- * > webview.load_uri('file:///path/to/my/page.html');
- * > },
- * >
- * > vfunc_dbus_unregister: function (connection, object_path) {
- * > this.parent(connection, object_path);
- * > this._webhelper.unregister();
- * > },
- * >});
- * >
- * >let app = new TestApplication({
- * > application_id: 'com.example.SmokeGrinder',
- * >});
- * >app.run(ARGV);
- */
-const WebHelper = new Lang.Class({
- Name: 'WebHelper',
- GTypeName: 'Wh2WebHelper',
- Extends: GObject.Object,
- Properties: {
- /**
- * Property: well-known-name
- * Well-known bus name owned by the calling program
- *
- * Type:
- * string
- *
- * This property is required at construction time.
- * It must conform to <the rules for well-known bus names at
- * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names>.
- *
- * This must be a well-known bus name that your program owns.
- * The easiest way to ensure that is to use your application's ID, since
- * every application class registers its ID as a bus name.
- */
- 'well-known-name': GObject.ParamSpec.string('well-known-name',
- 'Well-known name',
- 'Well-known bus name owned by the calling program',
- GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
- ''),
- /**
- * Property: connection
- * DBus connection owned by the calling program
- *
- * Type:
- * *Gio.DBusConnection*
- *
- * This property is required at construction time.
- *
- * This must be a DBus connection object that your program owns.
- * The easiest way to ensure that is to use the connection object passed
- * in to your application's *vfunc_dbus_register()* function.
- */
- 'connection': GObject.ParamSpec.object('connection', 'Connection',
- 'DBus connection owned by the calling program',
- GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
- Gio.DBusConnection.$gtype),
- },
-
- _init: function (props={}) {
- this._web_actions = {};
- this._gettext = null;
- this._ngettext = null;
- this._ProxyConstructor =
- Gio.DBusProxy.makeProxyWrapper(WH2_DBUS_EXTENSION_INTERFACE);
- this.parent(props);
-
- if (this.well_known_name === '')
- throw new Error('The "well-known-name" parameter is required.');
- this._extension_name = this.well_known_name + '.webhelper';
-
- // Set up Webkit to load our web extension
- let context = WebKit2.WebContext.get_default();
- context.connect('initialize-web-extensions', () => {
- let libexec = Gio.File.new_for_path(Config.LIBEXECDIR);
- let path = libexec.get_child(LIBEXEC_SUBDIR).get_path();
-
- let localpath = GLib.getenv('WEBHELPER_UNINSTALLED_EXTENSION_DIR');
- if (localpath)
- path = localpath;
-
- context.set_web_extensions_directory(path);
- context.set_web_extensions_initialization_user_data(new GLib.Variant('s',
- this.well_known_name));
- });
-
- // Export our own DBus interface
- this._dbus_impl =
- Gio.DBusExportedObject.wrapJSObject(WH2_DBUS_MAIN_PROGRAM_INTERFACE,
- this);
- this._dbus_impl.export(this.connection, '/com/endlessm/gettext');
-
- // Set up handling for custom URIs
- WebHelper2Private.register_uri_scheme(WH2_URI_SCHEME,
- this._on_endless_uri_request.bind(this));
- WebHelper2Private.register_uri_scheme(WH2_LOCAL_FILE_SCHEME,
- this._on_local_file_request.bind(this));
- },
-
- _on_endless_uri_request: function (request) {
- let uri = request.get_uri();
-
- // get the name and parameters for the desired function
- let f_call = uri.substr((WH2_URI_SCHEME + '://').length).split('?');
- let function_name = decodeURI(f_call[0]);
-
- if (!this._web_actions.hasOwnProperty(function_name))
- throw new Error(('Undefined WebHelper action "%s". Did you define it with ' +
- 'WebHelper.Application.define_web_action()?').format(function_name));
-
- let parameters = {};
- if (f_call[1]) {
- // there are parameters
- let params = f_call[1].split('&');
- params.forEach(function (entry) {
- let param = entry.split('=');
-
- if (param.length == 2) {
- param[0] = decodeURIComponent(param[0]);
- param[1] = decodeURIComponent(param[1]);
- // and now we add it...
- parameters[param[0]] = param[1];
- }
- });
- }
-
- (this._web_actions[function_name].bind(this))(parameters);
-
- // Don't call request.finish(), because we don't want to finish the
- // action, which would involve loading a new page. The request dies
- // if we return from this function without calling ref() or finish()
- // on it.
- },
-
- _on_local_file_request: function (request) {
- let path = request.get_path();
- let file = Gio.File.new_for_path(path);
- let [content_type, certain] = Gio.content_type_guess(path, null);
- try {
- let stream = file.read(null);
- request.finish(stream, -1, content_type);
- } catch (error) {
- request.finish_error(error);
- }
- },
-
- // DBus implementations
-
- Gettext: function (string) {
- return this._gettext(string);
- },
-
- NGettext: function (singular, plural, number) {
- return this._ngettext(singular, plural, number);
- },
-
- // Public API
-
- /**
- * Method: set_gettext
- * Define function which translates text
- *
- * Parameters:
- * gettext_func - a function, or null
- *
- * When you plan to translate text in your web application, set this
- * property to the translation function.
- * The function must take one parameter, a string, and also return a
- * string.
- * The canonical example is gettext().
- *
- * This function will be called with each string to translate when you call
- * <translate_html()>.
- * The function is also made available directly to the browser-side
- * Javascript as *gettext()*, a property of the global object.
- *
- * Pass null for _gettext_func_ to unset the translation function.
- *
- * If this function has not been called, or has most recently been called
- * with null, then it is illegal to call <translate_html()>.
- *
- * Example:
- * > const Gettext = imports.gettext;
- * > const GETTEXT_DOMAIN = 'smoke-grinder';
- * >
- * > webhelper.set_gettext(Gettext.dgettext.bind(null, GETTEXT_DOMAIN));
- */
- set_gettext: function (gettext_func) {
- if (gettext_func !== null && typeof gettext_func !== 'function')
- throw new Error('The translation function must be a function, or ' +
- 'null.');
- this._gettext = gettext_func;
- },
-
- /**
- * Method: get_gettext
- * Retrieve the currently set translation function
- *
- * Returns:
- * the translation function previously set with <set_gettext()>, or null
- * if none is currently set.
- */
- get_gettext: function () {
- return this._gettext;
- },
-
- /**
- * Method: set_ngettext
- * Define function which translates singular/plural text
- *
- * Parameters:
- * ngettext_func - a function, or null
- *
- * When you plan to translate text in your web application, set this
- * property to the translation function.
- * The function must take three parameters: a string singular message, a
- * string plural message, and a number for which to generate the message.
- * The function must return a string.
- * The canonical example is ngettext().
- *
- * This function is made available directly to the browser-side Javascript
- * as *ngettext()*, a property of the global object.
- *
- * Pass null for _ngettext_func_ to unset the translation function.
- *
- * If this function has not been called, or has most recently been called
- * with null, then it is illegal to call *ngettext()* in the client-side
- * Javascript.
- *
- * Example:
- * > const WebHelper2 = imports.webhelper2;
- * > const Gettext = imports.gettext;
- * > const GETTEXT_DOMAIN = 'smoke-grinder';
- * >
- * > let webhelper = new WebHelper2.WebHelper('com.example.SmokeGrinder');
- * > webhelper.set_gettext(Gettext.dngettext.bind(null, GETTEXT_DOMAIN));
- */
- set_ngettext: function (ngettext_func) {
- if (ngettext_func !== null && typeof ngettext_func !== 'function')
- throw new Error('The translation function must be a function, or ' +
- 'null.');
- this._ngettext = ngettext_func;
- },
-
- /**
- * Method: get_ngettext
- * Retrieve the currently set singular/plural translation function
- *
- * Returns:
- * the translation function previously set with <set_ngettext()>, or null
- * if none is currently set.
- */
- get_ngettext: function () {
- return this._ngettext;
- },
-
- /**
- * Method: translate_html
- * Translate the HTML page in a webview asynchronously
- *
- * Parameters:
- * webview - a *WebKit2.WebView* with HTML loaded
- * cancellable - a *Gio.Cancellable*, or null
- * callback - a function that takes two parameters: this <WebHelper>
- * object, and a result object; or null if you don't want a callback
- *
- * Perform translation on all HTML elements marked with name="translatable"
- * in the HTML document displaying in _webview_.
- * The translation will be performed using the function you have set using
- * <set_gettext()>.
- *
- * When the translation is finished, _callback_ will be called.
- * You can get the result of the operation by calling
- * <translate_html_finish()> with the _result_ object passed to _callback_.
- *
- * You can optionally pass _cancellable_ if you want to be able to cancel
- * the operation.
- *
- * Example:
- * > webview.connect('load-changed', (webview, event) => {
- * > if (event === WebKit2.LoadEvent.FINISHED)
- * > webhelper.translate_html(webview, null, (obj, res) => {
- * > webhelper.translate_html_finish(res);
- * > // Translation done, show the page
- * > webview.show_all();
- * > });
- * > });
- */
- translate_html: function (webview, cancellable, callback) {
- let task = { callback: callback };
- // Wait for the DBus interface to appear on the bus
- task.watch_id = Gio.DBus.watch_name(Gio.BusType.SESSION,
- this._extension_name, Gio.BusNameWatcherFlags.NONE,
- (connection) => {
- // name appeared
- let webview_object_path = DBUS_WEBVIEW_EXPORT_PATH +
- webview.get_page_id();
- // Warning: this._ProxyConstructor will do a synchronous
- // operation unless you pass in a callback
- new this._ProxyConstructor(connection, this._extension_name,
- webview_object_path, (proxy, error) =>
- {
- if (error) {
- this._translate_callback(task, null, error);
- return;
- }
- if (cancellable)
- proxy.TranslateRemote(cancellable,
- this._translate_callback.bind(this, task));
- else
- proxy.TranslateRemote(this._translate_callback.bind(this,
- task));
- }, cancellable);
- },
- null); // do nothing when name vanishes
- return task;
- },
-
- _translate_callback: function (task, result, error) {
- Gio.DBus.unwatch_name(task.watch_id);
- if (error)
- task.error = error;
- if (task.callback)
- task.callback(this, task);
- },
-
- /**
- * Method: translate_html_finish
- * Get the result of <translate_html()>
- *
- * Parameters:
- * res - result object passed to your callback
- *
- * Finishes an operation started by <translate_html()>.
- * If the operation ended in an error, this function will throw that error.
- */
- translate_html_finish: function (res) {
- if (res.error)
- throw res.error;
- },
-
- /**
- * Method: define_web_action
- * Define an action that may be invoked from a WebView
- *
- * Parameters:
- * name - a string, which must be a valid URI location.
- * implementation - a function (see Callback Parameters below.)
- *
- * Callback Parameters:
- * dict - object containing properties corresponding to the query
- * parameters that the web action was called with
- *
- * Sets up an action that may be invoked from an HTML document inside a
- * WebView, or from the in-browser Javascript environment inside a WebView.
- * If you set up an action "setVolume" as follows:
- * > webhelper.define_web_action('setVolume', function (dict) { ... });
- * Then you can invoke the action inside the HTML document, e.g. as the
- * target of a link, as follows:
- * > <a href="webhelper://setVolume?volume=11">This one goes to 11</a>
- * Or from the in-browser Javascript, by navigating to the action URI, as
- * follows:
- * > window.location.href = 'webhelper://setVolume?volume=11';
- *
- * In both cases, the function would then be called with the _dict_
- * parameter equal to
- * > { "volume": "11" }
- *
- * If an action called _name_ is already defined, the new _implementation_
- * replaces the old one.
- */
- define_web_action: function (name, implementation) {
- if (typeof implementation !== 'function') {
- throw new Error('The implementation of a web action must be a ' +
- 'function.');
- }
- this._web_actions[name] = implementation;
- },
-
- /**
- * Method: define_web_actions
- * Define several web actions at once
- *
- * Parameters:
- * dict - an object, with web action names as property names, and their
- * implementations as values
- *
- * Convenience method to define more than one web action at once.
- * Calls <define_web_action()> on each property of _dict_.
- *
- * *Note* This API is Javascript-only. It will not be implemented in C.
- */
- define_web_actions: function (dict) {
- Object.keys(dict).forEach((key) =>
- this.define_web_action(key, dict[key]));
- },
-
- /**
- * Method: unregister
- * Break the connection to WebKit
- *
- * Breaks the connection to all webviews and removes all DBus objects.
- * You should call this in your application's *vfunc_dbus_unregister()*
- * implementation.
- *
- * After this function has been called, no WebHelper functionality will
- * work.
- */
- unregister: function () {
- this._dbus_impl.unexport_from_connection(this.connection);
- },
-});
diff --git a/webhelper/webhelper_private/config.js.in b/webhelper/webhelper_private/config.js.in
deleted file mode 100644
index f9d87cb..0000000
--- a/webhelper/webhelper_private/config.js.in
+++ /dev/null
@@ -1 +0,0 @@
-const LIBEXECDIR = '%libexecdir%';