Remove incomplete Javascript extension
This commit is contained in:
parent
7a7f4c6a44
commit
3aad0189c4
1 changed files with 0 additions and 327 deletions
|
@ -1,327 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
See the file COPYING for the full license text.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
midori.tabs
|
|
||||||
midori.windows
|
|
||||||
midori.currentWindow
|
|
||||||
midori.createAction({name:'Example',label:'_Example',icon:'gtk-info',tooltip:'Examples',activate:function()})
|
|
||||||
action = midori.currentWindow.getAction(name)
|
|
||||||
foreach (window as midori.windows) window.getAction('myaction').activate()
|
|
||||||
midori.window[i].tabs
|
|
||||||
midori.addWindow
|
|
||||||
midori.addTab
|
|
||||||
midori.removeWindow
|
|
||||||
midori.removeTab
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <midori/midori.h>
|
|
||||||
#include <midori/sokoke.h>
|
|
||||||
#include <JavaScriptCore/JavaScript.h>
|
|
||||||
|
|
||||||
gchar*
|
|
||||||
sokoke_js_string_utf8 (JSStringRef js_string)
|
|
||||||
{
|
|
||||||
size_t size_utf8;
|
|
||||||
gchar* string_utf8;
|
|
||||||
|
|
||||||
g_return_val_if_fail (js_string, NULL);
|
|
||||||
|
|
||||||
size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
|
|
||||||
string_utf8 = g_new (gchar, size_utf8);
|
|
||||||
JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
|
|
||||||
return string_utf8;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
javascript_deactivate_cb (MidoriExtension* extension,
|
|
||||||
MidoriBrowser* browser)
|
|
||||||
{
|
|
||||||
/* FIXME: Unload all javascript extensions */
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValueRef
|
|
||||||
midori_javascript_midori_action_cb (JSContextRef js_context,
|
|
||||||
JSObjectRef js_function,
|
|
||||||
JSObjectRef js_this,
|
|
||||||
size_t n_arguments,
|
|
||||||
const JSValueRef js_arguments[],
|
|
||||||
JSValueRef* js_exception)
|
|
||||||
{
|
|
||||||
GtkAction* action;
|
|
||||||
JSObjectRef js_meta;
|
|
||||||
JSPropertyNameArrayRef js_properties;
|
|
||||||
size_t n_properties;
|
|
||||||
guint i;
|
|
||||||
MidoriApp* app;
|
|
||||||
|
|
||||||
if (n_arguments != 1)
|
|
||||||
{
|
|
||||||
*js_exception = JSValueMakeString (js_context,
|
|
||||||
JSStringCreateWithUTF8CString (
|
|
||||||
"MidoriError: Wrong number of arguments; 'midori.createAction ({property:value, ...})'"));
|
|
||||||
return JSValueMakeNull (js_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JSValueIsObject (js_context, js_arguments[0]))
|
|
||||||
{
|
|
||||||
*js_exception = JSValueMakeString (js_context,
|
|
||||||
JSStringCreateWithUTF8CString (
|
|
||||||
"MidoriError: Argument is not an object; 'midori.createAction ({property:value, ...})'"));
|
|
||||||
return JSValueMakeNull (js_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
action = g_object_new (GTK_TYPE_ACTION, NULL);
|
|
||||||
js_meta = JSValueToObject (js_context, js_arguments[0], NULL);
|
|
||||||
js_properties = JSObjectCopyPropertyNames (js_context, js_meta);
|
|
||||||
n_properties = JSPropertyNameArrayGetCount (js_properties);
|
|
||||||
for (i = 0; i < n_properties; i++)
|
|
||||||
{
|
|
||||||
JSStringRef js_name;
|
|
||||||
gchar* name;
|
|
||||||
JSValueRef js_property;
|
|
||||||
JSStringRef js_string;
|
|
||||||
gchar* string;
|
|
||||||
|
|
||||||
js_name = JSPropertyNameArrayGetNameAtIndex (js_properties, i);
|
|
||||||
name = sokoke_js_string_utf8 (js_name);
|
|
||||||
if (g_str_equal (name, "label"))
|
|
||||||
{
|
|
||||||
js_property = JSObjectGetProperty (js_context, js_meta, js_name, NULL);
|
|
||||||
js_string = JSValueToStringCopy (js_context, js_property, NULL);
|
|
||||||
string = sokoke_js_string_utf8 (js_string);
|
|
||||||
JSStringRelease (js_string);
|
|
||||||
g_object_set (action, "label", string, NULL);
|
|
||||||
g_free (string);
|
|
||||||
}
|
|
||||||
else if (g_str_equal (name, "icon"))
|
|
||||||
{
|
|
||||||
js_property = JSObjectGetProperty (js_context, js_meta, js_name, NULL);
|
|
||||||
js_string = JSValueToStringCopy (js_context, js_property, NULL);
|
|
||||||
string = sokoke_js_string_utf8 (js_string);
|
|
||||||
JSStringRelease (js_string);
|
|
||||||
/* FIXME: stock-id, or icon-name, or URI */
|
|
||||||
g_object_set (action, "stock-id", string, NULL);
|
|
||||||
g_free (string);
|
|
||||||
}
|
|
||||||
else if (g_str_equal (name, "tooltip"))
|
|
||||||
{
|
|
||||||
js_property = JSObjectGetProperty (js_context, js_meta, js_name, NULL);
|
|
||||||
js_string = JSValueToStringCopy (js_context, js_property, NULL);
|
|
||||||
string = sokoke_js_string_utf8 (js_string);
|
|
||||||
JSStringRelease (js_string);
|
|
||||||
g_object_set (action, "tooltip", string, NULL);
|
|
||||||
g_free (string);
|
|
||||||
}
|
|
||||||
else if (g_str_equal (name, "activate"))
|
|
||||||
{
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*js_exception = JSValueMakeString (js_context,
|
|
||||||
JSStringCreateWithUTF8CString (
|
|
||||||
"MidoriError: Unknown property; 'midori.createAction ({property:value, ...})'"));
|
|
||||||
return JSValueMakeNull (js_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((app = JSObjectGetPrivate (js_this)))
|
|
||||||
{
|
|
||||||
/* TODO: Offer the user to add a toolbar button */
|
|
||||||
}
|
|
||||||
/* TODO: add action to all existing and future browsers */
|
|
||||||
/* gtk_action_connect_accelerator */
|
|
||||||
return JSValueMakeNull (js_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSContextRef
|
|
||||||
midori_javascript_context (MidoriApp* app)
|
|
||||||
{
|
|
||||||
JSContextRef js_context = JSGlobalContextCreateInGroup (NULL, NULL);
|
|
||||||
JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
|
|
||||||
JSClassRef js_class;
|
|
||||||
JSObjectRef js_object;
|
|
||||||
JSStringRef js_name;
|
|
||||||
JSStaticFunction functions[] = {
|
|
||||||
{ "createAction", midori_javascript_midori_action_cb, kJSPropertyAttributeNone },
|
|
||||||
{ NULL, NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
js_class_def.className = "midori";
|
|
||||||
js_class_def.staticFunctions = functions;
|
|
||||||
js_class = JSClassCreate (&js_class_def);
|
|
||||||
js_object = JSObjectMake (js_context, js_class, app);
|
|
||||||
|
|
||||||
js_name = JSStringCreateWithUTF8CString ("midori");
|
|
||||||
JSObjectSetProperty (js_context, JSContextGetGlobalObject (js_context),
|
|
||||||
js_name, js_object, kJSPropertyAttributeNone, NULL);
|
|
||||||
JSStringRelease (js_name);
|
|
||||||
|
|
||||||
return js_context;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
midori_javascript_extension_activate_cb (MidoriExtension* extension,
|
|
||||||
MidoriApp* app)
|
|
||||||
{
|
|
||||||
gchar* filename = g_object_get_data (G_OBJECT (extension), "filename");
|
|
||||||
gchar* fullname = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
|
||||||
PACKAGE_NAME, "extensions", filename, NULL);
|
|
||||||
gchar* script;
|
|
||||||
GError* error = NULL;
|
|
||||||
if (g_file_get_contents (fullname, &script, NULL, &error))
|
|
||||||
{
|
|
||||||
JSContextRef js_context = midori_javascript_context (app);
|
|
||||||
gchar* exception = NULL;
|
|
||||||
g_free (sokoke_js_script_eval (js_context, script, &exception));
|
|
||||||
if (exception)
|
|
||||||
{
|
|
||||||
g_object_set (extension, "description",
|
|
||||||
exception, "version", NULL, NULL);
|
|
||||||
g_warning ("%s", exception);
|
|
||||||
g_free (exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_set (extension, "description",
|
|
||||||
error->message, "version", NULL, NULL);
|
|
||||||
g_warning ("%s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
g_free (fullname);
|
|
||||||
g_free (script);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
javascript_load_extensions (gchar** active,
|
|
||||||
MidoriApp* app,
|
|
||||||
const gchar* path)
|
|
||||||
{
|
|
||||||
GDir* dir;
|
|
||||||
|
|
||||||
/* TODO: Monitor folder for new files or modifications at runtime */
|
|
||||||
if ((dir = g_dir_open (path, 0, NULL)))
|
|
||||||
{
|
|
||||||
KatzeArray* extensions = katze_object_get_object (app, "extensions");
|
|
||||||
JSContextRef js_context = midori_javascript_context (app);
|
|
||||||
const gchar* filename;
|
|
||||||
|
|
||||||
while ((filename = g_dir_read_name (dir)))
|
|
||||||
{
|
|
||||||
gchar* fullname;
|
|
||||||
GError* error;
|
|
||||||
gchar* script;
|
|
||||||
MidoriExtension* extension;
|
|
||||||
|
|
||||||
/* Ignore files which don't have the correct suffix */
|
|
||||||
if (!g_str_has_suffix (filename, ".js"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fullname = g_build_filename (path, filename, NULL);
|
|
||||||
error = NULL;
|
|
||||||
extension = g_object_new (MIDORI_TYPE_EXTENSION, "name", filename, NULL);
|
|
||||||
if (g_file_get_contents (fullname, &script, NULL, &error))
|
|
||||||
{
|
|
||||||
JSStringRef js_script;
|
|
||||||
JSValueRef js_exception;
|
|
||||||
|
|
||||||
js_script = JSStringCreateWithUTF8CString (script);
|
|
||||||
if (JSCheckScriptSyntax (js_context, js_script, NULL,
|
|
||||||
0, &js_exception))
|
|
||||||
{
|
|
||||||
/* FIXME: Read meta data from .js file */
|
|
||||||
g_object_set (extension, "description", "",
|
|
||||||
"version", "0.1", "authors", "", NULL);
|
|
||||||
/* Signal that we want the extension to load and save */
|
|
||||||
g_object_set_data_full (G_OBJECT (extension), "filename",
|
|
||||||
g_strdup (filename), g_free);
|
|
||||||
if (midori_extension_is_prepared (extension))
|
|
||||||
midori_extension_get_config_dir (extension);
|
|
||||||
g_signal_connect (extension, "activate",
|
|
||||||
G_CALLBACK (midori_javascript_extension_activate_cb), NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JSStringRef js_string = JSValueToStringCopy (js_context,
|
|
||||||
js_exception, NULL);
|
|
||||||
gchar* string = sokoke_js_string_utf8 (js_string);
|
|
||||||
JSStringRelease (js_string);
|
|
||||||
g_object_set (extension, "description", string, NULL);
|
|
||||||
g_warning ("%s", string);
|
|
||||||
g_free (string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_set (extension, "description", error->message, NULL);
|
|
||||||
g_warning ("%s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
g_free (fullname);
|
|
||||||
katze_array_add_item (extensions, extension);
|
|
||||||
if (active)
|
|
||||||
{
|
|
||||||
guint i = 0;
|
|
||||||
gchar* name;
|
|
||||||
while ((name = active[i++]))
|
|
||||||
if (!g_strcmp0 (filename, name))
|
|
||||||
g_signal_emit_by_name (extension, "activate", app);
|
|
||||||
}
|
|
||||||
/* FIXME main.c needs to monitor extensions
|
|
||||||
g_signal_connect_after (extension, "activate",
|
|
||||||
G_CALLBACK (extension_activate_cb), app);
|
|
||||||
g_signal_connect_after (extension, "deactivate",
|
|
||||||
G_CALLBACK (extension_activate_cb), app); */
|
|
||||||
g_object_unref (extension);
|
|
||||||
}
|
|
||||||
g_object_unref (extensions);
|
|
||||||
g_dir_close (dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
javascript_activate_cb (MidoriExtension* extension,
|
|
||||||
MidoriApp* app)
|
|
||||||
{
|
|
||||||
gchar** active = midori_extension_get_string_list (extension, "extensions", NULL);
|
|
||||||
/* FIXME Scan system data dirs */
|
|
||||||
gchar* path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
|
||||||
PACKAGE_NAME, "extensions", NULL);
|
|
||||||
javascript_load_extensions (active, app, path);
|
|
||||||
g_free (path);
|
|
||||||
g_strfreev (active);
|
|
||||||
|
|
||||||
g_signal_connect (extension, "deactivate",
|
|
||||||
G_CALLBACK (javascript_deactivate_cb), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
MidoriExtension*
|
|
||||||
extension_init (void)
|
|
||||||
{
|
|
||||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
|
||||||
"name", _("Javascript extensions"),
|
|
||||||
"description", _("Enable extensions written in Javascript"),
|
|
||||||
"version", "0.1",
|
|
||||||
"authors", "Christian Dywan <christian@twotoasts.de>",
|
|
||||||
NULL);
|
|
||||||
midori_extension_install_string_list (extension, "extensions", NULL, G_MAXSIZE);
|
|
||||||
|
|
||||||
g_signal_connect (extension, "activate",
|
|
||||||
G_CALLBACK (javascript_activate_cb), NULL);
|
|
||||||
|
|
||||||
return extension;
|
|
||||||
}
|
|
Loading…
Reference in a new issue