1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-12 23:10:51 +00:00

[smjs local storage] spider monkey local storage

This commit is contained in:
nobody@earth.com 2021-02-22 23:27:19 +01:00
parent 7148c15150
commit a19b95f20c
11 changed files with 508 additions and 5 deletions

View File

@ -666,8 +666,10 @@ for package in mozjs-52; do
else
AC_MSG_CHECKING([for SpiderMonkey (mozjs-52) in pkg-config $package])
if $PKG_CONFIG $pkg_config_static --cflags --libs $package > /dev/null 2>&AS_MESSAGE_LOG_FD; then
SPIDERMONKEY_LIBS="$($PKG_CONFIG $pkg_config_static --libs $package)"
SPIDERMONKEY_CFLAGS="$($PKG_CONFIG $pkg_config_static --cflags $package)"
DB_LOCALSTORAGE_LIBS="$($PKG_CONFIG $pkg_config_static --libs sqlite3)"
SPIDERMONKEY_LIBS="$($PKG_CONFIG $pkg_config_static --libs $package) $DB_LOCALSTORAGE_LIBS"
DB_LOCALSTORAGE_CFLAGS="$($PKG_CONFIG $pkg_config_static --cflags sqlite3)"
SPIDERMONKEY_CFLAGS="$($PKG_CONFIG $pkg_config_static --cflags $package) $DB_LOCALSTORAGE_CFLAGS"
LIBS="$SPIDERMONKEY_LIBS $LIBS_X"
CFLAGS="$CFLAGS_X $SPIDERMONKEY_CFLAGS"
CPPFLAGS="$CPPFLAGS_X $SPIDERMONKEY_CFLAGS"

View File

