Introduce GjsValue API
This commit is contained in:
parent
83285cb052
commit
94d7e7dc53
2 changed files with 438 additions and 3 deletions
370
midori/gjs.c
370
midori/gjs.c
|
@ -14,7 +14,364 @@
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
|
struct _GjsValue
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
JSContextRef js_context;
|
||||||
|
JSValueRef js_value;
|
||||||
|
gchar* string;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GjsValue, gjs_value, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gjs_value_finalize (GObject* object)
|
||||||
|
{
|
||||||
|
GjsValue* value = GJS_VALUE (object);
|
||||||
|
|
||||||
|
g_free (value->string);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gjs_value_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gjs_value_class_init (GjsValueClass* class)
|
||||||
|
{
|
||||||
|
GObjectClass* gobject_class = G_OBJECT_CLASS (class);
|
||||||
|
gobject_class->finalize = gjs_value_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gjs_value_init (GjsValue* value)
|
||||||
|
{
|
||||||
|
value->js_context = NULL;
|
||||||
|
value->js_value = NULL;
|
||||||
|
value->string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_new:
|
||||||
|
* @js_context: a #JSContextRef
|
||||||
|
* @js_value: a #JSValueRef or %NULL
|
||||||
|
*
|
||||||
|
* Creates a new #GjsValue for a #JsValueRef. If @js_value
|
||||||
|
* is %NULL, the new value represents the global object.
|
||||||
|
*
|
||||||
|
* Return value: a new #GjsValue
|
||||||
|
**/
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_new (JSContextRef js_context,
|
||||||
|
JSValueRef js_value)
|
||||||
|
{
|
||||||
|
GjsValue* value;
|
||||||
|
|
||||||
|
g_return_val_if_fail (js_context, NULL);
|
||||||
|
|
||||||
|
value = g_object_new (GJS_TYPE_VALUE, NULL);
|
||||||
|
value->js_context = js_context;
|
||||||
|
value->js_value = js_value ? js_value : JSContextGetGlobalObject (js_context);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_is_valid:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
*
|
||||||
|
* Determines whether the value is valid, with regard to
|
||||||
|
* its internal state. This is primarily useful for API
|
||||||
|
* to ensure that the value is in a defined condition.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if value is valid
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gjs_value_is_valid (GjsValue* value)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GJS_IS_VALUE (value), FALSE);
|
||||||
|
g_return_val_if_fail (value->js_context, FALSE);
|
||||||
|
g_return_val_if_fail (value->js_value, FALSE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_is_object:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
*
|
||||||
|
* Determines whether the value is an object.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if value is an object
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gjs_value_is_object (GjsValue* value)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (gjs_value_is_valid (value), FALSE);
|
||||||
|
|
||||||
|
return JSValueIsObject (value->js_context, value->js_value) == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_has_attribute:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @name: the name of a attribute
|
||||||
|
*
|
||||||
|
* Determines whether the value has the specified attribute.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the specified attribute exists
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gjs_value_has_attribute (GjsValue* value,
|
||||||
|
const gchar* name)
|
||||||
|
{
|
||||||
|
JSObjectRef js_object;
|
||||||
|
JSStringRef js_name;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_is_object (value), FALSE);
|
||||||
|
g_return_val_if_fail (name, FALSE);
|
||||||
|
|
||||||
|
js_object = JSValueToObject (value->js_context, value->js_value, NULL);
|
||||||
|
js_name = JSStringCreateWithUTF8CString (name);
|
||||||
|
result = JSObjectHasProperty (value->js_context, js_object, js_name) == true;
|
||||||
|
JSStringRelease (js_name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_get_attribute:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @name: the name of a attribute
|
||||||
|
*
|
||||||
|
* Retrieves the specified attribute.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
*
|
||||||
|
* Return value: a new #GjsValue
|
||||||
|
**/
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_attribute (GjsValue* value,
|
||||||
|
const gchar* name)
|
||||||
|
{
|
||||||
|
JSObjectRef js_object;
|
||||||
|
JSStringRef js_name;
|
||||||
|
JSValueRef js_value;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_has_attribute (value, name), NULL);
|
||||||
|
|
||||||
|
js_object = JSValueToObject (value->js_context, value->js_value, NULL);
|
||||||
|
js_name = JSStringCreateWithUTF8CString (name);
|
||||||
|
js_value = JSObjectGetProperty (value->js_context, js_object, js_name, NULL);
|
||||||
|
JSStringRelease (js_name);
|
||||||
|
|
||||||
|
return gjs_value_new (value->js_context, js_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_get_string:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
*
|
||||||
|
* Retrieves the value in the form of a string.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
*
|
||||||
|
* Note: The string won't reflect changes to the value.
|
||||||
|
*
|
||||||
|
* Return value: the value as a string
|
||||||
|
**/
|
||||||
|
const gchar*
|
||||||
|
gjs_value_get_string (GjsValue* value)
|
||||||
|
{
|
||||||
|
JSStringRef js_string;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_is_valid (value), NULL);
|
||||||
|
|
||||||
|
if (value->string)
|
||||||
|
return value->string;
|
||||||
|
|
||||||
|
js_string = JSValueToStringCopy (value->js_context, value->js_value, NULL);
|
||||||
|
value->string = gjs_string_utf8 (js_string);
|
||||||
|
JSStringRelease (js_string);
|
||||||
|
return value->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gjs_value_weak_notify_cb (GjsValue* attribute,
|
||||||
|
GjsValue* value)
|
||||||
|
{
|
||||||
|
g_object_unref (attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_get_attribute_string:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @name: the name of a attribute
|
||||||
|
*
|
||||||
|
* Retrieves the attribute of the value in the form of a string.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
*
|
||||||
|
* Note: The string won't reflect changes to the value.
|
||||||
|
*
|
||||||
|
* Return value: the value as a string
|
||||||
|
**/
|
||||||
|
const gchar*
|
||||||
|
gjs_value_get_attribute_string (GjsValue* value,
|
||||||
|
const gchar* name)
|
||||||
|
{
|
||||||
|
GjsValue* attribute;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_has_attribute (value, name), NULL);
|
||||||
|
|
||||||
|
attribute = gjs_value_get_attribute (value, name);
|
||||||
|
g_object_weak_ref (G_OBJECT (value),
|
||||||
|
(GWeakNotify)gjs_value_weak_notify_cb, attribute);
|
||||||
|
return gjs_value_get_string (attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_foreach:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @callback: a callback
|
||||||
|
* @user_data: user data
|
||||||
|
*
|
||||||
|
* Runs the specified callback for each attribute of the value.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gjs_value_foreach (GjsValue* value,
|
||||||
|
GjsCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
JSObjectRef js_object;
|
||||||
|
JSPropertyNameArrayRef js_properties;
|
||||||
|
size_t n_properties;
|
||||||
|
guint i;
|
||||||
|
JSStringRef js_property;
|
||||||
|
gchar* property;
|
||||||
|
GjsValue* attribute;
|
||||||
|
|
||||||
|
g_return_if_fail (gjs_value_is_object (value));
|
||||||
|
|
||||||
|
js_object = JSValueToObject (value->js_context, value->js_value, NULL);
|
||||||
|
js_properties = JSObjectCopyPropertyNames (value->js_context, js_object);
|
||||||
|
n_properties = JSPropertyNameArrayGetCount (js_properties);
|
||||||
|
for (i = 0; i < n_properties; i++)
|
||||||
|
{
|
||||||
|
js_property = JSPropertyNameArrayGetNameAtIndex (js_properties, i);
|
||||||
|
property = gjs_string_utf8 (js_property);
|
||||||
|
if (gjs_value_has_attribute (value, property))
|
||||||
|
{
|
||||||
|
attribute = gjs_value_get_attribute (value, property);
|
||||||
|
callback (attribute, user_data);
|
||||||
|
g_object_unref (attribute);
|
||||||
|
}
|
||||||
|
g_free (property);
|
||||||
|
JSStringRelease (js_property);
|
||||||
|
}
|
||||||
|
JSPropertyNameArrayRelease (js_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_get_by_name:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @name: the name of an object
|
||||||
|
*
|
||||||
|
* Retrieves a value for the specified name,
|
||||||
|
* for example "document" or "document.body".
|
||||||
|
*
|
||||||
|
* Return value: the value, or %NULL
|
||||||
|
**/
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_by_name (GjsValue* value,
|
||||||
|
const gchar* name)
|
||||||
|
{
|
||||||
|
gchar* script;
|
||||||
|
GjsValue* elements;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_is_valid (value), NULL);
|
||||||
|
g_return_val_if_fail (name, NULL);
|
||||||
|
|
||||||
|
script = g_strdup_printf ("return %s;", name);
|
||||||
|
elements = gjs_value_execute (value, script, NULL);
|
||||||
|
g_free (script);
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_get_elements_by_tag_name:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @name: the tag name
|
||||||
|
*
|
||||||
|
* Retrieves all children with the specified tag name.
|
||||||
|
*
|
||||||
|
* This can only be used on object values.
|
||||||
|
*
|
||||||
|
* Return value: all matching elements
|
||||||
|
**/
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_elements_by_tag_name (GjsValue* value,
|
||||||
|
const gchar* name)
|
||||||
|
{
|
||||||
|
gchar* script;
|
||||||
|
GjsValue* elements;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_is_valid (value), NULL);
|
||||||
|
g_return_val_if_fail (name, NULL);
|
||||||
|
|
||||||
|
script = g_strdup_printf ("return this.getElementsByTagName ('%s');", name);
|
||||||
|
elements = gjs_value_execute (value, script, NULL);
|
||||||
|
g_free (script);
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gjs_value_execute:
|
||||||
|
* @value: a #GjsValue
|
||||||
|
* @script: javascript code
|
||||||
|
*
|
||||||
|
* Executes a piece of javascript code. If @value is an object
|
||||||
|
* it can be referred to as 'this' in the code.
|
||||||
|
*
|
||||||
|
* A 'return' statement in the code will yield the result to
|
||||||
|
* the return value of this function.
|
||||||
|
*
|
||||||
|
* Return value: the return value, or %NULL
|
||||||
|
**/
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_execute (GjsValue* value,
|
||||||
|
const gchar* script,
|
||||||
|
gchar** exception)
|
||||||
|
{
|
||||||
|
JSStringRef js_script;
|
||||||
|
JSObjectRef js_function;
|
||||||
|
JSObjectRef js_object;
|
||||||
|
JSValueRef js_exception;
|
||||||
|
JSValueRef js_value;
|
||||||
|
JSStringRef js_message;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gjs_value_is_valid (value), FALSE);
|
||||||
|
g_return_val_if_fail (script, FALSE);
|
||||||
|
|
||||||
|
js_script = JSStringCreateWithUTF8CString (script);
|
||||||
|
js_function = JSObjectMakeFunction (value->js_context, NULL, 0, NULL,
|
||||||
|
js_script, NULL, 1, NULL);
|
||||||
|
JSStringRelease (js_script);
|
||||||
|
js_object = JSValueToObject (value->js_context, value->js_value, NULL);
|
||||||
|
js_exception = NULL;
|
||||||
|
js_value = JSObjectCallAsFunction (value->js_context, js_function,
|
||||||
|
js_object, 0, NULL, &js_exception);
|
||||||
|
if (!js_value && exception)
|
||||||
|
{
|
||||||
|
js_message = JSValueToStringCopy (value->js_context, js_exception, NULL);
|
||||||
|
*exception = gjs_string_utf8 (js_message);
|
||||||
|
JSStringRelease (js_message);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return gjs_value_new (value->js_context, js_value);
|
||||||
|
}
|
||||||
|
|
||||||
JSValueRef
|
JSValueRef
|
||||||
gjs_script_eval (JSContextRef js_context,
|
gjs_script_eval (JSContextRef js_context,
|
||||||
|
@ -93,12 +450,19 @@ gjs_script_from_file (JSContextRef js_context,
|
||||||
gchar*
|
gchar*
|
||||||
gjs_string_utf8 (JSStringRef js_string)
|
gjs_string_utf8 (JSStringRef js_string)
|
||||||
{
|
{
|
||||||
size_t size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
|
size_t size_utf8;
|
||||||
gchar* string_utf8 = g_new (gchar, 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);
|
JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
|
||||||
return string_utf8;
|
return string_utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_js_class_get_property_names_cb (JSContextRef js_context,
|
_js_class_get_property_names_cb (JSContextRef js_context,
|
||||||
JSObjectRef js_object,
|
JSObjectRef js_object,
|
||||||
|
|
71
midori/gjs.h
71
midori/gjs.h
|
@ -17,6 +17,77 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GJS_TYPE_VALUE \
|
||||||
|
(gjs_value_get_type ())
|
||||||
|
#define GJS_VALUE(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GJS_TYPE_VALUE, GjsValue))
|
||||||
|
#define GJS_VALUE_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST ((klass), GJS_TYPE_VALUE, GjsValueClass))
|
||||||
|
#define GJS_IS_VALUE(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GJS_TYPE_VALUE))
|
||||||
|
#define GJS_IS_VALUE_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE ((klass), GJS_TYPE_VALUE))
|
||||||
|
#define GJS_VALUE_GET_CLASS(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((obj), GJS_TYPE_VALUE, GjsValueClass))
|
||||||
|
|
||||||
|
typedef struct _GjsValue GjsValue;
|
||||||
|
typedef struct _GjsValueClass GjsValueClass;
|
||||||
|
|
||||||
|
struct _GjsValueClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType
|
||||||
|
gjs_value_get_type (void);
|
||||||
|
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_new (JSContextRef js_context,
|
||||||
|
JSValueRef js_value);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gjs_value_is_valid (GjsValue* value);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gjs_value_is_object (GjsValue* value);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gjs_value_has_attribute (GjsValue* value,
|
||||||
|
const gchar* name);
|
||||||
|
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_attribute (GjsValue* value,
|
||||||
|
const gchar* name);
|
||||||
|
|
||||||
|
const gchar*
|
||||||
|
gjs_value_get_string (GjsValue* value);
|
||||||
|
|
||||||
|
const gchar*
|
||||||
|
gjs_value_get_attribute_string (GjsValue* value,
|
||||||
|
const gchar* name);
|
||||||
|
|
||||||
|
typedef void
|
||||||
|
(*GjsCallback) (GjsValue* value,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
void
|
||||||
|
gjs_value_foreach (GjsValue* value,
|
||||||
|
GjsCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_by_name (GjsValue* value,
|
||||||
|
const gchar* name);
|
||||||
|
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_get_elements_by_tag_name (GjsValue* value,
|
||||||
|
const gchar* name);
|
||||||
|
|
||||||
|
GjsValue*
|
||||||
|
gjs_value_execute (GjsValue* value,
|
||||||
|
const gchar* script,
|
||||||
|
gchar** exception);
|
||||||
|
|
||||||
JSValueRef
|
JSValueRef
|
||||||
gjs_script_eval (JSContextRef js_context,
|
gjs_script_eval (JSContextRef js_context,
|
||||||
const gchar* script,
|
const gchar* script,
|
||||||
|
|
Loading…
Reference in a new issue