1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-21 00:25:37 +00:00

Alternative experimental ECMAScript engine.

This commit is contained in:
witekfl 2006-01-10 19:17:29 +01:00 committed by
parent d2e346436a
commit d8592e4f99
27 changed files with 3408 additions and 89 deletions

View File

@ -142,6 +142,7 @@ CONFIG_RISCOS = @CONFIG_RISCOS@
CONFIG_RUBY = @CONFIG_RUBY@
CONFIG_SCANNER = @CONFIG_SCANNER@
CONFIG_SCRIPTING = @CONFIG_SCRIPTING@
CONFIG_SEE = @CONFIG_SEE@
CONFIG_SHA1 = @CONFIG_SHA1@
CONFIG_SMALL = @CONFIG_SMALL@
CONFIG_SMB = @CONFIG_SMB@

View File

@ -496,6 +496,55 @@ if test "$CONFIG_WIN32" = yes; then
EL_CONFIG_WIN32
fi
dnl ===================================================================
dnl Check for SEE (Simple Ecmascript Engine)
dnl ===================================================================
AC_ARG_WITH(see, [ --with-see enable Simple Ecmascript Engine (SEE) support],
[ if test "x$withval" != xno; then enable_see=yes; fi ])
# The following is probably bad, ugly and so on. Stolen from Guile's (1.4)
# SEE_FLAGS but I really don't want to require people to have Guile in order
# to compile CVS. Also, the macro seems to be really stupid regarding searching
# for Guile in $PATH etc. --pasky
AC_MSG_CHECKING([for SEE])
if test "$enable_see" = "yes"; then
AC_MSG_RESULT(yes);
## Based on the SEE_FLAGS macro.
if test -d "$withval"; then
SEE_PATH="$withval:$PATH"
else
SEE_PATH="$PATH"
fi
AC_PATH_PROG(SEE_CONFIG, libsee-config, no, $SEE_PATH)
## First, let's just see if we can find Guile at all.
if test "$SEE_CONFIG" != no; then
cf_result="yes";
SEE_LIBS="`$SEE_CONFIG --libs`"
SEE_CFLAGS="`$SEE_CONFIG --cppflags`"
LIBS="$SEE_LIBS $LIBS"
CPPFLAGS="$CPPFLAGS $SEE_CFLAGS"
EL_CONFIG(CONFIG_SEE, [SEE])
AC_SUBST(SEE_CFLAGS)
AC_SUBST(CONFIG_SEE)
disable_spidermonkey=yes
else
if test -n "$withval" && test "x$withval" != xno; then
AC_MSG_ERROR([SEE not found])
else
AC_MSG_WARN([SEE support disabled])
fi
fi
else
AC_MSG_RESULT(no);
fi
dnl ===================================================================
dnl Check for SpiderMonkey, optional even if installed.
dnl ===================================================================
@ -550,7 +599,7 @@ fi
AC_SUBST(CONFIG_SPIDERMONKEY)
EL_CONFIG_DEPENDS(CONFIG_ECMASCRIPT, [CONFIG_SPIDERMONKEY], [ECMAScript (JavaScript)])
EL_CONFIG_DEPENDS(CONFIG_ECMASCRIPT, [CONFIG_SEE CONFIG_SPIDERMONKEY], [ECMAScript (JavaScript)])
dnl ===================================================================

View File

@ -2,7 +2,10 @@ top_builddir=../..
include $(top_builddir)/Makefile.config
INCLUDES += $(SPIDERMONKEY_CFLAGS)
SUBDIRS = spidermonkey
OBJS = ecmascript.o spidermonkey.o
SUBDIRS-$(CONFIG_SPIDERMONKEY) += spidermonkey
SUBDIRS-$(CONFIG_SEE) += see
OBJS-$(CONFIG_SPIDERMONKEY) += spidermonkey.o
OBJS-$(CONFIG_SEE) += see.o
OBJS = ecmascript.o
include $(top_srcdir)/Makefile.lib

View File

@ -12,7 +12,6 @@
#include "document/document.h"
#include "document/view.h"
#include "ecmascript/ecmascript.h"
#include "ecmascript/spidermonkey.h"
#include "intl/gettext/libintl.h"
#include "main/module.h"
#include "protocol/uri.h"
@ -61,49 +60,6 @@ static struct option_info ecmascript_options[] = {
NULL_OPTION_INFO,
};
#define get_ecmascript_enable() get_opt_bool("ecmascript.enable")
static void
ecmascript_init(struct module *module)
{
spidermonkey_init();
}
static void
ecmascript_done(struct module *module)
{
spidermonkey_done();
}
struct ecmascript_interpreter *
ecmascript_get_interpreter(struct view_state *vs)
{
struct ecmascript_interpreter *interpreter;
assert(vs);
interpreter = mem_calloc(1, sizeof(*interpreter));
if (!interpreter)
return NULL;
interpreter->vs = vs;
init_list(interpreter->onload_snippets);
spidermonkey_get_interpreter(interpreter);
return interpreter;
}
void
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
{
assert(interpreter);
spidermonkey_put_interpreter(interpreter);
free_string_list(&interpreter->onload_snippets);
mem_free(interpreter);
}
void
ecmascript_reset_state(struct view_state *vs)
{
@ -124,40 +80,6 @@ ecmascript_reset_state(struct view_state *vs)
vs->ecmascript_fragile = 1;
}
void
ecmascript_eval(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return;
assert(interpreter);
spidermonkey_eval(interpreter, code);
}
unsigned char *
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return NULL;
assert(interpreter);
return spidermonkey_eval_stringback(interpreter, code);
}
int
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return -1;
assert(interpreter);
return spidermonkey_eval_boolback(interpreter, code);
}
void
ecmascript_protocol_handler(struct session *ses, struct uri *uri)
{
@ -197,6 +119,20 @@ ecmascript_protocol_handler(struct session *ses, struct uri *uri)
}
void
ecmascript_timeout_dialog(struct terminal *term, int max_exec_time)
{
info_box(term, MSGBOX_FREE_TEXT,
N_("JavaScript Emergency"), ALIGN_LEFT,
msg_text(term,
N_("A script embedded in the current document was running\n"
"for more than %d seconds. This probably means there is\n"
"a bug in the script and it could have halted the whole\n"
"ELinks, so the script execution was interrupted."),
max_exec_time));
}
struct module ecmascript_module = struct_module(
/* name: */ N_("ECMAScript"),
/* options: */ ecmascript_options,

View File

@ -9,9 +9,12 @@
#include "util/time.h"
struct string;
struct terminal;
struct uri;
struct view_state;
#define get_ecmascript_enable() get_opt_bool("ecmascript.enable")
struct ecmascript_interpreter {
struct view_state *vs;
void *backend_data;
@ -63,6 +66,11 @@ int ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter, struct
* follows a link with this synstax. */
void ecmascript_protocol_handler(struct session *ses, struct uri *uri);
void ecmascript_init(struct module *);
void ecmascript_done(struct module *);
void ecmascript_timeout_dialog(struct terminal *term, int max_exec_time);
extern struct module ecmascript_module;
#endif

243
src/ecmascript/see.c Normal file
View File

@ -0,0 +1,243 @@
/* The SEE ECMAScript backend. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see.h"
#include "ecmascript/see/document.h"
#include "ecmascript/see/form.h"
#include "ecmascript/see/input.h"
#include "ecmascript/see/location.h"
#include "ecmascript/see/navigator.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/unibar.h"
#include "ecmascript/see/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/string.h"
#include "viewer/text/draw.h"
#include "viewer/text/form.h"
#include "viewer/text/link.h"
#include "viewer/text/vs.h"
/*** Global methods */
/* TODO? Are there any which need to be implemented? */
/*** The ELinks interface */
void
ecmascript_init(struct module *module)
{
see_init();
}
void
ecmascript_done(struct module *module)
{
see_done();
}
struct ecmascript_interpreter *
ecmascript_get_interpreter(struct view_state *vs)
{
struct ecmascript_interpreter *interpreter;
assert(vs);
interpreter = mem_calloc(1, sizeof(*interpreter));
if (!interpreter)
return NULL;
interpreter->vs = vs;
init_list(interpreter->onload_snippets);
see_get_interpreter(interpreter);
return interpreter;
}
void
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
{
assert(interpreter);
see_put_interpreter(interpreter);
free_string_list(&interpreter->onload_snippets);
mem_free(interpreter);
}
void
ecmascript_eval(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return;
assert(interpreter);
see_eval(interpreter, code);
}
unsigned char *
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return NULL;
assert(interpreter);
return see_eval_stringback(interpreter, code);
}
int
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return -1;
assert(interpreter);
return see_eval_boolback(interpreter, code);
}
void
see_init(void)
{
init_intern_strings();
}
void
see_done(void)
{
}
void *
see_get_interpreter(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = SEE_NEW(NULL, struct global_object);
struct SEE_interpreter *interp = &g->interp;
interpreter->backend_data = g;
g->max_exec_time = get_opt_int("ecmascript.max_exec_time");
g->exec_start = time(NULL);
SEE_interpreter_init(interp);
init_js_window_object(interpreter);
init_js_menubar_object(interpreter);
init_js_statusbar_object(interpreter);
init_js_navigator_object(interpreter);
init_js_history_object(interpreter);
init_js_location_object(interpreter);
init_js_document_object(interpreter);
init_js_forms_object(interpreter);
return interp;
}
void
see_put_interpreter(struct ecmascript_interpreter *interpreter)
{
interpreter->backend_data = NULL;
}
void
see_eval(struct ecmascript_interpreter *interpreter,
struct string *code)
{
struct SEE_interpreter *interp = interpreter->backend_data;
struct global_object *g = (struct global_object *)interp;
struct SEE_input *input = SEE_input_elinks(interp, code->source);
SEE_try_context_t try_ctxt;
struct SEE_value result;
struct SEE_value v;
g->exec_start = time(NULL);
SEE_TRY(interp, try_ctxt) {
SEE_Global_eval(interp, input, &result);
}
SEE_INPUT_CLOSE(input);
SEE_CAUGHT(try_ctxt);
}
unsigned char *
see_eval_stringback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
struct SEE_interpreter *interp = interpreter->backend_data;
struct global_object *g = (struct global_object *)interp;
struct SEE_input *input = SEE_input_elinks(interp, code->source);
SEE_try_context_t try_ctxt;
struct SEE_value result;
unsigned char *string = NULL;
g->exec_start = time(NULL);
SEE_TRY(interp, try_ctxt) {
SEE_Global_eval(interp, input, &result);
if (SEE_VALUE_GET_TYPE(&result) != SEE_NULL)
string = SEE_value_to_unsigned_char(interp, &result);
}
SEE_INPUT_CLOSE(input);
if (SEE_CAUGHT(try_ctxt)) {
return NULL;
}
return string;
}
int
see_eval_boolback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
struct SEE_interpreter *interp = interpreter->backend_data;
struct global_object *g = (struct global_object *)interp;
struct SEE_input *input = SEE_input_elinks(interp, code->source);
SEE_try_context_t try_ctxt;
struct SEE_value result;
SEE_int32_t res = 0;
g->exec_start = time(NULL);
SEE_TRY(interp, try_ctxt) {
SEE_Global_eval(interp, input, &result);
/* history.back() returns SEE_NULL */
if (SEE_VALUE_GET_TYPE(&result) == SEE_NULL)
res = 0;
else
res = SEE_ToInt32(interp, &result);
}
SEE_INPUT_CLOSE(input);
if (SEE_CAUGHT(try_ctxt)) {
return -1;
}
return res;
}

