From 317737fa34f8fe0690e0fd6fddedbdd5fb14db7a Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sat, 27 Jan 2024 15:23:09 +0100 Subject: [PATCH] [spidermonkey] element.offsetTop --- src/ecmascript/spidermonkey/element.cpp | 96 +++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/ecmascript/spidermonkey/element.cpp b/src/ecmascript/spidermonkey/element.cpp index 360608a3a..189537324 100644 --- a/src/ecmascript/spidermonkey/element.cpp +++ b/src/ecmascript/spidermonkey/element.cpp @@ -94,6 +94,7 @@ static bool element_get_property_nodeType(JSContext *ctx, unsigned int argc, JS: static bool element_get_property_nodeValue(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_offsetLeft(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_offsetParent(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool element_get_property_offsetTop(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_ownerDocument(JSContext *ctx, unsigned int argc, JS::Value *vp); @@ -174,6 +175,7 @@ JSPropertySpec element_props[] = { JS_PSG("nodeValue", element_get_property_nodeValue, JSPROP_ENUMERATE), JS_PSG("offsetLeft", element_get_property_offsetLeft, JSPROP_ENUMERATE), JS_PSG("offsetParent", element_get_property_offsetParent, JSPROP_ENUMERATE), + JS_PSG("offsetTop", element_get_property_offsetTop, JSPROP_ENUMERATE), JS_PSGS("outerHTML", element_get_property_outerHtml, element_set_property_outerHtml, JSPROP_ENUMERATE), JS_PSG("ownerDocument", element_get_property_ownerDocument, JSPROP_ENUMERATE), JS_PSG("parentElement", element_get_property_parentElement, JSPROP_ENUMERATE), @@ -1713,6 +1715,100 @@ element_get_property_offsetParent(JSContext *ctx, unsigned int argc, JS::Value * return true; } +static bool +element_get_property_offsetTop(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; + 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 = (struct ecmascript_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, &element_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; + } + dom_node *el = (dom_node *)JS::GetMaybePtrFromReservedSlot(hobj, 0); + + if (!el) { + args.rval().setNull(); + return true; + } + struct document_view *doc_view = vs->doc_view; + struct document *document = doc_view->document; + struct session *ses; + + if (!document) { + args.rval().setInt32(0); + return true; + } + int offset = find_offset(document->element_map_rev, el); + + if (offset <= 0) { + args.rval().setInt32(0); + return true; + } + struct node_rect *rect = get_element_rect(document, offset); + + if (!rect) { + args.rval().setInt32(0); + return true; + } + ses = doc_view->session; + + if (!ses) { + args.rval().setInt32(0); + return true; + } + dom_node *node = NULL; + dom_exception exc = dom_node_get_parent_node(el, &node); + if (exc != DOM_NO_ERR || !node) { + args.rval().setInt32(0); + return true; + } + int offset_parent = find_offset(document->element_map_rev, node); + + if (offset_parent <= 0) { + args.rval().setInt32(0); + return true; + } + struct node_rect *rect_parent = get_element_rect(document, offset_parent); + + if (!rect_parent) { + args.rval().setInt32(0); + return true; + } + int dy = int_max(0, (rect->y0 - rect_parent->y0) * ses->tab->term->cell_height); + dom_node_unref(node); + args.rval().setInt32(dy); + + return true; +} + static bool element_get_property_ownerDocument(JSContext *ctx, unsigned int argc, JS::Value *vp)