mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Add a pre-format-html hook.
This commit is contained in:
parent
30ccbaaf21
commit
e3fed7e19e
@ -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
|
||||
|
151
src/scripting/smjs/cache_object.c
Normal file
151
src/scripting/smjs/cache_object.c
Normal 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;
|
||||
}
|
9
src/scripting/smjs/cache_object.h
Normal file
9
src/scripting/smjs/cache_object.h
Normal 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
|
||||
|
72
src/scripting/smjs/hooks.c
Normal file
72
src/scripting/smjs/hooks.c
Normal 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,
|
||||
};
|
8
src/scripting/smjs/hooks.h
Normal file
8
src/scripting/smjs/hooks.h
Normal 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
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user