17
src/ecmascript/see.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef EL__ECMASCRIPT_SEE_H
#define EL__ECMASCRIPT_SEE_H
struct ecmascript_interpreter;
struct string;
void see_init();
void see_done();
void *see_get_interpreter(struct ecmascript_interpreter *interpreter);
void see_put_interpreter(struct ecmascript_interpreter *interpreter);
void see_eval(struct ecmascript_interpreter *interpreter, struct string *code);
unsigned char *see_eval_stringback(struct ecmascript_interpreter *interpreter, struct string *code);
int see_eval_boolback(struct ecmascript_interpreter *interpreter, struct string *code);
#endif

BIN
src/ecmascript/see.o Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
top_builddir=../../..
include $(top_builddir)/Makefile.config
OBJS = document.o form.o input.o location.o navigator.o strings.o unibar.o window.o
include $(top_srcdir)/Makefile.lib

View File

@ -0,0 +1,257 @@
/* The SEE document object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/document.h"
#include "ecmascript/see/form.h"
#include "ecmascript/see/input.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/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"
static void document_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void document_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static int document_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int document_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void js_document_write(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
void location_goto(struct document_view *, unsigned char *);
struct SEE_objectclass js_document_object_class = {
NULL,
document_get,
document_put,
document_canput,
document_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
static void
document_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct js_window_object *win = g->win;
struct view_state *vs = win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_document_object *doc = (struct js_document_object *)o;
struct session *ses = doc_view->session;
struct SEE_string *str;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_cookie) {
#ifdef CONFIG_COOKIES
struct string *cookies = send_cookies(vs->uri);
if (cookies) {
static unsigned char cookiestr[1024];
strncpy(cookiestr, cookies->source, 1024);
done_string(cookies);
str = string_to_SEE_string(interp, cookiestr);
} else {
str = string_to_SEE_string(interp, "");
}
SEE_SET_STRING(res, str);
#endif
} else if (p == s_title) {
str = string_to_SEE_string(interp, document->title);
SEE_SET_STRING(res, str);
} else if (p == s_url) {
string = get_uri_string(document->uri, URI_ORIGINAL);
str = string_to_SEE_string(interp, string);
mem_free_if(string);
SEE_SET_STRING(res, str);
} else if (p == s_location) {
SEE_OBJECT_GET(interp, interp->Global, s_location, res);
} else if (p == s_referrer) {
switch (get_opt_int("protocol.http.referer.policy")) {
case REFERER_NONE:
SEE_SET_UNDEFINED(res);
break;
case REFERER_FAKE:
str = string_to_SEE_string(interp,
get_opt_str("protocol.http.referer.fake"));
SEE_SET_STRING(res, str);
break;
case REFERER_TRUE:
if (ses->referrer) {
string = get_uri_string(ses->referrer, URI_HTTP_REFERRER);
str = string_to_SEE_string(interp, string);
mem_free_if(string);
SEE_SET_STRING(res, str);
}
break;
case REFERER_SAME_URL:
string = get_uri_string(document->uri, URI_HTTP_REFERRER);
str = string_to_SEE_string(interp, string);
mem_free_if(string);
SEE_SET_STRING(res, str);
break;
}
} else if (p == s_forms) {
SEE_SET_OBJECT(res, doc->forms);
} else {
struct form *form;
unsigned char *string = SEE_string_to_unsigned_char(p);
struct form_view *form_view;
struct js_form *form_object;
foreach (form, document->forms) {
if (!form->name || strcasecmp(string, form->name))
continue;
mem_free_if(string);
form_view = find_form_view(doc_view, form);
form_object = js_get_form_object(interp, doc, form_view);
SEE_SET_OBJECT(res, (struct SEE_object *)form_object);
break;
}
}
}
static void
document_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_document_object *doc = (struct js_document_object *)o;
struct SEE_value res;
unsigned char *string;
checktime(interp);
if (p == s_forms) {
SEE_ToObject(interp, val, &res);
doc->forms = res.u.object;
} else if (p == s_title) {
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&document->title, string);
print_screen_status(doc_view->session);
} else if (p == s_location || p == s_url) {
/* According to the specs this should be readonly but some
* broken sites still assign to it (i.e.
* http://www.e-handelsfonden.dk/validering.asp?URL=www.polyteknisk.dk).
* So emulate window.location. */
string = SEE_value_to_unsigned_char(interp, val);
location_goto(doc_view, string);
mem_free_if(string);
} else if (p == s_cookie) {
#ifdef CONFIG_COOKIES
string = SEE_value_to_unsigned_char(interp, val);
set_cookie(vs->uri, string);
mem_free_if(string);
#endif
}
}
static void
js_document_write(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
#ifdef CONFIG_LEDS
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
/* XXX: I don't know about you, but I have *ENOUGH* of those 'Undefined
* function' errors, I want to see just the useful ones. So just
* lighting a led and going away, no muss, no fuss. --pasky */
/* TODO: Perhaps we can introduce ecmascript.error_report_unsupported
* -> "Show information about the document using some valid,
* nevertheless unsupported methods/properties." --pasky too */
set_led_value(vs->doc_view->session->status.ecmascript_led, 'J');
#endif
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
}
static int
document_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_location || p == s_url || p == s_cookie)
return 1;
return 0;
}
static int
document_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
void
init_js_document_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct js_document_object *doc = SEE_NEW(interp,
struct js_document_object);
doc->object.objectclass = &js_document_object_class;
doc->object.objectclass->Class = s_document;
doc->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)doc);
SEE_OBJECT_PUT(interp, interp->Global, s_document, &v, 0);
doc->write = SEE_cfunction_make(interp, js_document_write, s_write, 1);
}

View File

@ -0,0 +1,14 @@
#ifndef EL__ECMASCRIPT_SEE_DOCUMENT_H
#define EL__ECMASCRIPT_SEE_DOCUMENT_H
struct ecmascript_interpreter;
struct js_document_object {
struct SEE_object object;
struct SEE_object *write;
struct SEE_object *forms;
};
void init_js_document_object(struct ecmascript_interpreter *);
#endif

964
src/ecmascript/see/form.c Normal file
View File

