From 17b7ffc7dfc86e4af4bb931b2537bdd3e6d1bdc8 Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Thu, 29 Dec 2005 07:05:31 +0000 Subject: [PATCH] Add elinks.bookmarks interface for reading bookmarks. --- src/bookmarks/bookmarks.c | 16 +++ src/bookmarks/bookmarks.h | 2 + src/scripting/smjs/Makefile | 2 +- src/scripting/smjs/bookmarks.c | 213 +++++++++++++++++++++++++++++ src/scripting/smjs/bookmarks.h | 8 ++ src/scripting/smjs/elinks_object.c | 2 + 6 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 src/scripting/smjs/bookmarks.c create mode 100644 src/scripting/smjs/bookmarks.h diff --git a/src/bookmarks/bookmarks.c b/src/bookmarks/bookmarks.c index 2fa9ce97..722f8754 100644 --- a/src/bookmarks/bookmarks.c +++ b/src/bookmarks/bookmarks.c @@ -443,6 +443,22 @@ update_bookmark(struct bookmark *bm, unsigned char *title, return 1; } +/* Search for a bookmark with the given title. Search in the given folder + * or in the root if folder is NULL. */ +struct bookmark * +get_bookmark_by_name(struct bookmark *folder, unsigned char *title) +{ + struct bookmark *bookmark; + struct list_head *lh; + + lh = folder ? &folder->child : &bookmarks; + + foreach (bookmark, *lh) + if (!strcmp(bookmark->title, title)) return bookmark; + + return NULL; +} + /* Search bookmark cache for item matching url. */ struct bookmark * get_bookmark(unsigned char *url) diff --git a/src/bookmarks/bookmarks.h b/src/bookmarks/bookmarks.h index 4c78d827..4c576aa7 100644 --- a/src/bookmarks/bookmarks.h +++ b/src/bookmarks/bookmarks.h @@ -43,6 +43,8 @@ int bookmarks_are_dirty(void); void delete_bookmark(struct bookmark *); struct bookmark *add_bookmark(struct bookmark *, int, unsigned char *, unsigned char *); +struct bookmark *get_bookmark_by_name(struct bookmark *folder, + unsigned char *title); struct bookmark *get_bookmark(unsigned char *url); void bookmark_terminal_tabs(struct terminal *term, unsigned char *foldername); void bookmark_auto_save_tabs(struct terminal *term); diff --git a/src/scripting/smjs/Makefile b/src/scripting/smjs/Makefile index a827b3e8..7ff12a14 100644 --- a/src/scripting/smjs/Makefile +++ b/src/scripting/smjs/Makefile @@ -4,6 +4,6 @@ include $(top_builddir)/Makefile.config INCLUDES += $(SPIDERMONKEY_CFLAGS) OBJS = smjs.o core.o global_object.o hooks.o elinks_object.o cache_object.o \ - keybinding.o + bookmarks.o keybinding.o include $(top_srcdir)/Makefile.lib diff --git a/src/scripting/smjs/bookmarks.c b/src/scripting/smjs/bookmarks.c new file mode 100644 index 00000000..dfeef0b3 --- /dev/null +++ b/src/scripting/smjs/bookmarks.c @@ -0,0 +1,213 @@ +/* "elinks.bookmarks" */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "elinks.h" + +#include "bookmarks/bookmarks.h" +#include "ecmascript/spidermonkey/util.h" +#include "main/event.h" +#include "scripting/smjs/core.h" +#include "scripting/smjs/elinks_object.h" +#include "util/memory.h" + + +/*** common code ***/ + +static JSObject * +smjs_get_bookmark_generic_object(struct bookmark *bookmark, JSClass *clasp) +{ + JSObject *jsobj; + + jsobj = JS_NewObject(smjs_ctx, clasp, NULL, NULL); + if (!jsobj) return NULL; + + if (!bookmark) return jsobj; + + if (JS_TRUE == JS_SetPrivate(smjs_ctx, jsobj, bookmark)) { + object_lock(bookmark); + + return jsobj; + } + + return NULL; +}; + +static void +bookmark_finalize(JSContext *ctx, JSObject *obj) +{ + struct bookmark *bookmark = JS_GetPrivate(ctx, obj); + + if (bookmark) object_unlock(bookmark); +} + + +/*** bookmark object ***/ + +enum bookmark_prop { + BOOKMARK_TITLE, + BOOKMARK_URL, + BOOKMARK_CHILDREN, +}; + +static const JSPropertySpec bookmark_props[] = { + { "title", BOOKMARK_TITLE, JSPROP_ENUMERATE }, + { "url", BOOKMARK_URL, JSPROP_ENUMERATE }, + { "children", BOOKMARK_CHILDREN, JSPROP_ENUMERATE | JSPROP_READONLY }, + { NULL } +}; + +static JSObject *smjs_get_bookmark_folder_object(struct bookmark *bookmark); + +static JSBool +bookmark_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) +{ + struct bookmark *bookmark = JS_GetPrivate(ctx, obj); + + if (!bookmark) return JS_FALSE; + + undef_to_jsval(ctx, vp); + + if (!JSVAL_IS_INT(id)) + return JS_FALSE; + + switch (JSVAL_TO_INT(id)) { + case BOOKMARK_TITLE: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, + bookmark->title)); + + return JS_TRUE; + case BOOKMARK_URL: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, + bookmark->url)); + + return JS_TRUE; + case BOOKMARK_CHILDREN: + *vp = OBJECT_TO_JSVAL(smjs_get_bookmark_folder_object(bookmark)); + + return JS_TRUE; + default: + INTERNAL("Invalid ID %d in bookmark_get_property().", + JSVAL_TO_INT(id)); + } + + return JS_FALSE; +} + +static JSBool +bookmark_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) +{ + struct bookmark *bookmark = JS_GetPrivate(ctx, obj); + + if (!bookmark) return JS_FALSE; + + if (!JSVAL_IS_INT(id)) + return JS_FALSE; + + switch (JSVAL_TO_INT(id)) { + case BOOKMARK_TITLE: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); + unsigned char *str = JS_GetStringBytes(jsstr); + + mem_free_set(&bookmark->title, stracpy(str)); + + return JS_TRUE; + } + case BOOKMARK_URL: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); + unsigned char *str = JS_GetStringBytes(jsstr); + + mem_free_set(&bookmark->url, stracpy(str)); + + return JS_TRUE; + } + default: + INTERNAL("Invalid ID %d in bookmark_set_property().", + JSVAL_TO_INT(id)); + } + + return JS_FALSE; +} + +static const JSClass bookmark_class = { + "bookmark", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, + bookmark_get_property, bookmark_set_property, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, bookmark_finalize, +}; + +static JSObject * +smjs_get_bookmark_object(struct bookmark *bookmark) +{ + JSObject *jsobj; + + jsobj = smjs_get_bookmark_generic_object(bookmark, + (JSClass *) &bookmark_class); + + if (jsobj + && JS_TRUE == JS_DefineProperties(smjs_ctx, jsobj, + (JSPropertySpec *) bookmark_props)) + return jsobj; + + return NULL; +} + + +/*** bookmark folder object ***/ + +static JSBool +bookmark_folder_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) +{ + struct bookmark *bookmark; + struct bookmark *folder = JS_GetPrivate(ctx, obj); + unsigned char *title; + + title = JS_GetStringBytes(JS_ValueToString(ctx, id)); + if (!title) { + *vp = JSVAL_NULL; + + return JS_TRUE; + } + + bookmark = get_bookmark_by_name(folder, title); + if (bookmark) object_lock(bookmark); + + *vp = OBJECT_TO_JSVAL(smjs_get_bookmark_object(bookmark)); + + return JS_TRUE; +} + +static const JSClass bookmark_folder_class = { + "bookmark_folder", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, + bookmark_folder_get_property, NULL, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, bookmark_finalize, +}; + +static JSObject * +smjs_get_bookmark_folder_object(struct bookmark *bookmark) +{ + return smjs_get_bookmark_generic_object(bookmark, + (JSClass *) &bookmark_folder_class); +} + +void +smjs_init_bookmarks_interface(void) +{ + jsval val; + struct JSObject *bookmarks_object; + + if (!smjs_ctx || !smjs_elinks_object) + return; + + bookmarks_object = smjs_get_bookmark_folder_object(NULL); + if (!bookmarks_object) return; + + val = OBJECT_TO_JSVAL(bookmarks_object); + + JS_SetProperty(smjs_ctx, smjs_elinks_object, "bookmarks", &val); +} diff --git a/src/scripting/smjs/bookmarks.h b/src/scripting/smjs/bookmarks.h new file mode 100644 index 00000000..bdf93852 --- /dev/null +++ b/src/scripting/smjs/bookmarks.h @@ -0,0 +1,8 @@ +#ifndef EL__SCRIPTING_SMJS_BOOKMARKS_H +#define EL__SCRIPTING_SMJS_BOOKMARKS_H + +#include "ecmascript/spidermonkey/util.h" + +void smjs_init_bookmarks_interface(void); + +#endif diff --git a/src/scripting/smjs/elinks_object.c b/src/scripting/smjs/elinks_object.c index 329479c1..00719584 100644 --- a/src/scripting/smjs/elinks_object.c +++ b/src/scripting/smjs/elinks_object.c @@ -9,6 +9,7 @@ #include "ecmascript/spidermonkey/util.h" #include "protocol/uri.h" #include "scripting/scripting.h" +#include "scripting/smjs/bookmarks.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" #include "scripting/smjs/global_object.h" @@ -109,6 +110,7 @@ smjs_init_elinks_object(void) { smjs_elinks_object = smjs_get_elinks_object(); + smjs_init_bookmarks_interface(); smjs_init_keybinding_interface(); }