@ -77,6 +77,10 @@ static INIT_LIST_OF(struct string_list_item, allowed_urls);
char *console_log_filename;
char *local_storage_filename;
int local_storage_ready;
static int
is_prefix(char *prefix, char *url, int dl)
{
@ -456,9 +460,15 @@ init_ecmascript_module(struct module *module)
{
read_url_list();
/* ecmascript console log */
if (elinks_home) {
console_log_filename = straconcat(elinks_home, "/console.log", NULL);
}
/* ecmascript local storage db location */
if (elinks_home) {
local_storage_filename = straconcat(elinks_home, "/elinks_ls.db", NULL);
}
}
static void
@ -466,6 +476,7 @@ done_ecmascript_module(struct module *module)
{
free_string_list(&allowed_urls);
mem_free_if(console_log_filename);
mem_free_if(local_storage_filename);
}
static struct module *ecmascript_modules[] = {

View File

@ -110,6 +110,10 @@ void ecmascript_set_timeout2(struct ecmascript_interpreter *interpreter, JS::Han
int get_ecmascript_enable(struct ecmascript_interpreter *interpreter);
extern char *console_log_filename;
extern char *local_storage_filename;
extern int local_storage_ready;
extern struct module ecmascript_module;
#endif

View File

@ -30,6 +30,7 @@
#include "ecmascript/spidermonkey/form.h"
#include "ecmascript/spidermonkey/heartbeat.h"
#include "ecmascript/spidermonkey/location.h"
#include "ecmascript/spidermonkey/localstorage.h"
#include "ecmascript/spidermonkey/navigator.h"
#include "ecmascript/spidermonkey/unibar.h"
#include "ecmascript/spidermonkey/window.h"
@ -214,7 +215,7 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
{
JSContext *ctx;
JSObject *console_obj, *document_obj, *forms_obj, *history_obj, *location_obj,
*statusbar_obj, *menubar_obj, *navigator_obj;
*statusbar_obj, *menubar_obj, *navigator_obj, *localstorage_obj;
static int initialized = 0;
@ -333,6 +334,16 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
goto release_and_fail;
}
localstorage_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
&localstorage_class, NULL, 0,
localstorage_props,
localstorage_funcs,
NULL, NULL);
if (!localstorage_obj) {
goto release_and_fail;
}
JS_SetCompartmentPrivate(js::GetContextCompartment(ctx), interpreter);
return ctx;

View File

@ -2,6 +2,6 @@ top_builddir=../../..
include $(top_builddir)/Makefile.config
INCLUDES += $(SPIDERMONKEY_CFLAGS)
OBJS = console.o document.o form.o heartbeat.o location.o navigator.o unibar.o window.o
OBJS = console.o document.o form.o heartbeat.o location.o localstorage.o localstorage-db.o navigator.o unibar.o window.o
include $(top_srcdir)/Makefile.lib

View File

@ -0,0 +1,207 @@
/* The SpiderMonkey localstorage database helper implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "src/ecmascript/ecmascript.h"
extern const int
db_prepare_structure(char *db_name)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char *sqlbuffer;
rc = sqlite3_open(db_name, &db);
if (rc)
{
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return(-1);
}
sqlite3_busy_timeout(db, 5000);
sqlbuffer=stracpy("CREATE TABLE storage (key TEXT, value TEXT);");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_step(stmt);
rc=sqlite3_finalize(stmt);
rc=sqlite3_close(db);
return(0);
}
extern const int
db_delete_from(char *db_name, char *key)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char *sqlbuffer;
int affected_rows = 0;
rc = sqlite3_open(db_name, &db);
if (rc)
{
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return(-1);
}
sqlite3_busy_timeout(db, 5000);
sqlbuffer=stracpy("DELETE FROM storage WHERE key = ?;");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
rc=sqlite3_step(stmt);
rc=sqlite3_finalize(stmt);
affected_rows=sqlite3_changes(db);
rc=sqlite3_close(db);
return(affected_rows);
}
extern const int
db_insert_into(char *db_name, char *key, char *value)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char *sqlbuffer;
int affected_rows = 0;
rc = sqlite3_open(db_name, &db);
if (rc) {
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return("");
}
sqlite3_busy_timeout(db, 5000);
sqlbuffer=stracpy("INSERT INTO storage (value,key) VALUES (?,?);");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_bind_text(stmt, 1, value, strlen(value), SQLITE_STATIC);
rc=sqlite3_bind_text(stmt, 2, key, strlen(key), SQLITE_STATIC);
rc=sqlite3_step(stmt);
rc=sqlite3_finalize(stmt);
affected_rows=sqlite3_changes(db);
rc=sqlite3_close(db);
return(affected_rows);
}
extern const int
db_update_set(char *db_name, char *key, char *value)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char sqlbuffer[8192];
char result[8192];
int affected_rows = 0;
rc = sqlite3_open(db_name, &db);
if (rc) {
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return("");
}
sqlite3_busy_timeout(db, 5000);
snprintf(sqlbuffer, 256, "UPDATE storage SET value = ? where key = ?;");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_bind_text(stmt, 1, value, strlen(value), SQLITE_STATIC);
rc=sqlite3_bind_text(stmt, 2, key, strlen(key), SQLITE_STATIC);
rc=sqlite3_step(stmt);
rc=sqlite3_finalize(stmt);
affected_rows=sqlite3_changes(db);
rc=sqlite3_close(db);
return(affected_rows);
}
extern const char *
db_query_by_value(char *db_name, char *value)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char *sqlbuffer;
char *result;
rc = sqlite3_open(db_name, &db);
if (rc) {
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return("");
}
rc = sqlite3_open(db_name, &db);
if (rc)
{
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return("");
}
sqlite3_busy_timeout(db, 2000);
sqlbuffer=stracpy("SELECT * FROM storage WHERE value like ?;");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_bind_text(stmt, 1, value, strlen(value) + 1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
if ((const char*) sqlite3_column_text(stmt,1)!= NULL) {
result=stracpy((const char *)sqlite3_column_text(stmt, 1));
//DBG("%s",result);
} else {
result=stracpy("");
}
}
rc=sqlite3_finalize(stmt);
rc=sqlite3_close(db);
return(result);
}
extern const char *
db_query_by_key(char *db_name, char *key)
{
sqlite3_stmt *stmt;
sqlite3 *db;
int rc;
char *sqlbuffer;
char *result;
rc = sqlite3_open(db_name, &db);
if (rc)
{
//DBG("Error opening localStorage database.");
rc=sqlite3_close(db);
return("");
}
sqlite3_busy_timeout(db, 2000);
sqlbuffer=stracpy("SELECT * FROM storage WHERE key like ?;");
rc=sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
rc=sqlite3_bind_text(stmt, 1, key, strlen(key) + 1, SQLITE_STATIC);
while (sqlite3_step(stmt) == SQLITE_ROW) {
if ((const char*) sqlite3_column_text(stmt,1)!= NULL) {
result=stracpy((const char *)sqlite3_column_text(stmt, 1));
//DBG("%s",result);
} else {
result=stracpy("");
}
}
rc=sqlite3_finalize(stmt);
rc=sqlite3_close(db);
return(result);
}

View File

@ -0,0 +1,16 @@
#ifndef EL__ECMASCRIPT_SPIDERMONKEY_LOCALSTORAGE_DB_H
#define EL__ECMASCRIPT_SPIDERMONKEY_LOCALSTORAGE_DB_H
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern const int db_prepare_structure(char *db_name);
extern const int db_delete_from(char *db_name, char *key);
extern const int db_insert_into(char *db_name, char *key, char *value);
extern const int db_update_set(char *db_name, char *key, char *value);
extern const char * db_query_by_key(char *db_name, char *key);
extern const char * db_qry_by_value(char *db_name, char *val);
#endif

View File

@ -0,0 +1,208 @@
/* The SpiderMonkey localstorage object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include "ecmascript/spidermonkey/util.h"
#include "bfu/dialog.h"
#include "cache/cache.h"
#include "config/home.h"
#include "cookies/cookies.h"
#include "dialogs/menu.h"
#include "dialogs/status.h"
#include "document/html/frames.h"
#include "document/document.h"
#include "document/forms.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/spidermonkey/form.h"
#include "ecmascript/spidermonkey/location.h"
#include "ecmascript/spidermonkey/localstorage.h"
#include "ecmascript/spidermonkey/localstorage-db.h"
#include "ecmascript/spidermonkey/document.h"
#include "ecmascript/spidermonkey/window.h"
#include "intl/gettext/libintl.h"
#include "main/select.h"
#include "osdep/newwin.h"
#include "osdep/sysname.h"
#include "protocol/http/http.h"
#include "protocol/uri.h"
#include "session/history.h"
#include "session/location.h"
#include "session/session.h"
#include "session/task.h"
#include "terminal/tab.h"
#include "terminal/terminal.h"
#include "util/conv.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
#include <time.h>
#include "document/renderer.h"
#include "document/refresh.h"
#include "terminal/screen.h"
/* IMPLEMENTS READ FROM STORAGE USING SQLITE DATABASE */
static unsigned char *
readFromStorage(unsigned char *key)
{
char * val = "";
val = (unsigned char *) malloc (32384);
if (local_storage_ready==0)
{
db_prepare_structure(local_storage_filename);
local_storage_ready=1;
}
val = db_query_by_key(local_storage_filename, key);
// DBG(log,"Read: %s %s %s",local_storage_filename, key, val);
return (val);
}
/* IMPLEMENTS SAVE TO STORAGE USING SQLITE DATABASE */
static void
saveToStorage(unsigned char *key, unsigned char *val)
{
if (local_storage_ready==0) {
db_prepare_structure(local_storage_filename);
local_storage_ready=1;
}
int rows_affected=0;
rows_affected=db_update_set(local_storage_filename, key, val);
if (rows_affected==0) {
rows_affected=db_insert_into(local_storage_filename, key, val);
}
// DBG(log, "UPD ROWS: %d KEY: %s VAL: %s",rows_affected,key,val);
}
static bool localstorage_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
JSClassOps localstorage_ops = {
JS_PropertyStub, nullptr,
localstorage_get_property, JS_StrictPropertyStub,
nullptr, nullptr, nullptr
};
/* Each @localstorage_class object must have a @window_class parent. */
const JSClass localstorage_class = {
"localStorage",
JSCLASS_HAS_PRIVATE,
&localstorage_ops
};
const JSPropertySpec localstorage_props[] = {
{ NULL }
};
///* @localstorage_class.getProperty */
static bool
localstorage_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
{
JSObject *parent_win; /* instance of @window_class */
return(true);
}
static bool localstorage_setitem(JSContext *ctx, unsigned int argc, JS::Value *vp);
static bool localstorage_getitem(JSContext *ctx, unsigned int argc, JS::Value *vp);
const spidermonkeyFunctionSpec localstorage_funcs[] = {
{ "setItem", localstorage_setitem, 2 },
{ "getItem", localstorage_getitem, 1 },
{ NULL }
};
static bool
localstorage_getitem(JSContext *ctx, unsigned int argc, JS::Value *vp)
{
//jsval val;
JSCompartment *comp = js::GetContextCompartment(ctx);
if (!comp)
{
return false;
}
struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp);
JS::CallArgs args = CallArgsFromVp(argc, vp);
unsigned char *key = JS_EncodeString(ctx, args[0].toString());
//DBG("localstorage get by key: %s\n", args);
if (argc != 1)
{
args.rval().setBoolean(false);
return(true);
}
unsigned char *val;
val = (unsigned char * ) malloc(32000);
val = readFromStorage(key);
//DBG("%s %s\n", key, val);
if (strlen(val)>0)
{
args.rval().setString(JS_NewStringCopyZ(ctx, val));
} else {
args.rval().setString(JS_NewStringCopyZ(ctx, ""));
}
return(true);
}
/* @localstorage_funcs{"setItem"} */
static bool
localstorage_setitem(JSContext *ctx, unsigned int argc, JS::Value *vp)
{
JSCompartment *comp = js::GetContextCompartment(ctx);
if (!comp)
{
return false;
}
struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp);
JS::CallArgs args = CallArgsFromVp(argc, vp);
if (argc != 2)
{
args.rval().setBoolean(false);
return(true);
}
unsigned char *key = JS_EncodeString(ctx, args[0].toString());
unsigned char *val = JS_EncodeString(ctx, args[1].toString());
saveToStorage(key,val);
//DBG("%s %s\n", key, val);
#ifdef CONFIG_LEDS
set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J');
#endif
args.rval().setBoolean(true);
return(true);
}