@ -0,0 +1,964 @@
/* The SEE form object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/document.h"
#include "ecmascript/see/form.h"
#include "ecmascript/see/input.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/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"
static void input_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void input_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static void js_input_blur(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_input_click(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_input_focus(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_input_select(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static int input_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int input_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static struct js_input *js_get_input_object(struct SEE_interpreter *, struct js_form *, struct form_state *);
static struct js_input *js_get_form_control_object(struct SEE_interpreter *, struct js_form *, enum form_type, struct form_state *);
static void js_form_elems_item(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_form_elems_namedItem(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void form_elems_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static int form_elems_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void js_forms_item(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_forms_namedItem(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void forms_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static int forms_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void form_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void form_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static int form_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int form_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void js_form_reset(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_form_submit(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
struct SEE_objectclass js_input_object_class = {
NULL,
input_get,
input_put,
input_canput,
input_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct SEE_objectclass js_form_elems_class = {
NULL,
form_elems_get,
SEE_no_put,
SEE_no_canput,
form_elems_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct SEE_objectclass js_forms_object_class = {
NULL,
forms_get,
SEE_no_put,
SEE_no_canput,
forms_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct SEE_objectclass js_form_class = {
NULL,
form_get,
form_put,
form_canput,
form_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct js_input {
struct SEE_object object;
struct js_form *parent;
struct form_state *fs;
struct SEE_object *blur;
struct SEE_object *click;
struct SEE_object *focus;
struct SEE_object *select;
};
struct js_forms_object {
struct SEE_object object;
struct js_document_object *parent;
struct SEE_object *item;
struct SEE_object *namedItem;
};
struct js_form_elems {
struct SEE_object object;
struct js_form *parent;
struct SEE_object *item;
struct SEE_object *namedItem;
};
static void
input_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_input *input = (struct js_input *)o;
struct js_form *parent = input->parent;
struct form_state *fs = input->fs;
struct form_control *fc = find_form_control(document, fs);
int linknum;
struct link *link = NULL;
struct SEE_string *str;
assert(fc);
assert(fc->form && fs);
checktime(interp);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum >= 0) link = &document->links[linknum];
SEE_SET_UNDEFINED(res);
if (p == s_accessKey) {
struct string keystr;
if (!link)
return;
init_string(&keystr);
add_accesskey_to_string(&keystr, link->accesskey);
str = string_to_SEE_string(interp, keystr.source);
SEE_SET_STRING(res, str);
done_string(&keystr);
} else if (p == s_alt) {
str = string_to_SEE_string(interp, fc->alt);
SEE_SET_STRING(res, str);
} else if (p == s_checked) {
SEE_SET_BOOLEAN(res, fs->state);
} else if (p == s_defaultChecked) {
SEE_SET_BOOLEAN(res, fc->default_state);
} else if (p == s_defaultValue) {
str = string_to_SEE_string(interp, fc->default_value);
SEE_SET_STRING(res, str);
} else if (p == s_disabled) {
/* FIXME: <input readonly disabled> --pasky */
SEE_SET_BOOLEAN(res, fc->mode == FORM_MODE_DISABLED);
} else if (p == s_form) {
SEE_SET_OBJECT(res, (struct SEE_object *)parent);
} else if (p == s_maxLength) {
SEE_SET_NUMBER(res, fc->maxlength);
} else if (p == s_name) {
str = string_to_SEE_string(interp, fc->name);
SEE_SET_STRING(res, str);
} else if (p == s_readonly) {
/* FIXME: <input readonly disabled> --pasky */
SEE_SET_BOOLEAN(res, fc->mode == FORM_MODE_READONLY);
} else if (p == s_size) {
SEE_SET_NUMBER(res, fc->size);
} else if (p == s_src) {
if (link && link->where_img) {
str = string_to_SEE_string(interp, link->where_img);
SEE_SET_STRING(res, str);
}
} else if (p == s_tabindex) {
if (link) {
/* FIXME: This is WRONG. --pasky */
SEE_SET_NUMBER(res, link->number);
}
} else if (p == s_type) {
switch (fc->type) {
case FC_TEXT: str = s_text; break;
case FC_PASSWORD: str = s_password; break;
case FC_FILE: str = s_file; break;
case FC_CHECKBOX: str = s_checkbox; break;
case FC_RADIO: str = s_radio; break;
case FC_SUBMIT: str = s_submit; break;
case FC_IMAGE: str = s_image; break;
case FC_RESET: str = s_reset; break;
case FC_BUTTON: str = s_button; break;
case FC_HIDDEN: str = s_hidden; break;
default: str = NULL;
}
if (str) {
SEE_SET_STRING(res, str);
}
} else if (p == s_value) {
str = string_to_SEE_string(interp, fs->value);
SEE_SET_STRING(res, str);
}
}
static void
input_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_input *input = (struct js_input *)o;
struct form_state *fs = input->fs;
struct form_control *fc = find_form_control(document, fs);
int linknum;
struct link *link = NULL;
unsigned char *string = NULL;
assert(fc);
assert(fc->form && fs);
checktime(interp);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum >= 0) link = &document->links[linknum];
if (p == s_accessKey) {
if (link) {
string = SEE_value_to_unsigned_char(interp, val);
if (!string)
return;
link->accesskey = accesskey_string_to_unicode(string);
mem_free(string);
}
} else if (p == s_alt) {
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&fc->alt, string);
} else if (p == s_checked) {
if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO)
return;
fs->state = SEE_ToUint32(interp, val);
} else if (p == s_disabled) {
/* FIXME: <input readonly disabled> --pasky */
SEE_uint32_t boo = SEE_ToUint32(interp, val);
fc->mode = (boo ? FORM_MODE_DISABLED
: (fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY
: FORM_MODE_NORMAL));
} else if (p == s_maxLength) {
string = SEE_value_to_unsigned_char(interp, val);
if (!string)
return;
fc->maxlength = atol(string);
mem_free(string);
} else if (p == s_name) {
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&fc->name, string);
} else if (p == s_readonly) {
SEE_uint32_t boo = SEE_ToUint32(interp, val);
fc->mode = (boo ? FORM_MODE_READONLY
: fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED
: FORM_MODE_NORMAL);
} else if (p == s_src) {
if (link) {
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&link->where_img, string);
}
} else if (p == s_value) {
if (fc->type == FC_FILE)
return;
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&fs->value, string);
if (fc->type == FC_TEXT || fc->type == FC_PASSWORD)
fs->state = strlen(fs->value);
}
}
static void
js_input_blur(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
/* We are a text-mode browser and there *always* has to be something
* selected. So we do nothing for now. (That was easy.) */
}
static void
js_input_click(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct session *ses = doc_view->session;
struct js_input *input = (struct js_input *)thisobj;
struct form_state *fs = input->fs;
struct form_control *fc;
int linknum;
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
assert(fs);
fc = find_form_control(document, fs);
assert(fc);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum < 0)
return;
/* Restore old current_link afterwards? */
jump_to_link_number(ses, doc_view, linknum);
if (enter(ses, doc_view, 0) == FRAME_EVENT_REFRESH)
refresh_view(ses, doc_view, 0);
else
print_screen_status(ses);
}
static void
js_input_focus(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct session *ses = doc_view->session;
struct js_input *input = (struct js_input *)thisobj;
struct form_state *fs = input->fs;
struct form_control *fc;
int linknum;
checktime(interp);
assert(fs);
fc = find_form_control(document, fs);
assert(fc);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum < 0)
return;
jump_to_link_number(ses, doc_view, linknum);
}
static void
js_input_select(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
checktime(interp);
/* We support no text selecting yet. So we do nothing for now.
* (That was easy, too.) */
}
static int
input_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
static int
input_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
/* all unknown properties return UNDEFINED value */
checktime(interp);
return 1;
}
static struct js_input *
js_get_input_object(struct SEE_interpreter *interp, struct js_form *jsform,
struct form_state *fs)
{
struct js_input *jsinput;
checktime(interp);
if (fs->ecmascript_obj)
return fs->ecmascript_obj;
/* jsform ('form') is input's parent */
/* FIXME: That is NOT correct since the real containing element
* should be its parent, but gimme DOM first. --pasky */
jsinput = SEE_NEW(interp, struct js_input);
jsinput->object.objectclass = &js_input_object_class;
jsinput->object.objectclass->Class = s_input;
jsinput->object.Prototype = NULL;
jsinput->blur = SEE_cfunction_make(interp, js_input_blur, s_blur, 0);
jsinput->click = SEE_cfunction_make(interp, js_input_click, s_click, 0);
jsinput->focus = SEE_cfunction_make(interp, js_input_focus, s_focus, 0);
jsinput->select = SEE_cfunction_make(interp, js_input_select, s_select, 0);
jsinput->fs = fs;
jsinput->parent = jsform;
fs->ecmascript_obj = jsinput;
return jsinput;
}
static struct js_input *
js_get_form_control_object(struct SEE_interpreter *interp, struct js_form *jsform,
enum form_type type, struct form_state *fs)
{
checktime(interp);
switch (type) {
case FC_TEXT:
case FC_PASSWORD:
case FC_FILE:
case FC_CHECKBOX:
case FC_RADIO:
case FC_SUBMIT:
case FC_IMAGE:
case FC_RESET:
case FC_BUTTON:
case FC_HIDDEN:
return js_get_input_object(interp, jsform, fs);
case FC_TEXTAREA:
case FC_SELECT:
/* TODO */
return NULL;
default:
INTERNAL("Weird fc->type %d", type);
return NULL;
}
}
static void
js_form_elems_item(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_form_elems *jsfe = (struct js_form_elems *)thisobj;
struct js_form *parent_form = jsfe->parent;
struct form_view *fv = parent_form->fv;
struct form *form = find_form_by_form_view(document, fv);
struct form_control *fc;
unsigned char *string;
int counter = -1;
int index;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
string = SEE_value_to_unsigned_char(interp, argv[0]);
if (!string)
return;
index = atol(string);
mem_free(string);
foreach (fc, form->items) {
counter++;
if (counter == index) {
struct js_input *fcobj = js_get_form_control_object(interp, parent_form, fc->type, find_form_state(doc_view, fc));
if (fcobj) {
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
}
break;
}
}
}
static void
js_form_elems_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_form_elems *jsfe = (struct js_form_elems *)thisobj;
struct js_form *parent_form = jsfe->parent;
struct form_view *fv = parent_form->fv;
struct form *form = find_form_by_form_view(document, fv);
struct form_control *fc;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
string = SEE_value_to_unsigned_char(interp, argv[0]);
if (!string)
return;
foreach (fc, form->items) {
if (fc->name && !strcasecmp(string, fc->name)) {
struct js_input *fcobj = js_get_form_control_object(interp, parent_form, fc->type, find_form_state(doc_view, fc));
if (fcobj) {
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
}
break;
}
}
mem_free(string);
}
static void
form_elems_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_form_elems *jsfe = (struct js_form_elems *)o;
struct js_form *parent_form = jsfe->parent;
struct form_view *fv = parent_form->fv;
struct form *form = find_form_by_form_view(document, fv);
checktime(interp);
if (p == s_length) {
SEE_number_t length = list_size(&form->items);
SEE_SET_NUMBER(res, length);
} else {
unsigned char *string = SEE_string_to_unsigned_char(p);
struct SEE_value argv;
if (!string) {
SEE_SET_UNDEFINED(res);
return;
}
SEE_SET_STRING(&argv, p);
if (string[0] >= '0' && string[1] <= '9') {
js_form_elems_item(interp, o, NULL, 1,
(struct SEE_value **)&argv, res);
} else {
js_form_elems_namedItem(interp, o, NULL, 1,
(struct SEE_value **)&argv, res);
}
mem_free(string);
}
}
static int
form_elems_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
static void
js_forms_item(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct js_forms_object *fo = (struct js_forms_object *)thisobj;
struct js_document_object *doc = fo->parent;
struct form_view *fv;
unsigned char *string;
int counter = -1;
int index;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
string = SEE_value_to_unsigned_char(interp, argv[0]);
if (!string)
return;
index = atol(string);
mem_free(string);
foreach (fv, vs->forms) {
counter++;
if (counter == index) {
struct js_form *obj = js_get_form_object(interp, doc, fv);
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
break;
}
}
}
static void
js_forms_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
struct js_forms_object *fo = (struct js_forms_object *)thisobj;
struct js_document_object *doc = fo->parent;
struct form *form;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
string = SEE_value_to_unsigned_char(interp, argv[0]);
if (!string)
return;
foreach (form, document->forms) {
if (form->name && !strcasecmp(string, form->name)) {
struct form_view *fv = find_form_view(doc_view, form);
struct js_form *obj = js_get_form_object(interp,
doc, fv);
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
break;
}
}
mem_free(string);
}
static void
forms_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct document *document = doc_view->document;
checktime(interp);
if (p == s_length) {
SEE_number_t length = list_size(&document->forms);
SEE_SET_NUMBER(res, length);
} else {
unsigned char *string = SEE_string_to_unsigned_char(p);
struct SEE_value argv;
if (!string) {
SEE_SET_UNDEFINED(res);
return;
}
SEE_SET_STRING(&argv, p);
if (string[0] >= '0' && string[1] <= '9') {
js_forms_item(interp, o, NULL, 1,
(struct SEE_value **)&argv, res);
} else {
js_forms_namedItem(interp, o, NULL, 1,
(struct SEE_value **)&argv, res);
}
mem_free(string);
}
}
static int
forms_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
static void
form_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct js_form *js_form = (struct js_form *)o;
struct form_view *fv = js_form->fv;
struct form *form = find_form_by_form_view(doc_view->document, fv);
struct SEE_string *str;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_action) {
str = string_to_SEE_string(interp, form->action);
SEE_SET_STRING(res, str);
} else if (p == s_encoding) {
switch (form->method) {
case FORM_METHOD_GET:
case FORM_METHOD_POST:
/* "application/x-www-form-urlencoded" */
SEE_SET_STRING(res, s_application_);
break;
case FORM_METHOD_POST_MP:
/* "multipart/form-data" */
SEE_SET_STRING(res, s_multipart_);
break;
case FORM_METHOD_POST_TEXT_PLAIN:
/* "text/plain") */
SEE_SET_STRING(res, s_textplain);
break;
}
} else if (p == s_length) {
SEE_number_t num = list_size(&form->items);
SEE_SET_NUMBER(res, num);
} else if (p == s_method) {
switch (form->method) {
case FORM_METHOD_GET:
SEE_SET_STRING(res, s_GET);
break;
case FORM_METHOD_POST:
case FORM_METHOD_POST_MP:
case FORM_METHOD_POST_TEXT_PLAIN:
SEE_SET_STRING(res, s_POST);
break;
}
} else if (p == s_name) {
str = string_to_SEE_string(interp, form->name);
SEE_SET_STRING(res, str);
} else if (p == s_target) {
str = string_to_SEE_string(interp, form->target);
SEE_SET_STRING(res, str);
} else if (p == s_elements) {
struct js_form_elems *jsfe = SEE_NEW(interp, struct js_form_elems);
jsfe->object.objectclass = &js_form_elems_class;
jsfe->object.objectclass->Class = s_elements;
jsfe->object.Prototype = NULL;
jsfe->parent = js_form;
jsfe->item = SEE_cfunction_make(interp, js_form_elems_item, s_item, 1);
jsfe->namedItem = SEE_cfunction_make(interp, js_form_elems_namedItem, s_namedItem, 1);
SEE_SET_OBJECT(res, (struct SEE_object *)jsfe);
} else if (p == s_submit) {
SEE_SET_OBJECT(res, js_form->submit);
} else if (p == s_reset) {
SEE_SET_OBJECT(res, js_form->reset);
} else {
unsigned char *string = SEE_string_to_unsigned_char(p);
struct form_control *fc;
if (!string)
return;
foreach(fc, form->items) {
struct js_input *fcobj = NULL;
if (!fc->name || strcasecmp(string, fc->name))
continue;
fcobj = js_get_form_control_object(interp, js_form, fc->type, find_form_state(doc_view, fc));
if (fcobj) {
SEE_SET_OBJECT(res, (struct SEE_object *)fcobj);
}
break;
}
mem_free(string);
}
}
static void
form_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct js_form *js_form = (struct js_form *)o;
struct form_view *fv = js_form->fv;
struct form *form = find_form_by_form_view(doc_view->document, fv);
unsigned char *string = SEE_value_to_unsigned_char(interp, val);
checktime(interp);
if (!string)
return;
if (p == s_action) {
mem_free_set(&form->action, string);
} else if (p == s_encoding) {
if (!strcasecmp(string, "application/x-www-form-urlencoded")) {
form->method = form->method == FORM_METHOD_GET ? FORM_METHOD_GET
: FORM_METHOD_POST;
} else if (!strcasecmp(string, "multipart/form-data")) {
form->method = FORM_METHOD_POST_MP;
} else if (!strcasecmp(string, "text/plain")) {
form->method = FORM_METHOD_POST_TEXT_PLAIN;
}
mem_free(string);
} else if (p == s_method) {
if (!strcasecmp(string, "GET")) {
form->method = FORM_METHOD_GET;
} else if (!strcasecmp(string, "POST")) {
form->method = FORM_METHOD_POST;
}
mem_free(string);
} else if (p == s_name) {
mem_free_set(&form->name, string);
} else if (p == s_target) {
mem_free_set(&form->target, string);
}
}
static int
form_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
static int
form_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
static void
js_form_reset(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct js_form *js_form = (struct js_form *)thisobj;
struct form_view *fv = js_form->fv;
struct form *form = find_form_by_form_view(doc_view->document, fv);
assert(form);
checktime(interp);
do_reset_form(doc_view, form);
draw_forms(doc_view->session->tab->term, doc_view);
SEE_SET_BOOLEAN(res, 0);
}
static void
js_form_submit(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
struct js_form *js_form = (struct js_form *)thisobj;
struct form_view *fv = js_form->fv;
struct form *form = find_form_by_form_view(doc_view->document, fv);
assert(form);
checktime(interp);
submit_given_form(ses, doc_view, form);
SEE_SET_BOOLEAN(res, 0);
}
struct js_form *js_get_form_object(struct SEE_interpreter *interp,
struct js_document_object *doc, struct form_view *fv)
{
struct js_form *js_form;
checktime(interp);
if (fv->ecmascript_obj)
return fv->ecmascript_obj;
/* jsdoc ('document') is fv's parent */
/* FIXME: That is NOT correct since the real containing element
* should be its parent, but gimme DOM first. --pasky */
js_form = SEE_NEW(interp, struct js_form);
js_form->object.objectclass = &js_form_class;
js_form->object.objectclass->Class = s_form;
js_form->object.Prototype = NULL; /* TODO: use prototype for form */
js_form->parent = doc;
js_form->reset = SEE_cfunction_make(interp, js_form_reset, s_reset, 0);
js_form->submit = SEE_cfunction_make(interp, js_form_submit, s_submit, 0);
js_form->fv = fv;
fv->ecmascript_obj = js_form;
return js_form;
}
void
init_js_forms_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v, document;
struct js_forms_object *forms = SEE_NEW(interp,
struct js_forms_object);
forms->object.objectclass = &js_forms_object_class;
forms->object.objectclass->Class = s_forms;
forms->object.Prototype = NULL;
SEE_OBJECT_GET(interp, interp->Global, s_document, &document);
SEE_SET_OBJECT(&v, (struct SEE_object *)forms);
SEE_OBJECT_PUT(interp, document.u.object, s_forms, &v, 0);
forms->item = SEE_cfunction_make(interp, js_forms_item, s_item, 1);
forms->namedItem = SEE_cfunction_make(interp, js_forms_namedItem,
s_namedItem, 1);
forms->parent = (struct js_document_object *)document.u.object;
}

