diff --git a/src/ecmascript/spidermonkey/element.cpp b/src/ecmascript/spidermonkey/element.cpp index f80db5f9d..eadee7587 100644 --- a/src/ecmascript/spidermonkey/element.cpp +++ b/src/ecmascript/spidermonkey/element.cpp @@ -25,6 +25,7 @@ #include "document/forms.h" #include "document/libdom/corestrings.h" #include "document/libdom/mapa.h" +#include "document/libdom/renderer2.h" #include "document/view.h" #include "ecmascript/ecmascript.h" #include "ecmascript/spidermonkey/attr.h" @@ -69,6 +70,7 @@ static bool element_get_property_childElementCount(JSContext *ctx, unsigned int static bool element_get_property_childNodes(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_className(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_set_property_className(JSContext *ctx, unsigned int argc, JS::Value *vp); +static bool element_get_property_clientHeight(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_clientLeft(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_clientTop(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool element_get_property_dir(JSContext *ctx, unsigned int argc, JS::Value *vp); @@ -149,6 +151,7 @@ JSPropertySpec element_props[] = { JS_PSG("childElementCount", element_get_property_childElementCount, JSPROP_ENUMERATE), JS_PSG("childNodes", element_get_property_childNodes, JSPROP_ENUMERATE), JS_PSGS("className", element_get_property_className, element_set_property_className, JSPROP_ENUMERATE), + JS_PSG("clientHeight", element_get_property_clientHeight, JSPROP_ENUMERATE), JS_PSG("clientLeft", element_get_property_clientLeft, JSPROP_ENUMERATE), JS_PSG("clientTop", element_get_property_clientTop, JSPROP_ENUMERATE), JS_PSGS("dir", element_get_property_dir, element_set_property_dir, JSPROP_ENUMERATE), @@ -578,6 +581,80 @@ element_get_property_className(JSContext *ctx, unsigned int argc, JS::Value *vp) return true; } +static bool +element_get_property_clientHeight(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; + } + int dy = int_max(0, (rect->y1 + 1 - rect->y0) * ses->tab->term->cell_height); + args.rval().setInt32(dy); + + return true; +} + static bool element_get_property_clientLeft(JSContext *ctx, unsigned int argc, JS::Value *vp) {