1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-30 01:55:30 +00:00

Add a pre-format-html hook.

This commit is contained in:
Miciah Dashiel Butler Masters 2005-12-18 17:58:42 +00:00 committed by Miciah Dashiel Butler Masters
parent 30ccbaaf21
commit e3fed7e19e
6 changed files with 243 additions and 2 deletions

View File

@ -3,6 +3,6 @@ include $(top_builddir)/Makefile.config
INCLUDES += $(SPIDERMONKEY_CFLAGS)
OBJS = smjs.o core.o elinks_object.o
OBJS = smjs.o core.o hooks.o elinks_object.o cache_object.o
include $(top_srcdir)/Makefile.lib

View File

@ -0,0 +1,151 @@
/* Exports struct cache_entry to the world of ECMAScript */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "elinks.h"
#include "cache/cache.h"
#include "ecmascript/spidermonkey/util.h"
#include "scripting/smjs/core.h"
#include "util/error.h"
#include "util/memory.h"
enum cache_entry_prop {
CACHE_ENTRY_CONTENT,
CACHE_ENTRY_TYPE,
CACHE_ENTRY_LENGTH,
CACHE_ENTRY_HEAD,
};
static const JSPropertySpec cache_entry_props[] = {
{ "content", CACHE_ENTRY_CONTENT, JSPROP_ENUMERATE },
{ "type", CACHE_ENTRY_TYPE, JSPROP_ENUMERATE },
{ "length", CACHE_ENTRY_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
{ "head", CACHE_ENTRY_HEAD, JSPROP_ENUMERATE },
};
static JSBool
cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
struct cache_entry *cached = JS_GetPrivate(ctx, obj);
if (!cached) return JS_FALSE;
undef_to_jsval(ctx, vp);
if (!JSVAL_IS_INT(id))
return JS_FALSE;
switch (JSVAL_TO_INT(id)) {
case CACHE_ENTRY_CONTENT: {
struct fragment *fragment = get_cache_fragment(cached);
assert(fragment);
*vp = STRING_TO_JSVAL(JS_NewStringCopyN(smjs_ctx,
fragment->data,
fragment->length));
return JS_TRUE;
}
case CACHE_ENTRY_TYPE:
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
cached->content_type));
return JS_TRUE;
case CACHE_ENTRY_HEAD:
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx,
cached->head));
return JS_TRUE;
case CACHE_ENTRY_LENGTH:
*vp = INT_TO_JSVAL(cached->length);
return JS_TRUE;
default:
INTERNAL("Invalid ID %d in cache_entry_get_property().",
JSVAL_TO_INT(id));
}
return JS_FALSE;
}
static JSBool
cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
struct cache_entry *cached = JS_GetPrivate(ctx, obj);
if (!cached) return JS_FALSE;
if (!JSVAL_IS_INT(id))
return JS_FALSE;
switch (JSVAL_TO_INT(id)) {
case CACHE_ENTRY_CONTENT: {
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
unsigned char *str = JS_GetStringBytes(jsstr);
size_t len = JS_GetStringLength(jsstr);
add_fragment(cached, 0, str, len);
normalize_cache_entry(cached, len);
return JS_TRUE;
}
case CACHE_ENTRY_TYPE: {
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
unsigned char *str = JS_GetStringBytes(jsstr);
mem_free_set(&cached->content_type, stracpy(str));
return JS_TRUE;
}
case CACHE_ENTRY_HEAD: {
JSString *jsstr = JS_ValueToString(smjs_ctx, *vp);
unsigned char *str = JS_GetStringBytes(jsstr);
mem_free_set(&cached->head, stracpy(str));
return JS_TRUE;
}
case CACHE_ENTRY_LENGTH:
INTERNAL("attempted to assign to cache_entry's length");
return JS_FALSE;
default:
INTERNAL("Invalid ID %d in cache_entry_get_property().",
JSVAL_TO_INT(id));
}
return JS_FALSE;
}
static const JSClass cache_entry_class = {
"cache_entry",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
cache_entry_get_property, cache_entry_set_property,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
JSObject *
get_cache_entry_object(struct cache_entry *cached)
{
JSObject *cache_entry_object;
cache_entry_object = JS_NewObject(smjs_ctx,
(JSClass *) &cache_entry_class,
NULL, NULL);
if (!cache_entry_object) return NULL;
JS_SetPrivate(smjs_ctx, cache_entry_object, cached);
JS_DefineProperties(smjs_ctx, cache_entry_object,
(JSPropertySpec *) cache_entry_props);
return cache_entry_object;
}

View File

@ -0,0 +1,9 @@
#ifndef EL__SCRIPTING_SMJS_CACHE_H
#define EL__SCRIPTING_SMJS_CACHE_H
struct cache_entry;
JSObject *get_cache_entry_object(struct cache_entry *cached);
#endif

View File

@ -0,0 +1,72 @@
/* Ruby scripting hooks */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "elinks.h"
#include "cache/cache.h"
#include "ecmascript/spidermonkey/util.h"
#include "main/event.h"
#include "main/module.h"
#include "scripting/smjs/cache_object.h"
#include "scripting/smjs/core.h"
#include "scripting/smjs/elinks_object.h"
#include "scripting/smjs/hooks.h"
#include "session/session.h"
/* If elinks.<hook> is defined, call it with the given arguments,
* store the return value in rval, and return JS_TRUE. Else return JS_FALSE. */
static JSBool
call_script_hook(unsigned char *hook, jsval argv[], int argc, jsval *rval)
{
JSFunction *func;
if (JS_FALSE == JS_GetProperty(smjs_ctx, smjs_elinks_object,
hook, rval))
return JS_FALSE;
if (JSVAL_VOID == *rval)
return JS_FALSE;
func = JS_ValueToFunction(smjs_ctx, *rval);
assert(func);
return JS_CallFunction(smjs_ctx, smjs_elinks_object,
func, argc, argv, rval);
}
static enum evhook_status
script_hook_pre_format_html(va_list ap, void *data)
{
struct session *ses = va_arg(ap, struct session *);
struct cache_entry *cached = va_arg(ap, struct cache_entry *);
enum evhook_status ret = EVENT_HOOK_STATUS_NEXT;
JSObject *cache_entry_object;
jsval args[1], rval;
evhook_use_params(ses && cached);
if (!smjs_ctx || !cached->length) goto end;
smjs_ses = ses;
cache_entry_object = get_cache_entry_object(cached);
args[0] = OBJECT_TO_JSVAL(cache_entry_object);
if (JS_TRUE == call_script_hook("preformat_html", args, 1, &rval))
if (JS_FALSE == JSVAL_TO_BOOLEAN(rval))
ret = EVENT_HOOK_STATUS_LAST;
end:
smjs_ses = NULL;
return ret;
}
struct event_hook_info smjs_scripting_hooks[] = {
{ "pre-format-html", 0, script_hook_pre_format_html, NULL },
NULL_EVENT_HOOK_INFO,
};

View File

@ -0,0 +1,8 @@
#ifndef EL__SCRIPTING_SMJS_HOOKS_H
#define EL__SCRIPTING_SMJS_HOOKS_H
struct event_hook_info;
extern struct event_hook_info smjs_scripting_hooks[];
#endif

View File

@ -8,12 +8,13 @@
#include "main/module.h"
#include "scripting/smjs/core.h"
#include "scripting/smjs/hooks.h"
struct module smjs_scripting_module = struct_module(
/* name: */ "ECMAScript scripting engine",
/* options: */ NULL,
/* events: */ NULL,
/* events: */ smjs_scripting_hooks,
/* submodules: */ NULL,
/* data: */ NULL,
/* init: */ init_smjs,