19
src/ecmascript/see/form.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef EL__ECMASCRIPT_SEE_FORM_H
#define EL__ECMASCRIPT_SEE_FORM_H
struct js_document_object;
struct ecmascript_interpreter;
struct form_view;
struct js_form {
struct SEE_object object;
struct js_document_object *parent;
struct form_view *fv;
struct SEE_object *reset;
struct SEE_object *submit;
};
struct js_form *js_get_form_object(struct SEE_interpreter *, struct js_document_object*, struct form_view *);
void init_js_forms_object(struct ecmascript_interpreter *);
#endif

100
src/ecmascript/see/input.c Normal file
View File

@ -0,0 +1,100 @@
/* Input for SEE */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <see/see.h>
#include <string.h>
#include "ecmascript/see/input.h"
#include "util/memory.h"
static SEE_unicode_t input_elinks_next(struct SEE_input *);
static void input_elinks_close(struct SEE_input *);
static struct SEE_inputclass input_elinks_class = {
input_elinks_next,
input_elinks_close
};
struct input_elinks {
struct SEE_input inp;
unsigned char *s;
};
static SEE_unicode_t
input_elinks_next(struct SEE_input *inp)
{
struct input_elinks *input = (struct input_elinks*)inp;
SEE_unicode_t next;
next = input->inp.lookahead;
if (*input->s == '\0') {
input->inp.eof = 1;
} else {
input->inp.lookahead = *input->s++;
input->inp.eof = 0;
}
return next;
}
static void
input_elinks_close(struct SEE_input *inp)
{
/* nothing */
}
struct SEE_input *
SEE_input_elinks(struct SEE_interpreter *interp, unsigned char *s)
{
struct input_elinks *input;
input = SEE_NEW(interp, struct input_elinks);
input->inp.interpreter = interp;
input->inp.inputclass = &input_elinks_class;
input->inp.filename = NULL;
input->inp.first_lineno = 1;
input->s = s;
SEE_INPUT_NEXT((struct SEE_input *)input); /* prime */
return (struct SEE_input *)input;
}
unsigned char *
SEE_string_to_unsigned_char(struct SEE_string *S)
{
int i;
unsigned char *str = mem_alloc(S->length + 1);
if (!str)
return NULL;
for (i = 0; i < S->length; i++)
str[i] = (unsigned char)S->data[i];
str[S->length] = '\0';
return str;
}
unsigned char *
SEE_value_to_unsigned_char(struct SEE_interpreter *interp, struct SEE_value *val)
{
struct SEE_value result;
SEE_ToString(interp, val, &result);
return SEE_string_to_unsigned_char(result.u.string);
}
struct SEE_string *
string_to_SEE_string(struct SEE_interpreter *interp, unsigned char *s)
{
unsigned int len;
unsigned int i;
struct SEE_string *str;
len = s ? strlen(s) : 0;
str = SEE_string_new(interp, len);
str->length = len;
for (i = 0; i < len; i++)
str->data[i] = s[i];
return str;
}

View File

@ -0,0 +1,11 @@
#ifndef EL__ECMASCRIPT_SEE_INPUT_H
#define EL__ECMASCRIPT_SEE_INPUT_H
#include <see/see.h>
struct SEE_input *SEE_input_elinks(struct SEE_interpreter *, unsigned char *);
unsigned char *SEE_string_to_unsigned_char(struct SEE_string *);
unsigned char *SEE_value_to_unsigned_char(struct SEE_interpreter *, struct SEE_value *);
struct SEE_string *string_to_SEE_string(struct SEE_interpreter *, unsigned char *);
#endif

View File

