diff --git a/src/document/dom/ecmascript/spidermonkey/Element.c b/src/document/dom/ecmascript/spidermonkey/Element.c index 9a85a22f9..d89543355 100644 --- a/src/document/dom/ecmascript/spidermonkey/Element.c +++ b/src/document/dom/ecmascript/spidermonkey/Element.c @@ -5,17 +5,34 @@ #include "elinks.h" #include "document/dom/ecmascript/spidermonkey.h" +#include "document/dom/ecmascript/spidermonkey/Attr.h" #include "document/dom/ecmascript/spidermonkey/Element.h" #include "document/dom/ecmascript/spidermonkey/Node.h" +#include "dom/sgml/html/html.h" +#include "dom/string.h" JSBool Element_getProperty(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) { + struct dom_node *node; + uint16_t type; + unsigned char *elem_name; + if (!JSVAL_IS_INT(id)) return JS_TRUE; + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL))) + return JS_FALSE; + + node = JS_GetPrivate(ctx, obj); + if (!node) + return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_ELEMENT_TAG_NAME: - /* Write me! */ + type = node->data.element.type; + if (type > 0 && type < HTML_ELEMENTS) { + elem_name = sgml_html_info.elements[type].string.string; + string_to_jsval(ctx, vp, elem_name); + } break; case JSP_ELEMENT_SCHEMA_TYPE_INFO: /* Write me! */ @@ -30,7 +47,15 @@ static JSBool Element_getAttribute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + unsigned char *attr; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 1) + return JS_FALSE; + + /* This will work only with HTML. --witekfl */ + attr = jsval_to_string(ctx, &argv[0]); + JS_GetProperty(ctx, obj, attr, rval); return JS_TRUE; } @@ -38,7 +63,15 @@ static JSBool Element_setAttribute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + unsigned char *attr; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 2) + return JS_FALSE; + + /* This will work only with HTML. --witekfl */ + attr = jsval_to_string(ctx, &argv[0]); + JS_SetProperty(ctx, obj, attr, &argv[1]); return JS_TRUE; } @@ -46,7 +79,14 @@ static JSBool Element_removeAttribute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + unsigned char *attr; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 1) + return JS_FALSE; + + attr = jsval_to_string(ctx, &argv[0]); + JS_SetProperty(ctx, obj, attr, NULL); /* Special case. */ return JS_TRUE; } @@ -54,7 +94,32 @@ static JSBool Element_getAttributeNode(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + struct dom_node *node, *searched; + struct dom_node_list *list; + struct dom_string name; + unsigned char *attr; + JSObject *ret = NULL; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 1) + return JS_FALSE; + + node = JS_GetPrivate(ctx, obj); + if (!node) + return JS_FALSE; + + attr = jsval_to_string(ctx, &argv[0]); + if (!attr) { + undef_to_jsval(ctx, rval); + return JS_TRUE; + } + list = node->data.element.map; + name.string = attr; + name.length = strlen(attr); + searched = get_dom_node_map_entry(list, DOM_NODE_ATTRIBUTE, 0, &name); + if (searched) + ret = searched->ecmascript_obj; + object_to_jsval(ctx, rval, ret); return JS_TRUE; } @@ -62,7 +127,33 @@ static JSBool Element_setAttributeNode(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + jsval v; + struct dom_node *node, *searched; + struct dom_node_list *list; + struct dom_string name; + JSObject *attr, *ret = NULL; + unsigned char *data; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 1) + return JS_FALSE; + attr = JSVAL_TO_OBJECT(argv[0]); + if (!JS_InstanceOf(ctx, attr, (JSClass *)&Attr_class, NULL)) + return JS_FALSE; + + JS_GetProperty(ctx, attr, "name", &v); + data = jsval_to_string(ctx, &v); + if (data) { + name.string = data; + name.length = strlen(data); + list = node->data.element.map; + searched = get_dom_node_map_entry(list, DOM_NODE_ATTRIBUTE, 0, &name); + if (searched) + ret = searched->ecmascript_obj; + } + JS_GetProperty(ctx, attr, "value", &v); + Element_setAttribute(ctx, obj, 1, &v, NULL); + object_to_jsval(ctx, rval, ret); return JS_TRUE; } @@ -70,7 +161,34 @@ static JSBool Element_removeAttributeNode(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - /* Write me! */ + /* This is probably wrong! */ + jsval v; + struct dom_node *node, *searched; + struct dom_node_list *list; + struct dom_string name; + JSObject *attr, *ret = NULL; + unsigned char *data; + + if (!obj || (!JS_InstanceOf(ctx, obj, (JSClass *)&Element_class, NULL)) + || argc != 1) + return JS_FALSE; + attr = JSVAL_TO_OBJECT(argv[0]); + if (!JS_InstanceOf(ctx, attr, (JSClass *)&Attr_class, NULL)) + return JS_FALSE; + + JS_GetProperty(ctx, attr, "name", &v); + data = jsval_to_string(ctx, &v); + if (data) { + name.string = data; + name.length = strlen(data); + list = node->data.element.map; + searched = get_dom_node_map_entry(list, DOM_NODE_ATTRIBUTE, 0, &name); + if (searched) + ret = searched->ecmascript_obj; + } + undef_to_jsval(ctx, &v); + Element_setAttribute(ctx, obj, 1, &v, NULL); + object_to_jsval(ctx, rval, ret); return JS_TRUE; }