From 3f0ef28f3398b65daad21e5fe70cdc1ac42d6a16 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Fri, 17 Sep 2021 18:28:40 +0200 Subject: [PATCH] [htmlCollection] set_items --- src/ecmascript/spidermonkey/element.c | 80 +++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/ecmascript/spidermonkey/element.c b/src/ecmascript/spidermonkey/element.c index 889930af..53252dca 100644 --- a/src/ecmascript/spidermonkey/element.c +++ b/src/ecmascript/spidermonkey/element.c @@ -55,6 +55,8 @@ #include #include +static bool htmlCollection_set_items(JSContext *ctx, JS::HandleObject hobj, void *node); + static bool element_get_property_attributes(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_children(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_childElementCount(JSContext *ctx, unsigned int argc, JS::Value *vp); @@ -3277,6 +3279,83 @@ htmlCollection_namedItem2(JSContext *ctx, JS::HandleObject hobj, char *str, JS:: return true; } +static bool +htmlCollection_set_items(JSContext *ctx, JS::HandleObject hobj, void *node) +{ +#ifdef ECMASCRIPT_DEBUG + fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); +#endif + struct view_state *vs; + struct document_view *doc_view; + struct document *document; + struct form_view *form_view; + struct form *form; + + 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, &htmlCollection_class, NULL)) { +#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; + + int counter = 0; + + xmlpp::Node::NodeSet *ns = JS_GetPrivate(hobj); + + if (!ns) { + return true; + } + + xmlpp::Element *element; + + while (1) { + try { + element = ns->at(counter); + } catch (std::out_of_range e) { return true;} + + if (!element) { + return true; + } + + JSObject *obj = getElement(ctx, element); + + if (!obj) { + continue; + } + JS::RootedObject v(ctx, obj); + JS::RootedValue ro(ctx, JS::ObjectOrNullValue(v)); + JS_SetElement(ctx, hobj, counter, ro); + + xmlpp::ustring name = element->get_attribute_value("id"); + if (name == "") { + name = element->get_attribute_value("name"); + } + if (name != "" && name != "item" && name != "namedItem") { + JS_DefineProperty(ctx, hobj, name.c_str(), ro, JSPROP_ENUMERATE); + } + counter++; + } + + return true; +} + static bool htmlCollection_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp) { @@ -3353,6 +3432,7 @@ getCollection(JSContext *ctx, void *node) spidermonkey_DefineFunctions(ctx, el, htmlCollection_funcs); JS_SetPrivate(el, node); + htmlCollection_set_items(ctx, r_el, node); return el; }