@ -0,0 +1,363 @@
/* The SEE location and history objects implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/input.h"
#include "ecmascript/see/location.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/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"
static void delayed_goto(void *);
static void history_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static int history_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void js_history_back(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_history_forward(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_history_go(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_location_toString(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void location_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void location_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static int location_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int location_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
void location_goto(struct document_view *, unsigned char *);
struct js_history_object {
struct SEE_object object;
struct SEE_object *back;
struct SEE_object *forward;
struct SEE_object *go;
};
struct js_location_object {
struct SEE_object object;
struct SEE_object *toString;
};
struct delayed_goto {
/* It might look more convenient to pass doc_view around but it could
* disappear during wild dances inside of frames or so. */
struct view_state *vs;
struct uri *uri;
};
struct SEE_objectclass js_history_object_class = {
NULL,
history_get,
SEE_no_put,
SEE_no_canput,
history_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct SEE_objectclass js_location_object_class = {
NULL,
location_get,
location_put,
location_canput,
location_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
static void
delayed_goto(void *data)
{
struct delayed_goto *deg = data;
assert(deg);
if (deg->vs->doc_view
&& deg->vs->doc_view == deg->vs->doc_view->session->doc_view) {
goto_uri_frame(deg->vs->doc_view->session, deg->uri,
deg->vs->doc_view->name,
CACHE_MODE_NORMAL);
}
done_uri(deg->uri);
mem_free(deg);
}
void
location_goto(struct document_view *doc_view, unsigned char *url)
{
unsigned char *new_abs_url;
struct uri *new_uri;
struct delayed_goto *deg;
/* Workaround for bug 611. Does not crash, but may lead to infinite loop.*/
if (!doc_view) return;
new_abs_url = join_urls(doc_view->document->uri,
trim_chars(url, ' ', 0));
if (!new_abs_url)
return;
new_uri = get_uri(new_abs_url, 0);
mem_free(new_abs_url);
if (!new_uri)
return;
deg = mem_calloc(1, sizeof(*deg));
if (!deg) {
done_uri(new_uri);
return;
}
assert(doc_view->vs);
deg->vs = doc_view->vs;
deg->uri = new_uri;
/* It does not seem to be very safe inside of frames to
* call goto_uri() right away. */
register_bottom_half(delayed_goto, deg);
}
static void
history_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct js_history_object *history = (struct js_history_object *)o;
checktime(interp);
if (p == s_back) {
SEE_SET_OBJECT(res, history->back);
} else if (p == s_forward) {
SEE_SET_OBJECT(res, history->forward);
} else if (p == s_go) {
SEE_SET_OBJECT(res, history->go);
} else {
SEE_SET_UNDEFINED(res);
}
}
static int
history_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_back || p == s_forward || p == s_go)
return 1;
return 0;
}
static void
js_history_back(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
SEE_SET_NULL(res);
go_back(ses);
}
static void
js_history_forward(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
checktime(interp);
SEE_SET_NULL(res);
go_unback(ses);
}
static void
js_history_go(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
unsigned char *str;
int index;
struct location *loc;
checktime(interp);
SEE_SET_NULL(res);
if (argc < 1)
return;
str = SEE_value_to_unsigned_char(interp, argv[0]);
if (!str)
return;
index = atol(str);
mem_free(str);
for (loc = cur_loc(ses);
loc != (struct location *) &ses->history.history;
loc = index > 0 ? loc->next : loc->prev) {
if (!index) {
go_history(ses, loc);
break;
}
index += index > 0 ? -1 : 1;
}
}
static void
js_location_toString(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
unsigned char *string = get_uri_string(vs->uri, URI_ORIGINAL);
struct SEE_string *str = string_to_SEE_string(interp, string);
mem_free_if(string);
checktime(interp);
SEE_SET_STRING(res, str);
}
static void
location_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct js_location_object *loc = (struct js_location_object *)o;
checktime(interp);
if (p == s_toString || p == s_toLocaleString) {
SEE_SET_OBJECT(res, loc->toString);
} else if (p == s_href) {
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
unsigned char *string = get_uri_string(vs->uri, URI_ORIGINAL);
struct SEE_string *str = string_to_SEE_string(interp, string);
mem_free_if(string);
SEE_SET_STRING(res, str);
} else {
SEE_SET_UNDEFINED(res);
}
}
static void
location_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_href) {
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
unsigned char *url = SEE_value_to_unsigned_char(interp, val);
location_goto(doc_view, url);
mem_free(url);
}
}
static int
location_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_toString || p == s_toLocaleString || p == s_href)
return 1;
return 0;
}
static int
location_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_href)
return 1;
return 0;
}
void
init_js_history_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct js_history_object *history = SEE_NEW(interp,
struct js_history_object);
history->object.objectclass = &js_history_object_class;
history->object.objectclass->Class = s_history;
history->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)history);
SEE_OBJECT_PUT(interp, interp->Global, s_history, &v, 0);
history->back = SEE_cfunction_make(interp, js_history_back, s_back, 0);
history->forward = SEE_cfunction_make(interp, js_history_forward, s_forward, 0);
history->go = SEE_cfunction_make(interp, js_history_go, s_go, 1);
}
void
init_js_location_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct js_location_object *loc = SEE_NEW(interp,
struct js_location_object);
loc->object.objectclass = &js_location_object_class;
loc->object.objectclass->Class = s_location;
loc->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)loc);
SEE_OBJECT_PUT(interp, interp->Global, s_location, &v, 0);
loc->toString = SEE_cfunction_make(interp, js_location_toString, s_toString, 0);
}

View File

@ -0,0 +1,9 @@
#ifndef EL__ECMASCRIPT_SEE_LOCATION_H
#define EL__ECMASCRIPT_SEE_LOCATION_H
struct ecmascript_interpreter;
void init_js_history_object(struct ecmascript_interpreter *);
void init_js_location_object(struct ecmascript_interpreter *);
#endif

View File

@ -0,0 +1,150 @@
/* The SEE navigator objects implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/input.h"
#include "ecmascript/see/navigator.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/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"
static void navigator_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static int navigator_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
struct SEE_objectclass js_navigator_object_class = {
NULL,
navigator_get,
SEE_no_put,
SEE_no_canput,
navigator_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
static void
navigator_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct SEE_string *str;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_appCodeName) {
SEE_SET_STRING(res, s_Mozilla);
} else if (p == s_appName) {
SEE_SET_STRING(res, s_ELinks_);
} else if (p == s_appVersion) {
str = string_to_SEE_string(interp, VERSION);
SEE_SET_STRING(res, str);
} else if (p == s_language) {
#ifdef CONFIG_NLS
if (get_opt_bool("protocol.http.accept_ui_language")) {
str = string_to_SEE_string(interp,
language_to_iso639(current_language));
SEE_SET_STRING(res, str);
}
#endif
} else if (p == s_platform) {
str = string_to_SEE_string(interp, system_name);
SEE_SET_STRING(res, str);
} else if (p == s_userAgent) {
/* FIXME: Code duplication. */
unsigned char *optstr = get_opt_str("protocol.http.user_agent");
if (*optstr && strcmp(optstr, " ")) {
unsigned char *ustr, ts[64] = "";
static unsigned char custr[256];
if (!list_empty(terminals)) {
unsigned int tslen = 0;
struct terminal *term = terminals.prev;
ulongcat(ts, &tslen, term->width, 3, 0);
ts[tslen++] = 'x';
ulongcat(ts, &tslen, term->height, 3, 0);
}
ustr = subst_user_agent(optstr, VERSION_STRING, system_name, ts);
if (ustr) {
safe_strncpy(custr, ustr, 256);
mem_free(ustr);
str = string_to_SEE_string(interp, custr);
SEE_SET_STRING(res, str);
}
}
}
}
static int
navigator_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_appCodeName || p == s_appName || p == s_appVersion
|| p == s_language || p == s_platform || p == s_userAgent)
return 1;
return 0;
}
void
init_js_navigator_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct SEE_object *navigator;
navigator = SEE_NEW(interp, struct SEE_object);
navigator->objectclass = &js_navigator_object_class;
navigator->objectclass->Class = s_navigator;
navigator->Prototype = NULL;
SEE_SET_OBJECT(&v, navigator);
SEE_OBJECT_PUT(interp, interp->Global, s_navigator, &v, 0);
}

View File

@ -0,0 +1,8 @@
#ifndef EL__ECMASCRIPT_SEE_NAVIGATOR_H
#define EL__ECMASCRIPT_SEE_NAVIGATOR_H
struct ecmascript_interpreter;
void init_js_navigator_object(struct ecmascript_interpreter *);
#endif

View File

