1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

[quickjs] forms also as array

Sometimes it works, sometimes not.
This commit is contained in:
Witold Filipczyk 2021-11-15 17:13:51 +01:00
parent be2a4d83b1
commit 98b3f14927
5 changed files with 77 additions and 52 deletions

View File

@ -213,6 +213,7 @@ struct document {
int ecmascript_counter; int ecmascript_counter;
void *dom; void *dom;
char *text; char *text;
void *forms_nodeset;
#endif #endif
#ifdef CONFIG_CSS #ifdef CONFIG_CSS
/** @todo FIXME: We should externally maybe using cache_entry store the /** @todo FIXME: We should externally maybe using cache_entry store the

View File

@ -21,5 +21,10 @@ int quickjs_eval_boolback(struct ecmascript_interpreter *interpreter, struct str
void quickjs_call_function(struct ecmascript_interpreter *interpreter, JSValueConst fun, struct string *ret); void quickjs_call_function(struct ecmascript_interpreter *interpreter, JSValueConst fun, struct string *ret);
inline int operator<(JSValueConst a, JSValueConst b)
{
return JS_VALUE_GET_PTR(a) < JS_VALUE_GET_PTR(b);
}
extern struct module quickjs_module; extern struct module quickjs_module;
#endif #endif

View File

@ -450,12 +450,19 @@ js_document_get_property_forms(JSContext *ctx, JSValueConst this_val)
if (!document->dom) { if (!document->dom) {
return JS_NULL; return JS_NULL;
} }
if (!document->forms_nodeset) {
document->forms_nodeset = new xmlpp::Node::NodeSet;
}
if (!document->forms_nodeset) {
return JS_NULL;
}
xmlpp::Document *docu = (xmlpp::Document *)document->dom; xmlpp::Document *docu = (xmlpp::Document *)document->dom;
xmlpp::Element* root = (xmlpp::Element *)docu->get_root_node(); xmlpp::Element* root = (xmlpp::Element *)docu->get_root_node();
xmlpp::ustring xpath = "//form"; xmlpp::ustring xpath = "//form";
xmlpp::Node::NodeSet *elements = new xmlpp::Node::NodeSet; xmlpp::Node::NodeSet *elements = static_cast<xmlpp::Node::NodeSet *>(document->forms_nodeset);
*elements = root->find(xpath); *elements = root->find(xpath);
if (elements->size() == 0) { if (elements->size() == 0) {

View File

@ -51,14 +51,10 @@
#define countof(x) (sizeof(x) / sizeof((x)[0])) #define countof(x) (sizeof(x) / sizeof((x)[0]))
static int operator<(JSValueConst a, JSValueConst b)
{
return JS_VALUE_GET_PTR(a) < JS_VALUE_GET_PTR(b);
}
static JSClassID js_form_class_id;
static std::map<struct form_view *, JSValueConst> map_form_elements; static std::map<struct form_view *, JSValueConst> map_form_elements;
static std::map<JSValueConst, struct form_view *> map_elements_form; static std::map<JSValueConst, struct form_view *> map_elements_form;
static std::map<struct form *, JSValueConst> map_form;
static std::map<JSValueConst, struct form *> map_rev_form;
JSValue getForm(JSContext *ctx, struct form *form); JSValue getForm(JSContext *ctx, struct form *form);
@ -78,6 +74,22 @@ setOpaque(JSValueConst this_val, struct form_view *fv)
} }
} }
static struct form *
form_GetOpaque(JSValueConst this_val)
{
return map_rev_form[this_val];
}
static void
form_SetOpaque(JSValueConst this_val, struct form *form)
{
if (!form) {
map_rev_form.erase(this_val);
} else {
map_rev_form[this_val] = form;
}
}
static JSValue static JSValue
js_get_form_control_object(JSContext *ctx, js_get_form_control_object(JSContext *ctx,
enum form_type type, struct form_state *fs) enum form_type type, struct form_state *fs)
@ -234,7 +246,6 @@ js_form_elements_get_property_length(JSContext *ctx, JSValueConst this_val)
#endif #endif
return JS_UNDEFINED; /* detached */ return JS_UNDEFINED; /* detached */
} }
form = find_form_by_form_view(document, form_view); form = find_form_by_form_view(document, form_view);
return JS_NewInt32(ctx, list_size(&form->items)); return JS_NewInt32(ctx, list_size(&form->items));
@ -399,7 +410,7 @@ js_form_get_property_action(JSContext *ctx, JSValueConst this_val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
return JS_NewString(ctx, form->action); return JS_NewString(ctx, form->action);
@ -424,7 +435,7 @@ js_form_set_property_action(JSContext *ctx, JSValueConst this_val, JSValue val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
const char *str; const char *str;
@ -548,7 +559,7 @@ js_form_get_property_encoding(JSContext *ctx, JSValueConst this_val)
return JS_NULL; return JS_NULL;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
switch (form->method) { switch (form->method) {
@ -584,7 +595,7 @@ js_form_set_property_encoding(JSContext *ctx, JSValueConst this_val, JSValue val
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
const char *str; const char *str;
size_t len; size_t len;
@ -628,7 +639,7 @@ js_form_get_property_length(JSContext *ctx, JSValueConst this_val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
return JS_NewInt32(ctx, list_size(&form->items)); return JS_NewInt32(ctx, list_size(&form->items));
@ -654,7 +665,7 @@ js_form_get_property_method(JSContext *ctx, JSValueConst this_val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
switch (form->method) { switch (form->method) {
@ -691,7 +702,7 @@ js_form_set_property_method(JSContext *ctx, JSValueConst this_val, JSValue val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
const char *str; const char *str;
char *string; char *string;
@ -733,7 +744,7 @@ js_form_get_property_name(JSContext *ctx, JSValueConst this_val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
return JS_NewString(ctx, form->name); return JS_NewString(ctx, form->name);
@ -761,7 +772,7 @@ js_form_set_property_name(JSContext *ctx, JSValueConst this_val, JSValue val)
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
const char *str; const char *str;
@ -797,7 +808,7 @@ js_form_get_property_target(JSContext *ctx, JSValueConst this_val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
return JS_NewString(ctx, form->target); return JS_NewString(ctx, form->target);
@ -823,7 +834,7 @@ js_form_set_property_target(JSContext *ctx, JSValueConst this_val, JSValue val)
return JS_UNDEFINED; return JS_UNDEFINED;
} }
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
const char *str; const char *str;
@ -853,7 +864,7 @@ js_form_reset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *arg
struct ecmascript_interpreter *interpreter = JS_GetContextOpaque(ctx); struct ecmascript_interpreter *interpreter = JS_GetContextOpaque(ctx);
vs = interpreter->vs; vs = interpreter->vs;
doc_view = vs->doc_view; doc_view = vs->doc_view;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
do_reset_form(doc_view, form); do_reset_form(doc_view, form);
@ -879,7 +890,7 @@ js_form_submit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *ar
doc_view = vs->doc_view; doc_view = vs->doc_view;
ses = doc_view->session; ses = doc_view->session;
form = JS_GetOpaque(this_val, js_form_class_id); form = form_GetOpaque(this_val);
assert(form); assert(form);
submit_given_form(ses, doc_view, form, 0); submit_given_form(ses, doc_view, form, 0);
@ -956,13 +967,13 @@ static const JSCFunctionListEntry js_form_proto_funcs[] = {
JS_CFUNC_DEF("submit", 0, js_form_submit), JS_CFUNC_DEF("submit", 0, js_form_submit),
}; };
static std::map<struct form *, JSValueConst> map_form;
static static
void js_form_finalizer(JSRuntime *rt, JSValue val) void js_form_finalizer(JSRuntime *rt, JSValue val)
{ {
struct form *form = JS_GetOpaque(val, js_form_class_id); struct form *form = form_GetOpaque(val);
form_SetOpaque(val, nullptr);
form->ecmascript_obj = JS_NULL; form->ecmascript_obj = JS_NULL;
map_form.erase(form); map_form.erase(form);
} }
@ -972,6 +983,7 @@ static JSClassDef js_form_class = {
js_form_finalizer js_form_finalizer
}; };
#if 0
static JSValue static JSValue
js_form_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) js_form_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
{ {
@ -1017,6 +1029,7 @@ js_form_init(JSContext *ctx, JSValue global_obj)
JS_SetPropertyStr(ctx, global_obj, "form", form_proto); JS_SetPropertyStr(ctx, global_obj, "form", form_proto);
return 0; return 0;
} }
#endif
JSValue JSValue
getForm(JSContext *ctx, struct form *form) getForm(JSContext *ctx, struct form *form)
@ -1029,18 +1042,10 @@ getForm(JSContext *ctx, struct form *form)
if (node_find != map_form.end()) { if (node_find != map_form.end()) {
return JS_DupValue(ctx, node_find->second); return JS_DupValue(ctx, node_find->second);
} }
static int initialized; JSValue form_obj = JS_NewArray(ctx);
/* create the element class */
if (!initialized) {
JS_NewClassID(&js_form_class_id);
JS_NewClass(JS_GetRuntime(ctx), js_form_class_id, &js_form_class);
initialized = 1;
}
JSValue form_obj = JS_NewObjectClass(ctx, js_form_class_id);
JS_SetPropertyFunctionList(ctx, form_obj, js_form_proto_funcs, countof(js_form_proto_funcs)); JS_SetPropertyFunctionList(ctx, form_obj, js_form_proto_funcs, countof(js_form_proto_funcs));
JS_SetClassProto(ctx, js_form_class_id, form_obj); form_SetOpaque(form_obj, form);
JS_SetOpaque(form_obj, form);
js_form_set_items2(ctx, form_obj, form); js_form_set_items2(ctx, form_obj, form);
form->ecmascript_obj = form_obj; form->ecmascript_obj = form_obj;

View File

@ -51,7 +51,24 @@
#define countof(x) (sizeof(x) / sizeof((x)[0])) #define countof(x) (sizeof(x) / sizeof((x)[0]))
static JSClassID js_forms_class_id; static std::map<void *, JSValueConst> map_forms;
static std::map<JSValueConst, void *> map_rev_forms;
static void *
forms_GetOpaque(JSValueConst this_val)
{
return map_rev_forms[this_val];
}
static void
forms_SetOpaque(JSValueConst this_val, void *node)
{
if (!node) {
map_rev_forms.erase(this_val);
} else {
map_rev_forms[this_val] = node;
}
}
/* Find the form whose name is @name, which should normally be a /* Find the form whose name is @name, which should normally be a
* string (but might not be). */ * string (but might not be). */
@ -273,22 +290,21 @@ static const JSCFunctionListEntry js_forms_proto_funcs[] = {
JS_CFUNC_DEF("namedItem", 1, js_forms_namedItem), JS_CFUNC_DEF("namedItem", 1, js_forms_namedItem),
}; };
static std::map<void *, JSValueConst> map_forms;
static static
void js_forms_finalizer(JSRuntime *rt, JSValue val) void js_forms_finalizer(JSRuntime *rt, JSValue val)
{ {
void *node = JS_GetOpaque(val, js_forms_class_id); void *node = forms_GetOpaque(val);
map_forms.erase(node); map_forms.erase(node);
forms_SetOpaque(val, nullptr);
} }
static JSClassDef js_forms_class = { static JSClassDef js_forms_class = {
"forms", "forms",
js_forms_finalizer js_forms_finalizer
}; };
#if 0
static JSValue static JSValue
js_forms_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) js_forms_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
{ {
@ -334,6 +350,7 @@ js_forms_init(JSContext *ctx, JSValue global_obj)
JS_SetPropertyStr(ctx, global_obj, "forms", forms_proto); JS_SetPropertyStr(ctx, global_obj, "forms", forms_proto);
return 0; return 0;
} }
#endif
JSValue JSValue
getForms(JSContext *ctx, void *node) getForms(JSContext *ctx, void *node)
@ -346,20 +363,10 @@ getForms(JSContext *ctx, void *node)
if (node_find != map_forms.end()) { if (node_find != map_forms.end()) {
return JS_DupValue(ctx, node_find->second); return JS_DupValue(ctx, node_find->second);
} }
static int initialized; JSValue forms_obj = JS_NewArray(ctx);
/* create the element class */
if (!initialized) {
JS_NewClassID(&js_forms_class_id);
JS_NewClass(JS_GetRuntime(ctx), js_forms_class_id, &js_forms_class);
initialized = 1;
}
JSValue forms_obj = JS_NewObjectClass(ctx, js_forms_class_id);
JS_SetPropertyFunctionList(ctx, forms_obj, js_forms_proto_funcs, countof(js_forms_proto_funcs)); JS_SetPropertyFunctionList(ctx, forms_obj, js_forms_proto_funcs, countof(js_forms_proto_funcs));
JS_SetClassProto(ctx, js_forms_class_id, forms_obj); forms_SetOpaque(forms_obj, node);
JS_SetOpaque(forms_obj, node);
js_forms_set_items(ctx, forms_obj, node); js_forms_set_items(ctx, forms_obj, node);
map_forms[node] = forms_obj; map_forms[node] = forms_obj;
return JS_DupValue(ctx, forms_obj); return JS_DupValue(ctx, forms_obj);