diff --git a/src/ecmascript/spidermonkey/Makefile b/src/ecmascript/spidermonkey/Makefile
index 3007fb4e..e88155e2 100644
--- a/src/ecmascript/spidermonkey/Makefile
+++ b/src/ecmascript/spidermonkey/Makefile
@@ -2,7 +2,7 @@ top_builddir=../../..
include $(top_builddir)/Makefile.config
INCLUDES += $(SPIDERMONKEY_CFLAGS)
-OBJS = attr.o attributes.o collection.o console.o document.o element.o form.o heartbeat.o history.o implementation.o \
+OBJS = attr.o attributes.o collection.o console.o document.o element.o form.o heartbeat.o history.o implementation.o input.o \
location.o localstorage.o navigator.o nodelist.o screen.o unibar.o window.o
include $(top_srcdir)/Makefile.lib
diff --git a/src/ecmascript/spidermonkey/form.c b/src/ecmascript/spidermonkey/form.c
index cf3c9bf2..376cf4f0 100644
--- a/src/ecmascript/spidermonkey/form.c
+++ b/src/ecmascript/spidermonkey/form.c
@@ -26,6 +26,7 @@
#include "ecmascript/spidermonkey.h"
#include "ecmascript/spidermonkey/document.h"
#include "ecmascript/spidermonkey/form.h"
+#include "ecmascript/spidermonkey/input.h"
#include "ecmascript/spidermonkey/window.h"
#include "intl/libintl.h"
#include "main/select.h"
@@ -82,1917 +83,12 @@ static JSClassOps form_ops = {
};
/* Each @form_class object must have a @document_class parent. */
-static JSClass form_class = {
+JSClass form_class = {
"form",
JSCLASS_HAS_PRIVATE, /* struct form_view *, or NULL if detached */
&form_ops
};
-/* Accordingly to the JS specs, each input type should own object. That'd be a
- * huge PITA though, however DOM comes to the rescue and defines just a single
- * HTMLInputElement. The difference could be spotted only by some clever tricky
- * JS code, but I hope it doesn't matter anywhere. --pasky */
-
-static bool input_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
-static bool input_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
-static void input_finalize(JSFreeOp *op, JSObject *obj);
-
-static JSClassOps input_ops = {
- nullptr, // addProperty
- nullptr, // deleteProperty
- nullptr, // enumerate
- nullptr, // newEnumerate
- nullptr, // resolve
- nullptr, // mayResolve
- input_finalize, // finalize
- nullptr, // call
- nullptr, // hasInstance
- nullptr, // construct
- JS_GlobalObjectTraceHook
-};
-
-/* Each @input_class object must have a @form_class parent. */
-static JSClass input_class = {
- "input", /* here, we unleash ourselves */
- JSCLASS_HAS_PRIVATE, /* struct form_state *, or NULL if detached */
- &input_ops
-};
-
-/* Tinyids of properties. Use negative values to distinguish these
- * from array indexes (even though this object has no array elements).
- * ECMAScript code should not use these directly as in input[-1];
- * future versions of ELinks may change the numbers. */
-enum input_prop {
- JSP_INPUT_ACCESSKEY = -1,
- JSP_INPUT_ALT = -2,
- JSP_INPUT_CHECKED = -3,
- JSP_INPUT_DEFAULT_CHECKED = -4,
- JSP_INPUT_DEFAULT_VALUE = -5,
- JSP_INPUT_DISABLED = -6,
- JSP_INPUT_FORM = -7,
- JSP_INPUT_MAX_LENGTH = -8,
- JSP_INPUT_NAME = -9,
- JSP_INPUT_READONLY = -10,
- JSP_INPUT_SELECTED_INDEX = -11,
- JSP_INPUT_SIZE = -12,
- JSP_INPUT_SRC = -13,
- JSP_INPUT_TABINDEX = -14,
- JSP_INPUT_TYPE = -15,
- JSP_INPUT_VALUE = -16,
-};
-
-static JSString *unicode_to_jsstring(JSContext *ctx, unicode_val_T u);
-static unicode_val_T jsval_to_accesskey(JSContext *ctx, JS::MutableHandleValue hvp);
-static struct form_state *input_get_form_state(JSContext *ctx, JSObject *jsinput);
-
-
-static bool
-input_get_property_accessKey(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- JSString *keystr;
-
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
-
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- linknum = get_form_control_link(document, fc);
- /* Hiddens have no link. */
- if (linknum >= 0) link = &document->links[linknum];
-
- if (!link) {
- args.rval().setUndefined();
- return true;
- }
-
- if (!link->accesskey) {
- args.rval().set(JS_GetEmptyStringValue(ctx));
- } else {
- keystr = unicode_to_jsstring(ctx, link->accesskey);
- if (keystr) {
- args.rval().setString(keystr);
- }
- else {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- }
- return true;
-}
-
-static bool
-input_set_property_accessKey(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- unicode_val_T accesskey;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- linknum = get_form_control_link(document, fc);
- /* Hiddens have no link. */
- if (linknum >= 0) link = &document->links[linknum];
-
-// accesskey = jsval_to_accesskey(ctx, args[0]);
-
- size_t len;
- char16_t chr[2];
-
- accesskey = UCS_NO_CHAR;
-
- if (!args[0].isString()) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- JSString *str = args[0].toString();
-
- len = JS_GetStringLength(str);
-
- /* This implementation ignores extra characters in the string. */
- if (len < 1) {
- accesskey = 0; /* which means no access key */
- } else if (len == 1) {
- JS_GetStringCharAt(ctx, str, 0, &chr[0]);
- if (!is_utf16_surrogate(chr[0])) {
- accesskey = chr[0];
- }
- } else {
- JS_GetStringCharAt(ctx, str, 1, &chr[1]);
- if (is_utf16_high_surrogate(chr[0])
- && is_utf16_low_surrogate(chr[1])) {
- accesskey = join_utf16_surrogates(chr[0], chr[1]);
- }
- }
- if (accesskey == UCS_NO_CHAR) {
- JS_ReportErrorUTF8(ctx, "Invalid UTF-16 sequence");
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- if (link) {
- link->accesskey = accesskey;
- }
-
- return true;
-}
-
-static bool
-input_get_property_alt(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
-
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- args.rval().setString(JS_NewStringCopyZ(ctx, fc->alt));
-
- return true;
-}
-
-static bool
-input_set_property_alt(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- mem_free_set(&fc->alt, jsval_to_string(ctx, args[0]));
-
- return true;
-}
-
-static bool
-input_get_property_checked(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct form_state *fs;
-
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
-
- args.rval().setBoolean(fs->state);
-
- return true;
-}
-
-static bool
-input_set_property_checked(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
-
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO)
- return true;
- fs->state = args[0].toBoolean();
-
- return true;
-}
-
-static bool
-input_get_property_defaultChecked(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- args.rval().setBoolean(fc->default_state);
-
- return true;
-}
-
-static bool
-input_get_property_defaultValue(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- /* FIXME (bug 805): convert from the charset of the document */
- args.rval().setString(JS_NewStringCopyZ(ctx, fc->default_value));
-
- return true;
-}
-
-static bool
-input_get_property_disabled(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- /* FIXME: --pasky */
- args.rval().setBoolean(fc->mode == FORM_MODE_DISABLED);
-
- return true;
-}
-
-static bool
-input_set_property_disabled(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- /* FIXME: --pasky */
- fc->mode = (args[0].toBoolean() ? FORM_MODE_DISABLED
- : fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY
- : FORM_MODE_NORMAL);
-
- return true;
-}
-
-static bool
-input_get_property_form(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- JS::RootedObject parent_form(ctx, JS::GetNonCCWObjectGlobal(hobj));
- assert(JS_InstanceOf(ctx, parent_form, &form_class, NULL));
- if_assert_failed {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- args.rval().setObject(*parent_form);
-
- return true;
-}
-
-static bool
-input_get_property_maxLength(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- args.rval().setInt32(fc->maxlength);
-
- return true;
-}
-
-static bool
-input_set_property_maxLength(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- fc->maxlength = args[0].toInt32();
-
- return true;
-}
-
-static bool
-input_get_property_name(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- args.rval().setString(JS_NewStringCopyZ(ctx, fc->name));
-
- return true;
-}
-
-/* @input_class.setProperty */
-static bool
-input_set_property_name(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
-
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- mem_free_set(&fc->name, jsval_to_string(ctx, args[0]));
-
- return true;
-}
-
-static bool
-input_get_property_readonly(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- /* FIXME: --pasky */
- args.rval().setBoolean(fc->mode == FORM_MODE_READONLY);
-
- return true;
-}
-
-/* @input_class.setProperty */
-static bool
-input_set_property_readonly(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- /* FIXME: --pasky */
- fc->mode = (args[0].toBoolean() ? FORM_MODE_READONLY
- : fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED
- : FORM_MODE_NORMAL);
-
- return true;
-}
-
-static bool
-input_get_property_selectedIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- if (fc->type == FC_SELECT) {
- args.rval().setInt32(fs->state);
- }
- else {
- args.rval().setUndefined();
- }
-
- return true;
-}
-
-/* @input_class.setProperty */
-static bool
-input_set_property_selectedIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- if (fc->type == FC_SELECT) {
- int item = args[0].toInt32();
-
- if (item >= 0 && item < fc->nvalues) {
- fs->state = item;
- mem_free_set(&fs->value, stracpy(fc->values[item]));
- }
- }
-
- return true;
-}
-
-static bool
-input_get_property_size(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- args.rval().setInt32(fc->size);
-
- return true;
-}
-
-static bool
-input_get_property_src(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
- linknum = get_form_control_link(document, fc);
- /* Hiddens have no link. */
- if (linknum >= 0) link = &document->links[linknum];
-
- if (link && link->where_img) {
- args.rval().setString(JS_NewStringCopyZ(ctx, link->where_img));
- } else {
- args.rval().setUndefined();
- }
-
- return true;
-}
-
-static bool
-input_set_property_src(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
- return;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- linknum = get_form_control_link(document, fc);
- /* Hiddens have no link. */
- if (linknum >= 0) link = &document->links[linknum];
-
- if (link) {
- mem_free_set(&link->where_img, jsval_to_string(ctx, args[0]));
- }
-
- return true;
-}
-
-static bool
-input_get_property_tabIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- linknum = get_form_control_link(document, fc);
- /* Hiddens have no link. */
- if (linknum >= 0) link = &document->links[linknum];
-
- if (link) {
- /* FIXME: This is WRONG. --pasky */
- args.rval().setInt32(link->number);
- } else {
- args.rval().setUndefined();
- }
-
- return true;
-}
-
-static bool
-input_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- char *s = NULL;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- switch (fc->type) {
- case FC_TEXT: s = "text"; break;
- case FC_PASSWORD: s = "password"; break;
- case FC_FILE: s = "file"; break;
- case FC_CHECKBOX: s = "checkbox"; break;
- case FC_RADIO: s = "radio"; break;
- case FC_SUBMIT: s = "submit"; break;
- case FC_IMAGE: s = "image"; break;
- case FC_RESET: s = "reset"; break;
- case FC_BUTTON: s = "button"; break;
- case FC_HIDDEN: s = "hidden"; break;
- case FC_SELECT: s = "select"; break;
- default: INTERNAL("input_get_property() upon a non-input item."); break;
- }
- args.rval().setString(JS_NewStringCopyZ(ctx, s));
-
- return true;
-}
-
-static bool
-input_get_property_value(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct form_state *fs;
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
-
- args.rval().setString(JS_NewStringCopyZ(ctx, fs->value));
-
- return true;
-}
-
-static bool
-input_set_property_value(JSContext *ctx, unsigned int argc, JS::Value *vp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::CallArgs args = CallArgsFromVp(argc, vp);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- if (!vs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
- doc_view = vs->doc_view;
- document = doc_view->document;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
- fc = find_form_control(document, fs);
-
- assert(fc);
- assert(fc->form && fs);
-
- if (fc->type != FC_FILE) {
- mem_free_set(&fs->value, jsval_to_string(ctx, args[0]));
- if (fc->type == FC_TEXT || fc->type == FC_PASSWORD)
- fs->state = strlen(fs->value);
- }
-
- return true;
-}
-
-/* XXX: Some of those are marked readonly just because we can't change them
- * safely now. Changing default* values would affect all open instances of the
- * document, leading to a potential security risk. Changing size and type would
- * require re-rendering the document (TODO), tabindex would require renumbering
- * of all links and whatnot. --pasky */
-static JSPropertySpec input_props[] = {
- JS_PSGS("accessKey", input_get_property_accessKey, input_set_property_accessKey, JSPROP_ENUMERATE),
- JS_PSGS("alt", input_get_property_alt, input_set_property_alt, JSPROP_ENUMERATE),
- JS_PSGS("checked", input_get_property_checked, input_set_property_checked, JSPROP_ENUMERATE),
- JS_PSG("defaultChecked", input_get_property_defaultChecked, JSPROP_ENUMERATE),
- JS_PSG("defaultValue",input_get_property_defaultValue, JSPROP_ENUMERATE),
- JS_PSGS("disabled", input_get_property_disabled, input_set_property_disabled, JSPROP_ENUMERATE),
- JS_PSG("form", input_get_property_form, JSPROP_ENUMERATE),
- JS_PSGS("maxLength", input_get_property_maxLength, input_set_property_maxLength, JSPROP_ENUMERATE),
- JS_PSGS("name", input_get_property_name, input_set_property_name, JSPROP_ENUMERATE),
- JS_PSGS("readonly", input_get_property_readonly, input_set_property_readonly, JSPROP_ENUMERATE),
- JS_PSGS("selectedIndex", input_get_property_selectedIndex, input_set_property_selectedIndex, JSPROP_ENUMERATE),
- JS_PSG("size", input_get_property_size, JSPROP_ENUMERATE),
- JS_PSGS("src", input_get_property_src, input_set_property_src,JSPROP_ENUMERATE),
- JS_PSG("tabindex", input_get_property_tabIndex, JSPROP_ENUMERATE),
- JS_PSG("type", input_get_property_type, JSPROP_ENUMERATE),
- JS_PSGS("value", input_get_property_value, input_set_property_value, JSPROP_ENUMERATE),
- JS_PS_END
-};
-
-static bool input_blur(JSContext *ctx, unsigned int argc, JS::Value *rval);
-static bool input_click(JSContext *ctx, unsigned int argc, JS::Value *rval);
-static bool input_focus(JSContext *ctx, unsigned int argc, JS::Value *rval);
-static bool input_select(JSContext *ctx, unsigned int argc, JS::Value *rval);
-
-static const spidermonkeyFunctionSpec input_funcs[] = {
- { "blur", input_blur, 0 },
- { "click", input_click, 0 },
- { "focus", input_focus, 0 },
- { "select", input_select, 0 },
- { NULL }
-};
-
-static struct form_state *
-input_get_form_state(JSContext *ctx, JSObject *jsinput)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::RootedObject r_jsinput(ctx, jsinput);
- struct form_state *fs = JS_GetInstancePrivate(ctx, r_jsinput,
- &input_class,
- NULL);
-
- if (!fs) return NULL; /* detached */
-
- assert(fs->ecmascript_obj == jsinput);
- if_assert_failed return NULL;
-
- return fs;
-}
-
-/* @input_class.getProperty */
-static bool
-input_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::RootedObject parent_form(ctx); /* instance of @form_class */
- JS::RootedObject parent_doc(ctx); /* instance of @document_class */
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- hvp.setUndefined();
-
- return true;
-}
-
-/* @input_class.setProperty */
-static bool
-input_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- ELINKS_CAST_PROP_PARAMS
- jsid id = hid.get();
-
- JS::RootedObject parent_form(ctx); /* instance of @form_class */
- JS::RootedObject parent_doc(ctx); /* instance of @document_class */
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- struct link *link = NULL;
- unicode_val_T accesskey;
-
- /* This can be called if @obj if not itself an instance of the
- * appropriate class but has one in its prototype chain. Fail
- * such calls. */
- if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- return true;
-}
-
-/* @input_funcs{"blur"} */
-static bool
-input_blur(JSContext *ctx, unsigned int argc, JS::Value *rval)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- /* We are a text-mode browser and there *always* has to be something
- * selected. So we do nothing for now. (That was easy.) */
- return true;
-}
-
-/* @input_funcs{"click"} */
-static bool
-input_click(JSContext *ctx, unsigned int argc, JS::Value *rval)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::Value val;
- JS::RootedObject parent_form(ctx); /* instance of @form_class */
- JS::RootedObject parent_doc(ctx); /* instance of @document_class */
- JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct session *ses;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- if (!JS_InstanceOf(ctx, hobj, &input_class, &args)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- doc_view = vs->doc_view;
- document = doc_view->document;
- ses = doc_view->session;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
-
- 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 true;
-
- /* 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);
-
- args.rval().setBoolean(false);
-
- return true;
-}
-
-/* @input_funcs{"focus"} */
-static bool
-input_focus(JSContext *ctx, unsigned int argc, JS::Value *rval)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- JS::Value val;
- JS::RootedObject parent_form(ctx); /* instance of @form_class */
- JS::RootedObject parent_doc(ctx); /* instance of @document_class */
- JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
- JS::RootedObject hobj(ctx, &args.thisv().toObject());
-
- struct view_state *vs;
- struct document_view *doc_view;
- struct document *document;
- struct session *ses;
- struct form_state *fs;
- struct el_form_control *fc;
- int linknum;
- JS::Realm *comp = js::GetContextRealm(ctx);
-
- if (!comp) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
-
- if (!JS_InstanceOf(ctx, hobj, &input_class, &args)) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false;
- }
-
- vs = interpreter->vs;
- doc_view = vs->doc_view;
- document = doc_view->document;
- ses = doc_view->session;
- fs = input_get_form_state(ctx, hobj);
- if (!fs) {
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
-#endif
- return false; /* detached */
- }
-
- 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 true;
-
- jump_to_link_number(ses, doc_view, linknum);
-
- args.rval().setBoolean(false);
- return true;
-}
-
-/* @input_funcs{"select"} */
-static bool
-input_select(JSContext *ctx, unsigned int argc, JS::Value *rval)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- /* We support no text selecting yet. So we do nothing for now.
- * (That was easy, too.) */
- return true;
-}
-
-static JSObject *
-get_input_object(JSContext *ctx, struct form_state *fs)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
-
- JSObject *jsinput = fs->ecmascript_obj;
-
- if (jsinput) {
- JS::RootedObject r_jsinput(ctx, jsinput);
- /* This assumes JS_GetInstancePrivate cannot GC. */
- assert(JS_GetInstancePrivate(ctx, r_jsinput,
- &input_class, NULL)
- == fs);
- if_assert_failed return NULL;
-
- return jsinput;
- }
-
- /* 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 = JS_NewObject(ctx, &input_class);
- if (!jsinput)
- return NULL;
-
- JS::RootedObject r_jsinput(ctx, jsinput);
-
- JS_DefineProperties(ctx, r_jsinput, (JSPropertySpec *) input_props);
- spidermonkey_DefineFunctions(ctx, jsinput, input_funcs);
-
- JS_SetPrivate(jsinput, fs); /* to @input_class */
- fs->ecmascript_obj = jsinput;
-
- return jsinput;
-}
-
-static void
-input_finalize(JSFreeOp *op, JSObject *jsinput)
-{
-#ifdef ECMASCRIPT_DEBUG
- fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
-#endif
- struct form_state *fs = JS_GetPrivate(jsinput);
-
- if (fs) {
- /* If this assertion fails, leave fs->ecmascript_obj
- * unchanged, because it may point to a different
- * JSObject whose private pointer will later have to
- * be updated to avoid crashes. */
- assert(fs->ecmascript_obj == jsinput);
- if_assert_failed return;
-
- fs->ecmascript_obj = NULL;
- /* No need to JS_SetPrivate, because jsinput is being
- * destroyed. */
- }
-}
-
void
spidermonkey_detach_form_state(struct form_state *fs)
{
@@ -3965,8 +2061,7 @@ forms_namedItem(JSContext *ctx, unsigned int argc, JS::Value *vp)
return true;
}
-
-static JSString *
+JSString *
unicode_to_jsstring(JSContext *ctx, unicode_val_T u)
{
#ifdef ECMASCRIPT_DEBUG
diff --git a/src/ecmascript/spidermonkey/form.h b/src/ecmascript/spidermonkey/form.h
index 73dd7e6a..a9a4087a 100644
--- a/src/ecmascript/spidermonkey/form.h
+++ b/src/ecmascript/spidermonkey/form.h
@@ -1,4 +1,3 @@
-
#ifndef EL__ECMASCRIPT_SPIDERMONKEY_FORM_H
#define EL__ECMASCRIPT_SPIDERMONKEY_FORM_H
@@ -6,6 +5,7 @@
struct form;
+extern JSClass form_class;
extern JSClass forms_class;
extern const spidermonkeyFunctionSpec forms_funcs[];
extern JSPropertySpec forms_props[];
@@ -13,4 +13,6 @@ extern JSPropertySpec forms_props[];
JSObject *get_form_object(JSContext *ctx, JSObject *jsdoc, struct form *form);
JSObject *getForms(JSContext *ctx, void *node);
+JSString *unicode_to_jsstring(JSContext *ctx, unicode_val_T u);
+
#endif
diff --git a/src/ecmascript/spidermonkey/input.c b/src/ecmascript/spidermonkey/input.c
new file mode 100644
index 00000000..7b728667
--- /dev/null
+++ b/src/ecmascript/spidermonkey/input.c
@@ -0,0 +1,1957 @@
+/* The SpiderMonkey window object implementation. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+
+#include "elinks.h"
+
+#include "ecmascript/spidermonkey/util.h"
+#include
+
+#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/spidermonkey.h"
+#include "ecmascript/spidermonkey/document.h"
+#include "ecmascript/spidermonkey/form.h"
+#include "ecmascript/spidermonkey/input.h"
+#include "ecmascript/spidermonkey/window.h"
+#include "intl/libintl.h"
+#include "main/select.h"
+#include "osdep/newwin.h"
+#include "osdep/sysname.h"
+#include "protocol/http/http.h"
+#include "protocol/uri.h"
+#include "session/history.h"
+#include "session/location.h"
+#include "session/session.h"
+#include "session/task.h"
+#include "terminal/tab.h"
+#include "terminal/terminal.h"
+#include "util/conv.h"
+#include "util/memory.h"
+#include "util/string.h"
+#include "viewer/text/draw.h"
+#include "viewer/text/form.h"
+#include "viewer/text/link.h"
+#include "viewer/text/vs.h"
+
+#include
+
+/* Accordingly to the JS specs, each input type should own object. That'd be a
+ * huge PITA though, however DOM comes to the rescue and defines just a single
+ * HTMLInputElement. The difference could be spotted only by some clever tricky
+ * JS code, but I hope it doesn't matter anywhere. --pasky */
+
+static bool input_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
+static bool input_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
+static void input_finalize(JSFreeOp *op, JSObject *obj);
+
+static JSClassOps input_ops = {
+ nullptr, // addProperty
+ nullptr, // deleteProperty
+ nullptr, // enumerate
+ nullptr, // newEnumerate
+ nullptr, // resolve
+ nullptr, // mayResolve
+ input_finalize, // finalize
+ nullptr, // call
+ nullptr, // hasInstance
+ nullptr, // construct
+ JS_GlobalObjectTraceHook
+};
+
+/* Each @input_class object must have a @form_class parent. */
+static JSClass input_class = {
+ "input", /* here, we unleash ourselves */
+ JSCLASS_HAS_PRIVATE, /* struct form_state *, or NULL if detached */
+ &input_ops
+};
+
+/* Tinyids of properties. Use negative values to distinguish these
+ * from array indexes (even though this object has no array elements).
+ * ECMAScript code should not use these directly as in input[-1];
+ * future versions of ELinks may change the numbers. */
+enum input_prop {
+ JSP_INPUT_ACCESSKEY = -1,
+ JSP_INPUT_ALT = -2,
+ JSP_INPUT_CHECKED = -3,
+ JSP_INPUT_DEFAULT_CHECKED = -4,
+ JSP_INPUT_DEFAULT_VALUE = -5,
+ JSP_INPUT_DISABLED = -6,
+ JSP_INPUT_FORM = -7,
+ JSP_INPUT_MAX_LENGTH = -8,
+ JSP_INPUT_NAME = -9,
+ JSP_INPUT_READONLY = -10,
+ JSP_INPUT_SELECTED_INDEX = -11,
+ JSP_INPUT_SIZE = -12,
+ JSP_INPUT_SRC = -13,
+ JSP_INPUT_TABINDEX = -14,
+ JSP_INPUT_TYPE = -15,
+ JSP_INPUT_VALUE = -16,
+};
+
+static JSString *unicode_to_jsstring(JSContext *ctx, unicode_val_T u);
+static unicode_val_T jsval_to_accesskey(JSContext *ctx, JS::MutableHandleValue hvp);
+static struct form_state *input_get_form_state(JSContext *ctx, JSObject *jsinput);
+
+
+static bool
+input_get_property_accessKey(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ JSString *keystr;
+
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ linknum = get_form_control_link(document, fc);
+ /* Hiddens have no link. */
+ if (linknum >= 0) link = &document->links[linknum];
+
+ if (!link) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ if (!link->accesskey) {
+ args.rval().set(JS_GetEmptyStringValue(ctx));
+ } else {
+ keystr = unicode_to_jsstring(ctx, link->accesskey);
+ if (keystr) {
+ args.rval().setString(keystr);
+ }
+ else {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
+input_set_property_accessKey(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ unicode_val_T accesskey;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ linknum = get_form_control_link(document, fc);
+ /* Hiddens have no link. */
+ if (linknum >= 0) link = &document->links[linknum];
+
+// accesskey = jsval_to_accesskey(ctx, args[0]);
+
+ size_t len;
+ char16_t chr[2];
+
+ accesskey = UCS_NO_CHAR;
+
+ if (!args[0].isString()) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ JSString *str = args[0].toString();
+
+ len = JS_GetStringLength(str);
+
+ /* This implementation ignores extra characters in the string. */
+ if (len < 1) {
+ accesskey = 0; /* which means no access key */
+ } else if (len == 1) {
+ JS_GetStringCharAt(ctx, str, 0, &chr[0]);
+ if (!is_utf16_surrogate(chr[0])) {
+ accesskey = chr[0];
+ }
+ } else {
+ JS_GetStringCharAt(ctx, str, 1, &chr[1]);
+ if (is_utf16_high_surrogate(chr[0])
+ && is_utf16_low_surrogate(chr[1])) {
+ accesskey = join_utf16_surrogates(chr[0], chr[1]);
+ }
+ }
+ if (accesskey == UCS_NO_CHAR) {
+ JS_ReportErrorUTF8(ctx, "Invalid UTF-16 sequence");
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ if (link) {
+ link->accesskey = accesskey;
+ }
+
+ return true;
+}
+
+static bool
+input_get_property_alt(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ args.rval().setString(JS_NewStringCopyZ(ctx, fc->alt));
+
+ return true;
+}
+
+static bool
+input_set_property_alt(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ mem_free_set(&fc->alt, jsval_to_string(ctx, args[0]));
+
+ return true;
+}
+
+static bool
+input_get_property_checked(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct form_state *fs;
+
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+
+ args.rval().setBoolean(fs->state);
+
+ return true;
+}
+
+static bool
+input_set_property_checked(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO)
+ return true;
+ fs->state = args[0].toBoolean();
+
+ return true;
+}
+
+static bool
+input_get_property_defaultChecked(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ args.rval().setBoolean(fc->default_state);
+
+ return true;
+}
+
+static bool
+input_get_property_defaultValue(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ /* FIXME (bug 805): convert from the charset of the document */
+ args.rval().setString(JS_NewStringCopyZ(ctx, fc->default_value));
+
+ return true;
+}
+
+static bool
+input_get_property_disabled(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ /* FIXME: --pasky */
+ args.rval().setBoolean(fc->mode == FORM_MODE_DISABLED);
+
+ return true;
+}
+
+static bool
+input_set_property_disabled(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ /* FIXME: --pasky */
+ fc->mode = (args[0].toBoolean() ? FORM_MODE_DISABLED
+ : fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY
+ : FORM_MODE_NORMAL);
+
+ return true;
+}
+
+static bool
+input_get_property_form(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ JS::RootedObject parent_form(ctx, JS::GetNonCCWObjectGlobal(hobj));
+ assert(JS_InstanceOf(ctx, parent_form, &form_class, NULL));
+ if_assert_failed {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ args.rval().setObject(*parent_form);
+
+ return true;
+}
+
+static bool
+input_get_property_maxLength(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ args.rval().setInt32(fc->maxlength);
+
+ return true;
+}
+
+static bool
+input_set_property_maxLength(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ fc->maxlength = args[0].toInt32();
+
+ return true;
+}
+
+static bool
+input_get_property_name(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ args.rval().setString(JS_NewStringCopyZ(ctx, fc->name));
+
+ return true;
+}
+
+/* @input_class.setProperty */
+static bool
+input_set_property_name(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ mem_free_set(&fc->name, jsval_to_string(ctx, args[0]));
+
+ return true;
+}
+
+static bool
+input_get_property_readonly(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ /* FIXME: --pasky */
+ args.rval().setBoolean(fc->mode == FORM_MODE_READONLY);
+
+ return true;
+}
+
+/* @input_class.setProperty */
+static bool
+input_set_property_readonly(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ /* FIXME: --pasky */
+ fc->mode = (args[0].toBoolean() ? FORM_MODE_READONLY
+ : fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED
+ : FORM_MODE_NORMAL);
+
+ return true;
+}
+
+static bool
+input_get_property_selectedIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ if (fc->type == FC_SELECT) {
+ args.rval().setInt32(fs->state);
+ }
+ else {
+ args.rval().setUndefined();
+ }
+
+ return true;
+}
+
+/* @input_class.setProperty */
+static bool
+input_set_property_selectedIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ if (fc->type == FC_SELECT) {
+ int item = args[0].toInt32();
+
+ if (item >= 0 && item < fc->nvalues) {
+ fs->state = item;
+ mem_free_set(&fs->value, stracpy(fc->values[item]));
+ }
+ }
+
+ return true;
+}
+
+static bool
+input_get_property_size(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ args.rval().setInt32(fc->size);
+
+ return true;
+}
+
+static bool
+input_get_property_src(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+ linknum = get_form_control_link(document, fc);
+ /* Hiddens have no link. */
+ if (linknum >= 0) link = &document->links[linknum];
+
+ if (link && link->where_img) {
+ args.rval().setString(JS_NewStringCopyZ(ctx, link->where_img));
+ } else {
+ args.rval().setUndefined();
+ }
+
+ return true;
+}
+
+static bool
+input_set_property_src(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+ return;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ linknum = get_form_control_link(document, fc);
+ /* Hiddens have no link. */
+ if (linknum >= 0) link = &document->links[linknum];
+
+ if (link) {
+ mem_free_set(&link->where_img, jsval_to_string(ctx, args[0]));
+ }
+
+ return true;
+}
+
+static bool
+input_get_property_tabIndex(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ linknum = get_form_control_link(document, fc);
+ /* Hiddens have no link. */
+ if (linknum >= 0) link = &document->links[linknum];
+
+ if (link) {
+ /* FIXME: This is WRONG. --pasky */
+ args.rval().setInt32(link->number);
+ } else {
+ args.rval().setUndefined();
+ }
+
+ return true;
+}
+
+static bool
+input_get_property_type(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ char *s = NULL;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ switch (fc->type) {
+ case FC_TEXT: s = "text"; break;
+ case FC_PASSWORD: s = "password"; break;
+ case FC_FILE: s = "file"; break;
+ case FC_CHECKBOX: s = "checkbox"; break;
+ case FC_RADIO: s = "radio"; break;
+ case FC_SUBMIT: s = "submit"; break;
+ case FC_IMAGE: s = "image"; break;
+ case FC_RESET: s = "reset"; break;
+ case FC_BUTTON: s = "button"; break;
+ case FC_HIDDEN: s = "hidden"; break;
+ case FC_SELECT: s = "select"; break;
+ default: INTERNAL("input_get_property() upon a non-input item."); break;
+ }
+ args.rval().setString(JS_NewStringCopyZ(ctx, s));
+
+ return true;
+}
+
+static bool
+input_get_property_value(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct form_state *fs;
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+
+ args.rval().setString(JS_NewStringCopyZ(ctx, fs->value));
+
+ return true;
+}
+
+static bool
+input_set_property_value(JSContext *ctx, unsigned int argc, JS::Value *vp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ if (!vs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+ fc = find_form_control(document, fs);
+
+ assert(fc);
+ assert(fc->form && fs);
+
+ if (fc->type != FC_FILE) {
+ mem_free_set(&fs->value, jsval_to_string(ctx, args[0]));
+ if (fc->type == FC_TEXT || fc->type == FC_PASSWORD)
+ fs->state = strlen(fs->value);
+ }
+
+ return true;
+}
+
+/* XXX: Some of those are marked readonly just because we can't change them
+ * safely now. Changing default* values would affect all open instances of the
+ * document, leading to a potential security risk. Changing size and type would
+ * require re-rendering the document (TODO), tabindex would require renumbering
+ * of all links and whatnot. --pasky */
+static JSPropertySpec input_props[] = {
+ JS_PSGS("accessKey", input_get_property_accessKey, input_set_property_accessKey, JSPROP_ENUMERATE),
+ JS_PSGS("alt", input_get_property_alt, input_set_property_alt, JSPROP_ENUMERATE),
+ JS_PSGS("checked", input_get_property_checked, input_set_property_checked, JSPROP_ENUMERATE),
+ JS_PSG("defaultChecked", input_get_property_defaultChecked, JSPROP_ENUMERATE),
+ JS_PSG("defaultValue",input_get_property_defaultValue, JSPROP_ENUMERATE),
+ JS_PSGS("disabled", input_get_property_disabled, input_set_property_disabled, JSPROP_ENUMERATE),
+ JS_PSG("form", input_get_property_form, JSPROP_ENUMERATE),
+ JS_PSGS("maxLength", input_get_property_maxLength, input_set_property_maxLength, JSPROP_ENUMERATE),
+ JS_PSGS("name", input_get_property_name, input_set_property_name, JSPROP_ENUMERATE),
+ JS_PSGS("readonly", input_get_property_readonly, input_set_property_readonly, JSPROP_ENUMERATE),
+ JS_PSGS("selectedIndex", input_get_property_selectedIndex, input_set_property_selectedIndex, JSPROP_ENUMERATE),
+ JS_PSG("size", input_get_property_size, JSPROP_ENUMERATE),
+ JS_PSGS("src", input_get_property_src, input_set_property_src,JSPROP_ENUMERATE),
+ JS_PSG("tabindex", input_get_property_tabIndex, JSPROP_ENUMERATE),
+ JS_PSG("type", input_get_property_type, JSPROP_ENUMERATE),
+ JS_PSGS("value", input_get_property_value, input_set_property_value, JSPROP_ENUMERATE),
+ JS_PS_END
+};
+
+static bool input_blur(JSContext *ctx, unsigned int argc, JS::Value *rval);
+static bool input_click(JSContext *ctx, unsigned int argc, JS::Value *rval);
+static bool input_focus(JSContext *ctx, unsigned int argc, JS::Value *rval);
+static bool input_select(JSContext *ctx, unsigned int argc, JS::Value *rval);
+
+static const spidermonkeyFunctionSpec input_funcs[] = {
+ { "blur", input_blur, 0 },
+ { "click", input_click, 0 },
+ { "focus", input_focus, 0 },
+ { "select", input_select, 0 },
+ { NULL }
+};
+
+static struct form_state *
+input_get_form_state(JSContext *ctx, JSObject *jsinput)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::RootedObject r_jsinput(ctx, jsinput);
+ struct form_state *fs = JS_GetInstancePrivate(ctx, r_jsinput,
+ &input_class,
+ NULL);
+
+ if (!fs) return NULL; /* detached */
+
+ assert(fs->ecmascript_obj == jsinput);
+ if_assert_failed return NULL;
+
+ return fs;
+}
+
+/* @input_class.getProperty */
+static bool
+input_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::RootedObject parent_form(ctx); /* instance of @form_class */
+ JS::RootedObject parent_doc(ctx); /* instance of @document_class */
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ hvp.setUndefined();
+
+ return true;
+}
+
+/* @input_class.setProperty */
+static bool
+input_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ ELINKS_CAST_PROP_PARAMS
+ jsid id = hid.get();
+
+ JS::RootedObject parent_form(ctx); /* instance of @form_class */
+ JS::RootedObject parent_doc(ctx); /* instance of @document_class */
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ struct link *link = NULL;
+ unicode_val_T accesskey;
+
+ /* This can be called if @obj if not itself an instance of the
+ * appropriate class but has one in its prototype chain. Fail
+ * such calls. */
+ if (!JS_InstanceOf(ctx, hobj, &input_class, NULL)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ return true;
+}
+
+/* @input_funcs{"blur"} */
+static bool
+input_blur(JSContext *ctx, unsigned int argc, JS::Value *rval)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ /* We are a text-mode browser and there *always* has to be something
+ * selected. So we do nothing for now. (That was easy.) */
+ return true;
+}
+
+/* @input_funcs{"click"} */
+static bool
+input_click(JSContext *ctx, unsigned int argc, JS::Value *rval)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::Value val;
+ JS::RootedObject parent_form(ctx); /* instance of @form_class */
+ JS::RootedObject parent_doc(ctx); /* instance of @document_class */
+ JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct session *ses;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ if (!JS_InstanceOf(ctx, hobj, &input_class, &args)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ ses = doc_view->session;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+
+ 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 true;
+
+ /* 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);
+
+ args.rval().setBoolean(false);
+
+ return true;
+}
+
+/* @input_funcs{"focus"} */
+static bool
+input_focus(JSContext *ctx, unsigned int argc, JS::Value *rval)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ JS::Value val;
+ JS::RootedObject parent_form(ctx); /* instance of @form_class */
+ JS::RootedObject parent_doc(ctx); /* instance of @document_class */
+ JS::CallArgs args = JS::CallArgsFromVp(argc, rval);
+ JS::RootedObject hobj(ctx, &args.thisv().toObject());
+
+ struct view_state *vs;
+ struct document_view *doc_view;
+ struct document *document;
+ struct session *ses;
+ struct form_state *fs;
+ struct el_form_control *fc;
+ int linknum;
+ JS::Realm *comp = js::GetContextRealm(ctx);
+
+ if (!comp) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ struct ecmascript_interpreter *interpreter = JS::GetRealmPrivate(comp);
+
+ if (!JS_InstanceOf(ctx, hobj, &input_class, &args)) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false;
+ }
+
+ vs = interpreter->vs;
+ doc_view = vs->doc_view;
+ document = doc_view->document;
+ ses = doc_view->session;
+ fs = input_get_form_state(ctx, hobj);
+ if (!fs) {
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
+#endif
+ return false; /* detached */
+ }
+
+ 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 true;
+
+ jump_to_link_number(ses, doc_view, linknum);
+
+ args.rval().setBoolean(false);
+ return true;
+}
+
+/* @input_funcs{"select"} */
+static bool
+input_select(JSContext *ctx, unsigned int argc, JS::Value *rval)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ /* We support no text selecting yet. So we do nothing for now.
+ * (That was easy, too.) */
+ return true;
+}
+
+JSObject *
+get_input_object(JSContext *ctx, struct form_state *fs)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+
+ JSObject *jsinput = fs->ecmascript_obj;
+
+ if (jsinput) {
+ JS::RootedObject r_jsinput(ctx, jsinput);
+ /* This assumes JS_GetInstancePrivate cannot GC. */
+ assert(JS_GetInstancePrivate(ctx, r_jsinput,
+ &input_class, NULL)
+ == fs);
+ if_assert_failed return NULL;
+
+ return jsinput;
+ }
+
+ /* 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 = JS_NewObject(ctx, &input_class);
+ if (!jsinput)
+ return NULL;
+
+ JS::RootedObject r_jsinput(ctx, jsinput);
+
+ JS_DefineProperties(ctx, r_jsinput, (JSPropertySpec *) input_props);
+ spidermonkey_DefineFunctions(ctx, jsinput, input_funcs);
+
+ JS_SetPrivate(jsinput, fs); /* to @input_class */
+ fs->ecmascript_obj = jsinput;
+
+ return jsinput;
+}
+
+static void
+input_finalize(JSFreeOp *op, JSObject *jsinput)
+{
+#ifdef ECMASCRIPT_DEBUG
+ fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
+#endif
+ struct form_state *fs = JS_GetPrivate(jsinput);
+
+ if (fs) {
+ /* If this assertion fails, leave fs->ecmascript_obj
+ * unchanged, because it may point to a different
+ * JSObject whose private pointer will later have to
+ * be updated to avoid crashes. */
+ assert(fs->ecmascript_obj == jsinput);
+ if_assert_failed return;
+
+ fs->ecmascript_obj = NULL;
+ /* No need to JS_SetPrivate, because jsinput is being
+ * destroyed. */
+ }
+}
+
diff --git a/src/ecmascript/spidermonkey/input.h b/src/ecmascript/spidermonkey/input.h
new file mode 100644
index 00000000..742029c3
--- /dev/null
+++ b/src/ecmascript/spidermonkey/input.h
@@ -0,0 +1,10 @@
+#ifndef EL__ECMASCRIPT_SPIDERMONKEY_INPUT_H
+#define EL__ECMASCRIPT_SPIDERMONKEY_INPUT_H
+
+#include "ecmascript/spidermonkey/util.h"
+
+struct form_state;
+
+JSObject *get_input_object(JSContext *ctx, struct form_state *fs);
+
+#endif
diff --git a/src/ecmascript/spidermonkey/meson.build b/src/ecmascript/spidermonkey/meson.build
index 21fa63ee..204bbef1 100644
--- a/src/ecmascript/spidermonkey/meson.build
+++ b/src/ecmascript/spidermonkey/meson.build
@@ -1,3 +1,3 @@
#INCLUDES += $(SPIDERMONKEY_CFLAGS)
-srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'document.c', 'element.c', 'form.c', 'heartbeat.c', 'history.c', 'implementation.c', 'location.c', 'localstorage.c', 'navigator.c', 'nodelist.c', 'screen.c', 'unibar.c', 'window.c')
+srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'document.c', 'element.c', 'form.c', 'heartbeat.c', 'history.c', 'implementation.c', 'input.c', 'location.c', 'localstorage.c', 'navigator.c', 'nodelist.c', 'screen.c', 'unibar.c', 'window.c')