@ -0,0 +1,379 @@
#include <see/see.h>
struct SEE_string *s_window;
struct SEE_string *s_closed;
struct SEE_string *s_parent;
struct SEE_string *s_self;
struct SEE_string *s_top;
struct SEE_string *s_alert;
struct SEE_string *s_open;
struct SEE_string *s_menubar;
struct SEE_string *s_statusbar;
struct SEE_string *s_visible;
struct SEE_string *s_navigator;
struct SEE_string *s_appCodeName;
struct SEE_string *s_appName;
struct SEE_string *s_appVersion;
struct SEE_string *s_language;
struct SEE_string *s_platform;
struct SEE_string *s_userAgent;
struct SEE_string *s_history;
struct SEE_string *s_back;
struct SEE_string *s_forward;
struct SEE_string *s_go;
struct SEE_string *s_location;
struct SEE_string *s_href;
struct SEE_string *s_toString;
struct SEE_string *s_toLocaleString;
struct SEE_string *s_input;
struct SEE_string *s_accessKey;
struct SEE_string *s_alt;
struct SEE_string *s_checked;
struct SEE_string *s_defaultChecked;
struct SEE_string *s_defaultValue;
struct SEE_string *s_disabled;
struct SEE_string *s_form;
struct SEE_string *s_maxLength;
struct SEE_string *s_name;
struct SEE_string *s_readonly;
struct SEE_string *s_size;
struct SEE_string *s_src;
struct SEE_string *s_tabindex;
struct SEE_string *s_type;
struct SEE_string *s_value;
struct SEE_string *s_blur;
struct SEE_string *s_click;
struct SEE_string *s_focus;
struct SEE_string *s_select;
struct SEE_string *s_elements;
struct SEE_string *s_item;
struct SEE_string *s_namedItem;
struct SEE_string *s_length;
struct SEE_string *s_action;
struct SEE_string *s_encoding;
struct SEE_string *s_method;
struct SEE_string *s_target;
struct SEE_string *s_reset;
struct SEE_string *s_submit;
struct SEE_string *s_forms;
struct SEE_string *s_document;
struct SEE_string *s_referrer;
struct SEE_string *s_title;
struct SEE_string *s_url;
struct SEE_string *s_write;
struct SEE_string *s_Mozilla;
struct SEE_string *s_ELinks_;
struct SEE_string *s_cookie;
struct SEE_string *s_GET;
struct SEE_string *s_POST;
struct SEE_string *s_application_;
struct SEE_string *s_multipart_;
struct SEE_string *s_textplain;
struct SEE_string *s_text;
struct SEE_string *s_password;
struct SEE_string *s_file;
struct SEE_string *s_checkbox;
struct SEE_string *s_radio;
struct SEE_string *s_image;
struct SEE_string *s_button;
struct SEE_string *s_hidden;
struct SEE_string *s_timeout;
void
init_intern_strings(void)
{
static SEE_char_t SA_window[] = {'w','i','n','d','o','w'};
static struct SEE_string S_window = SEE_STRING_DECL(SA_window);
static SEE_char_t SA_closed[] = {'c','l','o','s','e','d'};
static struct SEE_string S_closed = SEE_STRING_DECL(SA_closed);
static SEE_char_t SA_parent[] = {'p','a','r','e','n','t'};
static struct SEE_string S_parent = SEE_STRING_DECL(SA_parent);
static SEE_char_t SA_self[] = {'s','e','l','f'};
static struct SEE_string S_self = SEE_STRING_DECL(SA_self);
static SEE_char_t SA_top[] = {'t','o','p'};
static struct SEE_string S_top = SEE_STRING_DECL(SA_top);
static SEE_char_t SA_alert[] ={'a','l','e','r','t'};
static struct SEE_string S_alert = SEE_STRING_DECL(SA_alert);
static SEE_char_t SA_open[] ={'o','p','e','n'};
static struct SEE_string S_open = SEE_STRING_DECL(SA_open);
static SEE_char_t SA_menubar[] = {'m','e','n','u','b','a','r'};
static struct SEE_string S_menubar = SEE_STRING_DECL(SA_menubar);
static SEE_char_t SA_statusbar[] = {'s','t','a','t','u','s','b','a','r'};
static struct SEE_string S_statusbar = SEE_STRING_DECL(SA_statusbar);
static SEE_char_t SA_visible[] = {'v','i','s','i','b','l','e'};
static struct SEE_string S_visible = SEE_STRING_DECL(SA_visible);
static SEE_char_t SA_navigator[] ={'n','a','v','i','g','a','t','o','r'};
static struct SEE_string S_navigator = SEE_STRING_DECL(SA_navigator);
static SEE_char_t SA_appCodeName[] ={'a','p','p','C','o','d','e','N','a','m','e'};
static struct SEE_string S_appCodeName = SEE_STRING_DECL(SA_appCodeName);
static SEE_char_t SA_appName[] ={'a','p','p','N','a','m','e'};
static struct SEE_string S_appName = SEE_STRING_DECL(SA_appName);
static SEE_char_t SA_appVersion[] ={'a','p','p','V','e','r','s','i','o','n'};
static struct SEE_string S_appVersion = SEE_STRING_DECL(SA_appVersion);
static SEE_char_t SA_language[] ={'l','a','n','g','u','a','g','e'};
static struct SEE_string S_language = SEE_STRING_DECL(SA_language);
static SEE_char_t SA_platform[] ={'p','l','a','t','f','o','r','m'};
static struct SEE_string S_platform = SEE_STRING_DECL(SA_platform);
static SEE_char_t SA_userAgent[] ={'u','s','e','r','A','g','e','n','t'};
static struct SEE_string S_userAgent = SEE_STRING_DECL(SA_userAgent);
static SEE_char_t SA_history[] ={'h','i','s','t','o','r','y'};
static struct SEE_string S_history = SEE_STRING_DECL(SA_history);
static SEE_char_t SA_back[] ={'b','a','c','k'};
static struct SEE_string S_back = SEE_STRING_DECL(SA_back);
static SEE_char_t SA_forward[] ={'f','o','r','w','a','r','d'};
static struct SEE_string S_forward = SEE_STRING_DECL(SA_forward);
static SEE_char_t SA_go[] ={'g','o'};
static struct SEE_string S_go = SEE_STRING_DECL(SA_go);
static SEE_char_t SA_location[] ={'l','o','c','a','t','i','o','n'};
static struct SEE_string S_location = SEE_STRING_DECL(SA_location);
static SEE_char_t SA_href[] ={'h','r','e','f'};
static struct SEE_string S_href = SEE_STRING_DECL(SA_href);
static SEE_char_t SA_toString[] ={'t','o','S','t','r','i','n','g'};
static struct SEE_string S_toString = SEE_STRING_DECL(SA_toString);
static SEE_char_t SA_toLocaleString[] ={'t','o','L','o','c','a','l','e','S','t','r','i','n','g'};
static struct SEE_string S_toLocaleString = SEE_STRING_DECL(SA_toLocaleString);
static SEE_char_t SA_input[] ={'i','n','p','u','t'};
static struct SEE_string S_input = SEE_STRING_DECL(SA_input);
static SEE_char_t SA_accessKey[] ={'a','c','c','e','s','s','K','e','y'};
static struct SEE_string S_accessKey = SEE_STRING_DECL(SA_accessKey);
static SEE_char_t SA_alt[] ={'a','l','t'};
static struct SEE_string S_alt = SEE_STRING_DECL(SA_alt);
static SEE_char_t SA_checked[] ={'c','h','e','c','k','e','d'};
static struct SEE_string S_checked = SEE_STRING_DECL(SA_checked);
static SEE_char_t SA_defaultChecked[] ={'d','e','f','a','u','l','t','C','h','e','c','k','e','d'};
static struct SEE_string S_defaultChecked = SEE_STRING_DECL(SA_defaultChecked);
static SEE_char_t SA_defaultValue[] ={'d','e','f','a','u','l','t','V','a','l','u','e'};
static struct SEE_string S_defaultValue = SEE_STRING_DECL(SA_defaultValue);
static SEE_char_t SA_disabled[] ={'d','i','s','a','b','l','e','d'};
static struct SEE_string S_disabled = SEE_STRING_DECL(SA_disabled);
static SEE_char_t SA_form[] ={'f','o','r','m'};
static struct SEE_string S_form = SEE_STRING_DECL(SA_form);
static SEE_char_t SA_maxLength[] ={'m','a','x','L','e','n','g','t','h'};
static struct SEE_string S_maxLength = SEE_STRING_DECL(SA_maxLength);
static SEE_char_t SA_name[] ={'n','a','m','e'};
static struct SEE_string S_name = SEE_STRING_DECL(SA_name);
static SEE_char_t SA_readonly[] ={'r','e','a','d','o','n','l','y'};
static struct SEE_string S_readonly = SEE_STRING_DECL(SA_readonly);
static SEE_char_t SA_size[] ={'s','i','z','e'};
static struct SEE_string S_size = SEE_STRING_DECL(SA_size);
static SEE_char_t SA_src[] ={'s','r','c'};
static struct SEE_string S_src = SEE_STRING_DECL(SA_src);
static SEE_char_t SA_tabindex[] ={'t','a','b','i','n','d','e','x'};
static struct SEE_string S_tabindex = SEE_STRING_DECL(SA_tabindex);
static SEE_char_t SA_type[] ={'t','y','p','e'};
static struct SEE_string S_type = SEE_STRING_DECL(SA_type);
static SEE_char_t SA_value[] ={'v','a','l','u','e'};
static struct SEE_string S_value = SEE_STRING_DECL(SA_value);
static SEE_char_t SA_blur[] ={'b','l','u','r'};
static struct SEE_string S_blur = SEE_STRING_DECL(SA_blur);
static SEE_char_t SA_click[] ={'c','l','i','c','k'};
static struct SEE_string S_click = SEE_STRING_DECL(SA_click);
static SEE_char_t SA_focus[] ={'f','o','c','u','s'};
static struct SEE_string S_focus = SEE_STRING_DECL(SA_focus);
static SEE_char_t SA_select[] ={'s','e','l','e','c','t'};
static struct SEE_string S_select = SEE_STRING_DECL(SA_select);
static SEE_char_t SA_elements[] ={'e','l','e','m','e','n','t','s'};
static struct SEE_string S_elements = SEE_STRING_DECL(SA_elements);
static SEE_char_t SA_item[] ={'i','t','e','m'};
static struct SEE_string S_item = SEE_STRING_DECL(SA_item);
static SEE_char_t SA_namedItem[] ={'n','a','m','e','d','I','t','e','m'};
static struct SEE_string S_namedItem = SEE_STRING_DECL(SA_namedItem);
static SEE_char_t SA_length[] ={'l','e','n','g','t','h'};
static struct SEE_string S_length = SEE_STRING_DECL(SA_length);
static SEE_char_t SA_action[] ={'a','c','t','i','o','n'};
static struct SEE_string S_action = SEE_STRING_DECL(SA_action);
static SEE_char_t SA_encoding[] ={'e','n','c','o','d','i','g'};
static struct SEE_string S_encoding = SEE_STRING_DECL(SA_encoding);
static SEE_char_t SA_method[] ={'m','e','t','h','o','d'};
static struct SEE_string S_method = SEE_STRING_DECL(SA_method);
static SEE_char_t SA_target[] ={'t','a','r','g','e','t'};
static struct SEE_string S_target = SEE_STRING_DECL(SA_target);
static SEE_char_t SA_reset[] ={'r','e','s','e','t'};
static struct SEE_string S_reset = SEE_STRING_DECL(SA_reset);
static SEE_char_t SA_submit[] ={'s','u','b','m','i','t'};
static struct SEE_string S_submit = SEE_STRING_DECL(SA_submit);
static SEE_char_t SA_forms[] ={'f','o','r','m','s'};
static struct SEE_string S_forms = SEE_STRING_DECL(SA_forms);
static SEE_char_t SA_document[] = {'d','o','c','u','m','e','n','t'};
static struct SEE_string S_document = SEE_STRING_DECL(SA_document);
static SEE_char_t SA_referrer[] ={'r','e','f','e','r','r','e','r'};
static struct SEE_string S_referrer = SEE_STRING_DECL(SA_referrer);
static SEE_char_t SA_title[] ={'t','i','t','l','e'};
static struct SEE_string S_title = SEE_STRING_DECL(SA_title);
static SEE_char_t SA_url[] ={'u','r','l'};
static struct SEE_string S_url = SEE_STRING_DECL(SA_url);
static SEE_char_t SA_write[] = {'w','r','i','t','e'};
static struct SEE_string S_write = SEE_STRING_DECL(SA_write);
static SEE_char_t SA_Mozilla[] = {'M','o','z','i','l','l','a'};
static struct SEE_string S_Mozilla = SEE_STRING_DECL(SA_Mozilla);
static SEE_char_t SA_ELinks_[] = {'E','L','i','n','k','s',' ','(',
'r','o','u','g','h','l','y',' ','c','o','m','p','a','t','i','b','l','e',
' ','w','i','t','h',' ','N','e','t','s','c','a','p','e',' ',
'N','a','v','i','g','a','t','o','r',',',' ','M','o','z','i','l','l','a',
' ','a','n','d',' ','M','i','c','r','o','s','o','f','t',' ',
'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',')'};
static struct SEE_string S_ELinks_ = SEE_STRING_DECL(SA_ELinks_);
static SEE_char_t SA_cookie[] = {'c','o','o','k','i','e'};
static struct SEE_string S_cookie = SEE_STRING_DECL(SA_cookie);
static SEE_char_t SA_GET[] = {'G','E','T'};
static struct SEE_string S_GET = SEE_STRING_DECL(SA_GET);
static SEE_char_t SA_POST[] = {'P','O','S','T'};
static struct SEE_string S_POST = SEE_STRING_DECL(SA_POST);
static SEE_char_t SA_application_[] = {'a','p','p','l','i','c','a','t',
'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l',
'e','n','c','o','d','e','d'};
static struct SEE_string S_application_ = SEE_STRING_DECL(SA_application_);
static SEE_char_t SA_multipart_[] = {'m','u','l','t','i','p','a','r','t','/',
'f','o','r','m','-','d','a','t','a'};
static struct SEE_string S_multipart_ = SEE_STRING_DECL(SA_multipart_);
static SEE_char_t SA_textplain[] = {'t','e','x','t','/','p','l','a','i','n'};
static struct SEE_string S_textplain = SEE_STRING_DECL(SA_textplain);
static SEE_char_t SA_text[] = {'t','e','x','t'};
static struct SEE_string S_text = SEE_STRING_DECL(SA_text);
static SEE_char_t SA_password[] = {'p','a','s','s','w','o','r','d'};
static struct SEE_string S_password = SEE_STRING_DECL(SA_password);
static SEE_char_t SA_file[] = {'f','i','l','e'};
static struct SEE_string S_file = SEE_STRING_DECL(SA_file);
static SEE_char_t SA_checkbox[] = {'c','h','e','c','k','b','o','x'};
static struct SEE_string S_checkbox = SEE_STRING_DECL(SA_checkbox);
static SEE_char_t SA_radio[] = {'r','a','d','i','o'};
static struct SEE_string S_radio = SEE_STRING_DECL(SA_radio);
static SEE_char_t SA_image[] = {'i','m','a','g','e'};
static struct SEE_string S_image = SEE_STRING_DECL(SA_image);
static SEE_char_t SA_button[] = {'b','u','t','t','o','n'};
static struct SEE_string S_button = SEE_STRING_DECL(SA_button);
static SEE_char_t SA_hidden[] = {'h','i','d','d','e','n'};
static struct SEE_string S_hidden = SEE_STRING_DECL(SA_hidden);
static SEE_char_t SA_timeout[] = {'t','i','m','e','o','u','t'};
static struct SEE_string S_timeout = SEE_STRING_DECL(SA_timeout);
SEE_intern_global(s_window = &S_window);
SEE_intern_global(s_closed = &S_closed);
SEE_intern_global(s_parent = &S_parent);
SEE_intern_global(s_self = &S_self);
SEE_intern_global(s_top = &S_top);
SEE_intern_global(s_alert = &S_alert);
SEE_intern_global(s_open = &S_open);
SEE_intern_global(s_menubar = &S_menubar);
SEE_intern_global(s_statusbar = &S_statusbar);
SEE_intern_global(s_visible = &S_visible);
SEE_intern_global(s_navigator = &S_navigator);
SEE_intern_global(s_appCodeName = &S_appCodeName);
SEE_intern_global(s_appName = &S_appName);
SEE_intern_global(s_appVersion = &S_appVersion);
SEE_intern_global(s_language = &S_language);
SEE_intern_global(s_platform = &S_platform);
SEE_intern_global(s_userAgent = &S_userAgent);
SEE_intern_global(s_history = &S_history);
SEE_intern_global(s_back = &S_back);
SEE_intern_global(s_forward = &S_forward);
SEE_intern_global(s_go = &S_go);
SEE_intern_global(s_location = &S_location);
SEE_intern_global(s_href = &S_href);
SEE_intern_global(s_toString = &S_toString);
SEE_intern_global(s_toLocaleString = &S_toLocaleString);
SEE_intern_global(s_input = &S_input);
SEE_intern_global(s_accessKey = &S_accessKey);
SEE_intern_global(s_alt = &S_alt);
SEE_intern_global(s_checked = &S_checked);
SEE_intern_global(s_defaultChecked = &S_defaultChecked);
SEE_intern_global(s_defaultValue = &S_defaultValue);
SEE_intern_global(s_disabled = &S_disabled);
SEE_intern_global(s_form = &S_form);
SEE_intern_global(s_maxLength = &S_maxLength);
SEE_intern_global(s_name = &S_name);
SEE_intern_global(s_readonly = &S_readonly);
SEE_intern_global(s_size = &S_size);
SEE_intern_global(s_src = &S_src);
SEE_intern_global(s_tabindex = &S_tabindex);
SEE_intern_global(s_type = &S_type);
SEE_intern_global(s_value = &S_value);
SEE_intern_global(s_blur = &S_blur);
SEE_intern_global(s_click = &S_click);
SEE_intern_global(s_focus = &S_focus);
SEE_intern_global(s_select = &S_select);
SEE_intern_global(s_elements = &S_elements);
SEE_intern_global(s_item = &S_item);
SEE_intern_global(s_namedItem = &S_namedItem);
SEE_intern_global(s_length = &S_length);
SEE_intern_global(s_action = &S_action);
SEE_intern_global(s_encoding = &S_encoding);
SEE_intern_global(s_method = &S_method);
SEE_intern_global(s_target = &S_target);
SEE_intern_global(s_reset = &S_reset);
SEE_intern_global(s_submit = &S_submit);
SEE_intern_global(s_forms = &S_forms);
SEE_intern_global(s_document = &S_document);
SEE_intern_global(s_referrer = &S_referrer);
SEE_intern_global(s_title = &S_title);
SEE_intern_global(s_url = &S_url);
SEE_intern_global(s_write = &S_write);
SEE_intern_global(s_Mozilla = &S_Mozilla);
SEE_intern_global(s_ELinks_ = &S_ELinks_);
SEE_intern_global(s_cookie = &S_cookie);
SEE_intern_global(s_GET = &S_GET);
SEE_intern_global(s_POST = &S_POST);
SEE_intern_global(s_application_ = &S_application_);
SEE_intern_global(s_multipart_ = &S_multipart_);
SEE_intern_global(s_textplain = &S_textplain);
SEE_intern_global(s_text = &S_text);
SEE_intern_global(s_password = &S_password);
SEE_intern_global(s_file = &S_file);
SEE_intern_global(s_checkbox = &S_checkbox);
SEE_intern_global(s_radio = &S_radio);
SEE_intern_global(s_image = &S_image);
SEE_intern_global(s_button = &S_button);
SEE_intern_global(s_hidden = &S_hidden);
SEE_intern_global(s_timeout = &S_timeout);
}