View File

@ -0,0 +1,12 @@
#ifndef EL__ECMASCRIPT_SPIDERMONKEY_LOCALSTORAGE_H
#define EL__ECMASCRIPT_SPIDERMONKEY_LOCALSTORAGE_H
#include "ecmascript/spidermonkey/util.h"
#include "ecmascript/spidermonkey/localstorage-db.h"
extern const JSClass localstorage_class;
extern const spidermonkeyFunctionSpec localstorage_funcs[];
extern const JSPropertySpec localstorage_props[];
#endif

View File

@ -1,3 +1,3 @@
#INCLUDES += $(SPIDERMONKEY_CFLAGS)
srcs += files('console.c', 'document.c', 'form.c', 'heartbeat.c', 'location.c', 'navigator.c', 'unibar.c', 'window.c')
srcs += files('console.c', 'document.c', 'form.c', 'heartbeat.c', 'location.c', 'localstorage.c', 'localstorage-db.c', 'navigator.c', 'unibar.c', 'window.c')

View File

@ -0,0 +1,32 @@
<html>
<body>
<script>
console.log("---= LOCAL STORAGE TEST =---");
console.log("|``````````````````````````|");
localStorage.setItem("foo","bar");
foo=localStorage.getItem("foo");
console.log(". foo: "+foo);
localStorage.setItem("foo","off");
foo=localStorage.getItem("foo");
console.log(". foo: "+foo);
console.log("|,,,,,,,,,,,,,,,,,,,,,,,,,,|");
console.log("---======================---");
</script>
<pre>
<font color="cyan">
You'll find the result of storage at sqlite database:
<font color="lightGreen">e.g. ~/.elinks/lc_storage.db</font>
Ensure You have the storage table in there:
<font color="yellow">CREATE TABLE storage (key text, value text);</font>
For the result of this code see:
<font color="lightGreen">e.g. ~/.elinks/console.log</font>
</font>
</pre>
</body>
</html>