From 6798ffc8b0cd3cd06165817bd134dacaf421a676 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sun, 9 May 2021 21:53:14 +0200 Subject: [PATCH] [js] lastChild --- src/ecmascript/spidermonkey/element.c | 46 +++++++++++++++++++++++++++ test/ecmascript/lastChild.html | 15 +++++++++ 2 files changed, 61 insertions(+) create mode 100644 test/ecmascript/lastChild.html diff --git a/src/ecmascript/spidermonkey/element.c b/src/ecmascript/spidermonkey/element.c index 8517807c2..cd7bd08bb 100644 --- a/src/ecmascript/spidermonkey/element.c +++ b/src/ecmascript/spidermonkey/element.c @@ -64,6 +64,7 @@ static bool element_get_property_innerHtml(JSContext *ctx, unsigned int argc, JS static bool element_set_property_innerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_set_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool element_get_property_lastChild(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_outerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_set_property_outerHtml(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_tagName(JSContext *ctx, unsigned int argc, JS::Value *vp); @@ -92,6 +93,7 @@ JSPropertySpec element_props[] = { JS_PSGS("id", element_get_property_id, element_set_property_id, JSPROP_ENUMERATE), JS_PSGS("innerHTML", element_get_property_innerHtml, element_set_property_innerHtml, JSPROP_ENUMERATE), JS_PSGS("lang", element_get_property_lang, element_set_property_lang, JSPROP_ENUMERATE), + JS_PSG("lastChild", element_get_property_lastChild, JSPROP_ENUMERATE), JS_PSGS("outerHTML", element_get_property_outerHtml, element_set_property_outerHtml, JSPROP_ENUMERATE), JS_PSG("tagName", element_get_property_tagName, JSPROP_ENUMERATE), JS_PSGS("textContent", element_get_property_textContent, element_set_property_textContent, JSPROP_ENUMERATE), @@ -344,6 +346,50 @@ element_get_property_lang(JSContext *ctx, unsigned int argc, JS::Value *vp) return true; } +static bool +element_get_property_lastChild(JSContext *ctx, unsigned int argc, JS::Value *vp) +{ + JS::CallArgs args = CallArgsFromVp(argc, vp); + JS::RootedObject hobj(ctx, &args.thisv().toObject()); + + struct view_state *vs; + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(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, &element_class, NULL)) + return false; + + vs = interpreter->vs; + if (!vs) { + return false; + } + + xmlpp::Element *el = JS_GetPrivate(hobj); + + if (!el) { + args.rval().setNull(); + return true; + } + + auto nodes = el->get_children(); + if (nodes.empty()) { + args.rval().setNull(); + return true; + } + + JSObject *elem = getElement(ctx, *(nodes.rbegin())); + args.rval().setObject(*elem); + + return true; +} static bool element_get_property_tagName(JSContext *ctx, unsigned int argc, JS::Value *vp) diff --git a/test/ecmascript/lastChild.html b/test/ecmascript/lastChild.html new file mode 100644 index 000000000..6d117680d --- /dev/null +++ b/test/ecmascript/lastChild.html @@ -0,0 +1,15 @@ + + +BBB +bbb +AAAUUUAAAAAAA +BB + + + +