View File

@ -0,0 +1,101 @@
#ifndef EL__ECMASCRIPT_SEE_STRINGS_H
#define EL__ECMASCRIPT_SEE_STRINGS_H
#include <see/see.h>
void init_intern_strings(void);
extern struct SEE_string *s_window;
extern struct SEE_string *s_closed;
extern struct SEE_string *s_parent;
extern struct SEE_string *s_self;
extern struct SEE_string *s_top;
extern struct SEE_string *s_alert;
extern struct SEE_string *s_open;
extern struct SEE_string *s_menubar;
extern struct SEE_string *s_statusbar;
extern struct SEE_string *s_visible;
extern struct SEE_string *s_navigator;
extern struct SEE_string *s_appCodeName;
extern struct SEE_string *s_appName;
extern struct SEE_string *s_appVersion;
extern struct SEE_string *s_language;
extern struct SEE_string *s_platform;
extern struct SEE_string *s_userAgent;
extern struct SEE_string *s_history;
extern struct SEE_string *s_back;
extern struct SEE_string *s_forward;
extern struct SEE_string *s_go;
extern struct SEE_string *s_location;
extern struct SEE_string *s_href;
extern struct SEE_string *s_toString;
extern struct SEE_string *s_toLocaleString;
extern struct SEE_string *s_input;
extern struct SEE_string *s_accessKey;
extern struct SEE_string *s_alt;
extern struct SEE_string *s_checked;
extern struct SEE_string *s_defaultChecked;
extern struct SEE_string *s_defaultValue;
extern struct SEE_string *s_disabled;
extern struct SEE_string *s_form;
extern struct SEE_string *s_maxLength;
extern struct SEE_string *s_name;
extern struct SEE_string *s_readonly;
extern struct SEE_string *s_size;
extern struct SEE_string *s_src;
extern struct SEE_string *s_tabindex;
extern struct SEE_string *s_type;
extern struct SEE_string *s_value;
extern struct SEE_string *s_blur;
extern struct SEE_string *s_click;
extern struct SEE_string *s_focus;
extern struct SEE_string *s_select;
extern struct SEE_string *s_elements;
extern struct SEE_string *s_item;
extern struct SEE_string *s_namedItem;
extern struct SEE_string *s_length;
extern struct SEE_string *s_action;
extern struct SEE_string *s_encoding;
extern struct SEE_string *s_method;
extern struct SEE_string *s_target;
extern struct SEE_string *s_reset;
extern struct SEE_string *s_submit;
extern struct SEE_string *s_forms;
extern struct SEE_string *s_document;
extern struct SEE_string *s_referrer;
extern struct SEE_string *s_title;
extern struct SEE_string *s_url;
extern struct SEE_string *s_write;
extern struct SEE_string *s_Mozilla;
extern struct SEE_string *s_ELinks_;
extern struct SEE_string *s_cookie;
extern struct SEE_string *s_GET;
extern struct SEE_string *s_POST;
extern struct SEE_string *s_application_;
extern struct SEE_string *s_multipart_;
extern struct SEE_string *s_textplain;
extern struct SEE_string *s_text;
extern struct SEE_string *s_password;
extern struct SEE_string *s_file;
extern struct SEE_string *s_checkbox;
extern struct SEE_string *s_radio;
extern struct SEE_string *s_image;
extern struct SEE_string *s_button;
extern struct SEE_string *s_hidden;
extern struct SEE_string *s_timeout;
#endif

206
src/ecmascript/see/unibar.c Normal file
View File

