mirror of
https://github.com/rkd77/elinks.git
synced 2025-01-03 14:57:44 -05:00
[spidermonkey] document.getElementsByClassName
Memory leaks will be addressed later.
This commit is contained in:
parent
63590b0e05
commit
851c9c6f61
@ -609,3 +609,153 @@ walk_tree_query_append(dom_node *root, dom_node *node, const char *selector, int
|
||||
} while (child != NULL); /* No more children */
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
node_has_classes(struct dom_node *node, void *ctx)
|
||||
{
|
||||
LIST_OF(struct class_string) *list = (LIST_OF(struct class_string) *)ctx;
|
||||
struct class_string *st;
|
||||
|
||||
if (list_empty(*list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (st, *list) {
|
||||
bool ret = false;
|
||||
dom_exception exc = dom_element_has_class((struct dom_element *)node, st->name, &ret);
|
||||
|
||||
if (exc != DOM_NO_ERR || !ret) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static LIST_OF(struct class_string) *
|
||||
prepare_strings(char *text)
|
||||
{
|
||||
if (!text) {
|
||||
return NULL;
|
||||
}
|
||||
LIST_OF(struct class_string) *list = (LIST_OF(struct class_string) *)mem_calloc(1, sizeof(*list));
|
||||
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
init_list(*list);
|
||||
char *pos = text;
|
||||
|
||||
while (*pos) {
|
||||
skip_space(pos);
|
||||
if (*pos) {
|
||||
char *begin = pos;
|
||||
|
||||
skip_nonspace(pos);
|
||||
struct class_string *klass = (struct class_string *)mem_calloc(1, sizeof(*klass));
|
||||
|
||||
if (!klass) {
|
||||
continue;
|
||||
}
|
||||
lwc_string *ls = NULL;
|
||||
lwc_error err = lwc_intern_string(begin, pos - begin, &ls);
|
||||
|
||||
if (err == lwc_error_ok) {
|
||||
klass->name = ls;
|
||||
add_to_list_end(*list, klass);
|
||||
} else {
|
||||
mem_free(klass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
typedef bool (*dom_callback_is_in_collection)(struct dom_node *node, void *ctx);
|
||||
|
||||
/**
|
||||
* The html_collection structure
|
||||
*/
|
||||
struct el_dom_html_collection {
|
||||
dom_callback_is_in_collection ic;
|
||||
/**< The function pointer used to test
|
||||
* whether some node is an element of
|
||||
* this collection
|
||||
*/
|
||||
void *ctx; /**< Context for the callback */
|
||||
struct dom_html_document *doc; /**< The document created this
|
||||
* collection
|
||||
*/
|
||||
dom_node *root; /**< The root node of this collection */
|
||||
uint32_t refcnt; /**< Reference counting */
|
||||
};
|
||||
|
||||
/**
|
||||
* Intialiase a dom_html_collection
|
||||
*
|
||||
* \param doc The document
|
||||
* \param col The collection object to be initialised
|
||||
* \param root The root element of the collection
|
||||
* \param ic The callback function used to determin whether certain node
|
||||
* beint32_ts to the collection
|
||||
* \return DOM_NO_ERR on success.
|
||||
*/
|
||||
static dom_exception
|
||||
el_dom_html_collection_initialise(dom_html_document *doc,
|
||||
struct el_dom_html_collection *col,
|
||||
dom_node *root,
|
||||
dom_callback_is_in_collection ic, void *ctx)
|
||||
{
|
||||
assert(doc != NULL);
|
||||
assert(ic != NULL);
|
||||
assert(root != NULL);
|
||||
|
||||
col->doc = doc;
|
||||
dom_node_ref(doc);
|
||||
col->root = root;
|
||||
dom_node_ref(root);
|
||||
|
||||
col->ic = ic;
|
||||
col->ctx = ctx;
|
||||
col->refcnt = 1;
|
||||
|
||||
return DOM_NO_ERR;
|
||||
}
|
||||
|
||||
static dom_exception
|
||||
el_dom_html_collection_create(dom_html_document *doc,
|
||||
dom_node *root,
|
||||
dom_callback_is_in_collection ic,
|
||||
void *ctx,
|
||||
el_dom_html_collection **col)
|
||||
{
|
||||
*col = (el_dom_html_collection *)malloc(sizeof(struct el_dom_html_collection));
|
||||
|
||||
if (*col == NULL) {
|
||||
return DOM_NO_MEM_ERR;
|
||||
}
|
||||
|
||||
return el_dom_html_collection_initialise(doc, *col, root, ic, ctx);
|
||||
}
|
||||
|
||||
void *
|
||||
get_elements_by_class_name(dom_html_document *doc, dom_node *node, char *classes)
|
||||
{
|
||||
if (!node || !classes) {
|
||||
return NULL;
|
||||
}
|
||||
LIST_OF(struct class_string) *list = prepare_strings(classes);
|
||||
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
el_dom_html_collection *col = NULL;
|
||||
dom_exception exc = el_dom_html_collection_create(doc, node, node_has_classes, list, &col);
|
||||
|
||||
if (exc != DOM_NO_ERR || !col) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
@ -29,6 +29,12 @@ struct selector_node {
|
||||
void *node;
|
||||
};
|
||||
|
||||
struct class_string {
|
||||
LIST_HEAD_EL(struct class_string);
|
||||
|
||||
void *name;
|
||||
};
|
||||
|
||||
int ecmascript_get_interpreter_count(void);
|
||||
void ecmascript_put_interpreter(struct ecmascript_interpreter *interpreter);
|
||||
void toggle_ecmascript(struct session *ses);
|
||||
@ -50,6 +56,7 @@ void ecmascript_moved_form_state(struct form_state *fs);
|
||||
|
||||
void *walk_tree_query(dom_node *node, const char *selector, int depth);
|
||||
void walk_tree_query_append(dom_node *root, dom_node *node, const char *selector, int depth, LIST_OF(struct selector_node) *result_list);
|
||||
void *get_elements_by_class_name(dom_html_document *doc, dom_node *node, char *classes);
|
||||
|
||||
extern struct module ecmascript_module;
|
||||
|
||||
|
@ -1243,7 +1243,7 @@ const spidermonkeyFunctionSpec document_funcs[] = {
|
||||
{ "writeln", document_writeln, 1 },
|
||||
{ "replace", document_replace, 2 },
|
||||
{ "getElementById", document_getElementById, 1 },
|
||||
// { "getElementsByClassName", document_getElementsByClassName, 1 },
|
||||
{ "getElementsByClassName", document_getElementsByClassName, 1 },
|
||||
// { "getElementsByName", document_getElementsByName, 1 },
|
||||
{ "getElementsByTagName", document_getElementsByTagName, 1 },
|
||||
{ "querySelector", document_querySelector, 1 },
|
||||
@ -1963,17 +1963,35 @@ document_getElementsByClassName(JSContext *ctx, unsigned int argc, JS::Value *vp
|
||||
fprintf(stderr, "%s:%s\n", __FILE__, __FUNCTION__);
|
||||
#endif
|
||||
JS::CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS::RootedObject hobj(ctx, &args.thisv().toObject());
|
||||
|
||||
if (argc != 1) {
|
||||
args.rval().setBoolean(false);
|
||||
if (!JS_InstanceOf(ctx, hobj, &document_class, NULL)) {
|
||||
#ifdef ECMASCRIPT_DEBUG
|
||||
fprintf(stderr, "%s:%s %d\n", __FILE__, __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
dom_html_document *doc = JS::GetMaybePtrFromReservedSlot<dom_html_document>(hobj, 0);
|
||||
|
||||
if (!doc) {
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Realm *comp = js::GetContextRealm(ctx);
|
||||
struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp);
|
||||
if (argc != 1) {
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
char *classes = jsval_to_string(ctx, args[0]);
|
||||
dom_html_collection *col = get_elements_by_class_name(doc, (dom_node *)doc, classes);
|
||||
mem_free_if(classes);
|
||||
|
||||
// TODO
|
||||
args.rval().setNull();
|
||||
if (!col) {
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
JSObject *obj = getCollection(ctx, col);
|
||||
args.rval().setObject(*obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ First Name: <input name="fname" type="text" value="Doug">
|
||||
|
||||
<script>
|
||||
function myFunction() {
|
||||
var x = document.getElementsByClassName("test");//.item(1).outerHTML;
|
||||
var x = document.getElementsByClassName("test").item(1).outerHTML;
|
||||
console.assert(x === '<button onclick="myFunction()" class="test">Try it</button>', x);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
tofail = [
|
||||
'console.assert.html',
|
||||
#'document.getElementsByClassName.html', // not implemented
|
||||
#'document.getElementsByName.html', // not implemented
|
||||
'document.head.html',
|
||||
'element.namedItem.html'
|
||||
@ -19,6 +18,7 @@ took = [
|
||||
'document.documentElement.html',
|
||||
'document.documentURI.html',
|
||||
'document.domain.html',
|
||||
'document.getElementsByClassName.html',
|
||||
'document.getElementsByTagName.html',
|
||||
'document.images.html',
|
||||
'document.links.html',
|
||||
|
Loading…
Reference in New Issue
Block a user