/* The SpiderMonkey attr object implementation. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "elinks.h" #include "ecmascript/spidermonkey/util.h" #include #include "bfu/dialog.h" #include "cache/cache.h" #include "cookies/cookies.h" #include "dialogs/menu.h" #include "dialogs/status.h" #include "document/html/frames.h" #include "document/document.h" #include "document/forms.h" #include "document/view.h" #include "ecmascript/ecmascript.h" #include "ecmascript/spidermonkey/attr.h" #include "intl/libintl.h" #include "main/select.h" #include "osdep/newwin.h" #include "osdep/sysname.h" #include "protocol/http/http.h" #include "protocol/uri.h" #include "session/history.h" #include "session/location.h" #include "session/session.h" #include "session/task.h" #include "terminal/tab.h" #include "terminal/terminal.h" #include "util/conv.h" #include "util/memory.h" #include "util/string.h" #include "viewer/text/draw.h" #include "viewer/text/form.h" #include "viewer/text/link.h" #include "viewer/text/vs.h" #include #include #include #include #include #include #include #include static bool attr_get_property_name(JSContext *ctx, unsigned int argc, JS::Value *vp); static bool attr_get_property_value(JSContext *ctx, unsigned int argc, JS::Value *vp); static void attr_finalize(JSFreeOp *op, JSObject *obj) { #ifdef ECMASCRIPT_DEBUG fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__); #endif } JSClassOps attr_ops = { nullptr, // addProperty nullptr, // deleteProperty nullptr, // enumerate nullptr, // newEnumerate nullptr, // resolve nullptr, // mayResolve attr_finalize, // finalize nullptr, // call nullptr, // hasInstance nullptr, // construct JS_GlobalObjectTraceHook }; JSClass attr_class = { "attr", JSCLASS_HAS_PRIVATE, &attr_ops }; static JSPropertySpec attr_props[] = { JS_PSG("name", attr_get_property_name, JSPROP_ENUMERATE), JS_PSG("value", attr_get_property_value, JSPROP_ENUMERATE), JS_PS_END }; static bool attr_get_property_name(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, &attr_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; } xmlpp::AttributeNode *attr = static_cast(JS::GetPrivate(hobj)); if (!attr) { args.rval().setNull(); return true; } xmlpp::ustring v = attr->get_name(); args.rval().setString(JS_NewStringCopyZ(ctx, v.c_str())); return true; } static bool attr_get_property_value(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, &attr_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; } xmlpp::AttributeNode *attr = static_cast(JS::GetPrivate(hobj)); if (!attr) { args.rval().setNull(); return true; } xmlpp::ustring v = attr->get_value(); args.rval().setString(JS_NewStringCopyZ(ctx, v.c_str())); return true; } JSObject * getAttr(JSContext *ctx, void *node) { JSObject *el = JS_NewObject(ctx, &attr_class); if (!el) { return NULL; } JS::RootedObject r_el(ctx, el); JS_DefineProperties(ctx, r_el, (JSPropertySpec *) attr_props); // spidermonkey_DefineFunctions(ctx, el, attributes_funcs); JS::SetPrivate(el, node); return el; }