@ -0,0 +1,206 @@
/* The SEE location and history objects implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/input.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/unibar.h"
#include "ecmascript/see/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"
static void unibar_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void unibar_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static int unibar_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int unibar_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
struct js_unibar_object {
struct SEE_object object;
unsigned char bar;
};
struct SEE_objectclass js_menubar_object_class = {
NULL,
unibar_get,
unibar_put,
unibar_canput,
unibar_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
struct SEE_objectclass js_statusbar_object_class = {
NULL,
unibar_get,
unibar_put,
unibar_canput,
unibar_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
static void
unibar_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session_status *status = &doc_view->session->status;
struct js_unibar_object *obj = (struct js_unibar_object *)o;
unsigned char bar = obj->bar;
checktime(interp);
if (p == s_visible) {
#define unibar_fetch(bar) \
SEE_SET_BOOLEAN(res, status->force_show_##bar##_bar >= 0 \
? status->force_show_##bar##_bar \
: status->show_##bar##_bar)
switch (bar) {
case 's':
unibar_fetch(status);
break;
case 't':
unibar_fetch(title);
break;
default:
SEE_SET_BOOLEAN(res, 0);
break;
}
#undef unibar_fetch
return;
}
SEE_SET_UNDEFINED(res);
}
static void
unibar_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_location) {
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
struct session_status *status = &doc_view->session->status;
struct js_unibar_object *obj = (struct js_unibar_object *)o;
unsigned char bar = obj->bar;
switch (bar) {
case 's':
status->force_show_status_bar =
SEE_ToUint32(interp, val);
break;
case 't':
status->force_show_title_bar =
SEE_ToUint32(interp, val);
break;
default:
break;
}
}
}
static int
unibar_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_visible)
return 1;
return 0;
}
static int
unibar_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_visible)
return 1;
return 0;
}
void
init_js_menubar_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct js_unibar_object *menu;
menu = SEE_NEW(interp, struct js_unibar_object);
menu->object.objectclass = &js_menubar_object_class;
menu->object.objectclass->Class = s_menubar;
menu->object.Prototype = NULL;
menu->bar = 't';
SEE_SET_OBJECT(&v, (struct SEE_object *)menu);
SEE_OBJECT_PUT(interp, interp->Global, s_menubar, &v, 0);
}
void
init_js_statusbar_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
struct js_unibar_object *status;
status = SEE_NEW(interp, struct js_unibar_object);
status->object.objectclass = &js_statusbar_object_class;
status->object.objectclass->Class = s_statusbar;
status->object.Prototype = NULL;
status->bar = 's';
SEE_SET_OBJECT(&v, (struct SEE_object *)status);
SEE_OBJECT_PUT(interp, interp->Global, s_statusbar, &v, 0);
}

View File

@ -0,0 +1,9 @@
#ifndef EL__ECMASCRIPT_SEE_UNIBAR_H
#define EL__ECMASCRIPT_SEE_UNIBAR_H
struct emascript_interpreter;
void init_js_menubar_object(struct ecmascript_interpreter *);
void init_js_statusbar_object(struct ecmascript_interpreter *);
#endif

371
src/ecmascript/see/window.c Normal file
View File

@ -0,0 +1,371 @@
/* The SEE window object implementation. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "elinks.h"
#include <see/see.h>
#include "bfu/dialog.h"
#include "cache/cache.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/see/input.h"
#include "ecmascript/see/strings.h"
#include "ecmascript/see/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"
static struct js_window_object *js_get_global_object(void *);
static struct js_window_object *js_try_resolve_frame(struct document_view *, unsigned char *);
static void delayed_open(void *);
static void delayed_goto_uri_frame(void *);
static void window_get(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *);
static void window_put(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *, struct SEE_value *, int);
static int window_canput(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static int window_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
static void js_window_alert(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
static void js_window_open(struct SEE_interpreter *, struct SEE_object *, struct SEE_object *, int, struct SEE_value **, struct SEE_value *);
void location_goto(struct document_view *, unsigned char *);
struct delayed_open {
struct session *ses;
struct uri *uri;
unsigned char *target;
};
struct SEE_objectclass js_window_object_class = {
NULL,
window_get,
window_put,
window_canput,
window_hasproperty,
SEE_no_delete,
SEE_no_defaultvalue,
NULL,
NULL,
NULL,
NULL
};
static struct js_window_object *
js_get_global_object(void *data)
{
struct global_object *g = (struct global_object *)data;
return g->win;
}
static struct js_window_object *
js_try_resolve_frame(struct document_view *doc_view, unsigned char *id)
{
struct session *ses = doc_view->session;
struct frame *target;
assert(ses);
target = ses_find_frame(ses, id);
if (!target) return NULL;
if (target->vs.ecmascript_fragile)
ecmascript_reset_state(&target->vs);
if (!target->vs.ecmascript) return NULL;
return js_get_global_object(target->vs.ecmascript->backend_data);
}
static void
delayed_open(void *data)
{
struct delayed_open *deo = data;
assert(deo);
open_uri_in_new_tab(deo->ses, deo->uri, 0, 0);
done_uri(deo->uri);
mem_free(deo);
}
static void
delayed_goto_uri_frame(void *data)
{
struct delayed_open *deo = data;
assert(deo);
goto_uri_frame(deo->ses, deo->uri, deo->target, CACHE_MODE_NORMAL);
done_uri(deo->uri);
mem_free(deo);
}
static void
window_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *res)
{
struct js_window_object *win = (struct js_window_object *)o;
struct view_state *vs = win->vs;
checktime(interp);
if (p == s_closed) {
SEE_SET_BOOLEAN(res, 0);
} else if (p == s_self) {
SEE_SET_OBJECT(res, o);
} else if (p == s_top || p == s_parent) {
struct document_view *doc_view = vs->doc_view;
struct document_view *top_view = doc_view->session->doc_view;
struct js_window_object *newjsframe;
assert(top_view && top_view->vs);
if (top_view->vs->ecmascript_fragile)
ecmascript_reset_state(top_view->vs);
if (!top_view->vs->ecmascript) {
SEE_SET_UNDEFINED(res);
return;
}
newjsframe = js_get_global_object(
top_view->vs->ecmascript->backend_data);
/* Keep this unrolled this way. Will have to check document.domain
* JS property. */
/* Note that this check is perhaps overparanoid. If top windows
* is alien but some other child window is not, we should still
* let the script walk thru. That'd mean moving the check to
* other individual properties in this switch. */
if (compare_uri(vs->uri, top_view->vs->uri, URI_HOST)) {
SEE_SET_OBJECT(res, (struct SEE_object *)newjsframe);
}
} else if (p == s_alert) {
SEE_SET_OBJECT(res, win->alert);
} else if (p == s_open) {
SEE_SET_OBJECT(res, win->open);
} else {
unsigned char *frame = SEE_string_to_unsigned_char(p);
struct document_view *doc_view = vs->doc_view;
struct js_window_object *obj =
js_try_resolve_frame(doc_view, frame);
mem_free_if(frame);
if (obj) {
SEE_SET_OBJECT(res, (struct SEE_object *)obj);
} else {
SEE_SET_UNDEFINED(res);
}
}
}
static void
window_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_location) {
struct js_window_object *win = (struct js_window_object *)o;
struct view_state *vs = win->vs;
struct document_view *doc_view = vs->doc_view;
unsigned char *str = SEE_value_to_unsigned_char(interp, val);
if (str) {
location_goto(doc_view, str);
mem_free(str);
}
}
}
static int
window_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_location)
return 1;
return 0;
}
static int
window_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
static void
js_window_alert(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct js_window_object *win = (struct js_window_object *)thisobj;
struct view_state *vs = win->vs;
unsigned char *string;
checktime(interp);
SEE_SET_BOOLEAN(res, 1);
if (argc < 1)
return;
string = SEE_value_to_unsigned_char(interp, argv[0]);
if (!string || !*string)
return;
info_box(vs->doc_view->session->tab->term, MSGBOX_FREE_TEXT,
N_("JavaScript Alert"), ALIGN_CENTER, string);
}
static void
js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
struct js_window_object *win = (struct js_window_object*)thisobj;
struct view_state *vs = win->vs;
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
unsigned char *target = "";
unsigned char *url, *url2;
struct uri *uri;
#if 0
static time_t ratelimit_start;
static int ratelimit_count;
#endif
checktime(interp);
SEE_SET_UNDEFINED(res);
if (get_opt_bool("ecmascript.block_window_opening")) {
#ifdef CONFIG_LEDS
set_led_value(ses->status.popup_led, 'P');
#endif
return;
}
if (argc < 1) return;
#if 0
/* Ratelimit window opening. Recursive window.open() is very nice.
* We permit at most 20 tabs in 2 seconds. The ratelimiter is very
* rough but shall suffice against the usual cases. */
if (!ratelimit_start || time(NULL) - ratelimit_start > 2) {
ratelimit_start = time(NULL);
ratelimit_count = 0;
} else {
ratelimit_count++;
if (ratelimit_count > 20)
return;
}
#endif
url = SEE_value_to_unsigned_char(interp, argv[0]);
if (!url) return;
/* TODO: Support for window naming and perhaps some window features? */
url2 = join_urls(doc_view->document->uri,
trim_chars(url, ' ', 0));
mem_free(url);
if (!url2) return;
uri = get_uri(url2, 0);
mem_free(url2);
if (!uri) return;
if (argc > 1)
target = SEE_value_to_unsigned_char(interp, argv[1]);
if (target && *target && strcasecmp(target, "_blank")) {
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
if (deo) {
deo->ses = ses;
deo->uri = get_uri_reference(uri);
deo->target = target;
register_bottom_half(delayed_goto_uri_frame, deo);
goto end;
}
}
if (!get_cmd_opt_bool("no-connect")
&& !get_cmd_opt_bool("no-home")
&& !get_cmd_opt_bool("anonymous")
&& can_open_in_new(ses->tab->term)) {
open_uri_in_new_window(ses, uri, NULL, ENV_ANY,
CACHE_MODE_NORMAL, TASK_NONE);
} else {
/* When opening a new tab, we might get rerendered, losing our
* context and triggerring a disaster, so postpone that. */
struct delayed_open *deo = mem_calloc(1, sizeof(*deo));
if (deo) {
deo->ses = ses;
deo->uri = get_uri_reference(uri);
register_bottom_half(delayed_open, deo);
}
}
end:
done_uri(uri);
}
void
init_js_window_object(struct ecmascript_interpreter *interpreter)
{
struct global_object *g = interpreter->backend_data;
struct SEE_interpreter *interp = &g->interp;
struct SEE_value v;
g->win = SEE_NEW(interp, struct js_window_object);
g->win->object.objectclass = &js_window_object_class;
g->win->object.objectclass->Class = s_window;
g->win->object.Prototype = NULL;
g->win->vs = interpreter->vs;
SEE_SET_OBJECT(&v, (struct SEE_object *)g->win);
SEE_OBJECT_PUT(interp, interp->Global, s_window, &v, 0);
g->win->alert = SEE_cfunction_make(interp, js_window_alert, s_alert, 1);
g->win->open = SEE_cfunction_make(interp, js_window_open, s_open, 3);
}
void
checktime(struct SEE_interpreter *interp)
{
struct global_object *g = (struct global_object *)interp;
if (time(NULL) - g->exec_start > g->max_exec_time) {
struct terminal *term = g->win->vs->doc_view->session->tab->term;
/* A killer script! Alert! */
ecmascript_timeout_dialog(term, g->max_exec_time);
SEE_error_throw_string(interp, interp->Error, s_timeout);
}
}

View File

@ -0,0 +1,27 @@
#ifndef EL__ECMASCRIPT_SEE_WINDOW_H
#define EL__ECMASCRIPT_SEE_WINDOW_H
struct SEE_object;
struct SEE_interpreter;
struct string;
struct view_state;
struct js_window_object {
struct SEE_object object;
struct view_state *vs;
struct SEE_object *alert;
struct SEE_object *open;
};
struct global_object {
struct SEE_interpreter interp;
struct js_window_object *win;
int exec_start;
int max_exec_time;
};
void init_js_window_object(struct ecmascript_interpreter *);
void checktime(struct SEE_interpreter *interp);
#endif

View File

@ -61,6 +61,76 @@
static JSRuntime *jsrt;
void
ecmascript_init(struct module *module)
{
spidermonkey_init();
}
void
ecmascript_done(struct module *module)
{
spidermonkey_done();
}
struct ecmascript_interpreter *
ecmascript_get_interpreter(struct view_state *vs)
{
struct ecmascript_interpreter *interpreter;
assert(vs);
interpreter = mem_calloc(1, sizeof(*interpreter));
if (!interpreter)
return NULL;
interpreter->vs = vs;
init_list(interpreter->onload_snippets);
spidermonkey_get_interpreter(interpreter);
return interpreter;
}
void
ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter)
{
assert(interpreter);
spidermonkey_put_interpreter(interpreter);
free_string_list(&interpreter->onload_snippets);
mem_free(interpreter);
}
void
ecmascript_eval(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return;
assert(interpreter);
spidermonkey_eval(interpreter, code);
}
unsigned char *
ecmascript_eval_stringback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return NULL;
assert(interpreter);
return spidermonkey_eval_stringback(interpreter, code);
}
int
ecmascript_eval_boolback(struct ecmascript_interpreter *interpreter,
struct string *code)
{
if (!get_ecmascript_enable())
return -1;
assert(interpreter);
return spidermonkey_eval_boolback(interpreter, code);
}
static void
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
{
@ -123,14 +193,7 @@ safeguard(JSContext *ctx, JSScript *script)
struct terminal *term = interpreter->vs->doc_view->session->tab->term;
/* A killer script! Alert! */
info_box(term, MSGBOX_FREE_TEXT,
N_("JavaScript Emergency"), ALIGN_LEFT,
msg_text(term,
N_("A script embedded in the current document was running\n"
"for more than %d seconds. This probably means there is\n"
"a bug in the script and it could have halted the whole\n"
"ELinks, so the script execution was interrupted."),
max_exec_time));
ecmascript_timeout_dialog(term, max_exec_time);
return JS_FALSE;
}
return JS_TRUE;

View File

@ -0,0 +1,5 @@
<script>
while (true) {
var a = location.href;
}
</script>