diff options
author | Philip Chimento <philip@endlessm.com> | 2017-04-12 15:24:48 -0700 |
---|---|---|
committer | Philip Chimento <philip@endlessm.com> | 2017-04-12 16:14:06 -0700 |
commit | e54bec3feb08b09de64945f72885c8c37258de60 (patch) | |
tree | e86d9c5ff13eaf6b7b5498d68624a413a18b544d /webhelper | |
parent | 72694e1790f779edc8f8ac163a66af561bf14500 (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.c | 36 | ||||
-rw-r--r-- | webhelper/lib/wh2private.h | 20 | ||||
-rw-r--r-- | webhelper/webextensions/wh2extension.c | 588 | ||||
-rw-r--r-- | webhelper/webextensions/wh2jscutil.c | 65 | ||||
-rw-r--r-- | webhelper/webextensions/wh2jscutil.h | 25 | ||||
-rw-r--r-- | webhelper/webhelper.js | 290 | ||||
-rw-r--r-- | webhelper/webhelper2.js | 529 | ||||
-rw-r--r-- | webhelper/webhelper_private/config.js.in | 1 |
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, - ®ex_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 (®ex_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%'; |