Split off the extension importing stuff into a new library, 'ShellJS'

This allows us to create a separate utility to import things from
shell extensions that does not have the entire Shell stack built up

https://bugzilla.gnome.org/show_bug.cgi?id=668429
This commit is contained in:
Jasper St. Pierre 2012-01-18 19:41:07 -05:00
parent d1d4142052
commit b2f33e2895
7 changed files with 125 additions and 72 deletions

View File

@ -117,6 +117,7 @@ AC_CHECK_FUNCS(JS_NewGlobalObject XFixesCreatePointerBarrier)
CFLAGS=$saved_CFLAGS
LIBS=$saved_LIBS
PKG_CHECK_MODULES(GNOME_SHELL_JS, glib-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)

View File

@ -8,6 +8,7 @@ const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const ShellJS = imports.gi.ShellJS;
const Soup = imports.gi.Soup;
const Config = imports.misc.config;
@ -388,7 +389,7 @@ function loadExtension(dir, type, enabled) {
let extensionModule;
let extensionState = null;
try {
global.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path());
ShellJS.add_extension_importer('imports.ui.extensionSystem.extensions', meta.uuid, dir.get_path());
extensionModule = extensions[meta.uuid].extension;
} catch (e) {
if (stylesheetPath != null)

View File

@ -86,7 +86,7 @@ gnome_shell_cflags = \
-DJSDIR=\"$(pkgdatadir)/js\"
privlibdir = $(pkglibdir)
privlib_LTLIBRARIES = libgnome-shell.la
privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la
shell_built_sources = \
shell-enum-types.h \
@ -182,6 +182,23 @@ EXTRA_DIST += test-gapplication.js
########################################
libgnome_shell_js_la_SOURCES = \
shell-js.h \
shell-js.c \
$(NULL)
libgnome_shell_js_la_LIBADD = \
$(GNOME_SHELL_JS_LIBS) \
$(NULL)
libgnome_shell_js_la_LDFLAGS = \
-avoid-version
libgnome_shell_js_la_CPPFLAGS = \
$(GNOME_SHELL_JS_CFLAGS)
########################################
shell_recorder_sources = \
shell-recorder.c \
shell-recorder.h
@ -275,6 +292,13 @@ Shell_0_1_gir_SCANNERFLAGS = --include-uninstalled=$(builddir)/St-1.0.gir \
INTROSPECTION_GIRS += Shell-0.1.gir
CLEANFILES += Shell-0.1.gir
ShellJS-0.1.gir: libgnome-shell-js.la
ShellJS_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
ShellJS_0_1_gir_LIBS = libgnome-shell-js.la
ShellJS_0_1_gir_FILES = $(libgnome_shell_js_la_SOURCES)
INTROSPECTION_GIRS += ShellJS-0.1.gir
CLEANFILES += ShellJS-0.1.gir
St-1.0.gir: libst-1.0.la
St_1_0_gir_INCLUDES = Clutter-1.0 Gtk-3.0
St_1_0_gir_CFLAGS = $(st_cflags) -DST_COMPILATION

View File

@ -1177,70 +1177,6 @@ shell_global_destroy_pointer_barrier (ShellGlobal *global, guint32 barrier)
#endif
}
/**
* shell_global_add_extension_importer:
* @target_object_script: JavaScript code evaluating to a target object
* @target_property: Name of property to use for importer
* @directory: Source directory:
* @error: A #GError
*
* This function sets a property named @target_property on the object
* resulting from the evaluation of @target_object_script code, which
* acts as a GJS importer for directory @directory.
*
* Returns: %TRUE on success
*/
gboolean
shell_global_add_extension_importer (ShellGlobal *global,
const char *target_object_script,
const char *target_property,
const char *directory,
GError **error)
{
jsval target_object;
JSContext *context = gjs_context_get_native_context (global->js_context);
char *search_path[2] = { 0, 0 };
JS_BeginRequest (context);
// This is a bit of a hack; ideally we'd be able to pass our target
// object directly into this function, but introspection doesn't
// support that at the moment. Instead evaluate a string to get it.
if (!JS_EvaluateScript(context,
JS_GetGlobalObject(context),
target_object_script,
strlen (target_object_script),
"<target_object_script>",
0,
&target_object))
{
char *message;
gjs_log_exception(context,
&message);
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"%s", message ? message : "(unknown)");
g_free(message);
goto out_error;
}
if (!JSVAL_IS_OBJECT (target_object))
{
g_error ("shell_global_add_extension_importer: invalid target object");
goto out_error;
}
search_path[0] = (char*)directory;
gjs_define_importer (context, JSVAL_TO_OBJECT (target_object), target_property, (const char **)search_path, FALSE);
JS_EndRequest (context);
return TRUE;
out_error:
JS_EndRequest (context);
return FALSE;
}
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
*
* Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering

View File

@ -119,12 +119,6 @@ void shell_global_run_at_leisure (ShellGlobal *global,
/* Misc utilities / Shell API */
gboolean shell_global_add_extension_importer (ShellGlobal *global,
const char *target_object_script,
const char *target_property,
const char *directory,
GError **error);
void shell_global_sync_pointer (ShellGlobal *global);
GAppLaunchContext *

81
src/shell-js.c Normal file
View File

@ -0,0 +1,81 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "config.h"
#include "shell-js.h"
#include <jsapi.h>
#include <gio/gio.h>
#include <gjs/gjs.h>
#include <gjs/gjs-module.h>
/**
* shell_js_add_extension_importer:
* @target_object_script: JavaScript code evaluating to a target object
* @target_property: Name of property to use for importer
* @directory: Source directory:
* @error: A #GError
*
* This function sets a property named @target_property on the object
* resulting from the evaluation of @target_object_script code, which
* acts as a GJS importer for directory @directory.
*
* Returns: %TRUE on success
*/
gboolean
shell_js_add_extension_importer (const char *target_object_script,
const char *target_property,
const char *directory,
GError **error)
{
jsval target_object;
GList *contexts;
JSContext *context;
char *search_path[2] = { 0, 0 };
gboolean ret = FALSE;
/* Take the first GjsContext from all of them --
* we should only ever have one context, so this
* should be alright. */
contexts = gjs_context_get_all ();
context = gjs_context_get_native_context (contexts->data);
g_list_free_full (contexts, g_object_unref);
JS_BeginRequest (context);
/* This is a bit of a hack; ideally we'd be able to pass our target
* object directly into this function, but introspection doesn't
* support that at the moment. Instead evaluate a string to get it. */
if (!JS_EvaluateScript(context,
JS_GetGlobalObject(context),
target_object_script,
strlen (target_object_script),
"<target_object_script>",
0,
&target_object))
{
char *message;
gjs_log_exception(context,
&message);
g_set_error(error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"%s", message ? message : "(unknown)");
g_free(message);
goto out;
}
if (!JSVAL_IS_OBJECT (target_object))
{
g_error ("shell_js_add_extension_importer: invalid target object");
goto out;
}
search_path[0] = (char*)directory;
gjs_define_importer (context, JSVAL_TO_OBJECT (target_object), target_property, (const char **)search_path, FALSE);
ret = TRUE;
out:
JS_EndRequest (context);
return ret;
}

16
src/shell-js.h Normal file
View File

@ -0,0 +1,16 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_JS_H__
#define __SHELL_JS_H__
#include <glib.h>
G_BEGIN_DECLS
gboolean shell_js_add_extension_importer (const char *target_object_script,
const char *target_property,
const char *directory,
GError **error);
G_BEGIN_DECLS
#endif /* __SHELL_JS_H__ */