diff --git a/src/ecmascript/ecmascript-c.c b/src/ecmascript/ecmascript-c.c index e42e8327..d677c833 100644 --- a/src/ecmascript/ecmascript-c.c +++ b/src/ecmascript/ecmascript-c.c @@ -538,3 +538,64 @@ walk_tree_query(dom_node *node, char *selector, int depth) } return NULL; } + +void +walk_tree_query_append(dom_node *root, dom_node *node, char *selector, int depth) +{ + dom_exception exc; + dom_node *child; + void *res = NULL; + dom_node_type typ; + + /* Only interested in element nodes */ + exc = dom_node_get_node_type(node, &typ); + + if (typ != DOM_ELEMENT_NODE) { + return; + } + + if (res = el_match_selector(selector, node)) { + dom_node *clone = NULL; + exc = dom_node_clone_node(res, false, &clone); + + if (exc != DOM_NO_ERR || !clone) { + } else { + dom_node *result = NULL; + exc = dom_node_append_child(root, clone, &result); + } + + if (exc != DOM_NO_ERR) { + return; + } + } + /* Get the node's first child */ + exc = dom_node_get_first_child(node, &child); + + if (exc != DOM_NO_ERR) { + fprintf(stderr, "Exception raised for node_get_first_child\n"); + return; + } else if (child != NULL) { + /* node has children; decend to children's depth */ + depth++; + + /* Loop though all node's children */ + do { + dom_node *next_child; + + /* Visit node's descendents */ + walk_tree_query_append(root, child, selector, depth); + + /* Go to next sibling */ + exc = dom_node_get_next_sibling(child, &next_child); + if (exc != DOM_NO_ERR) { + fprintf(stderr, "Exception raised for " + "node_get_next_sibling\n"); + dom_node_unref(child); + return; + } + + dom_node_unref(child); + child = next_child; + } while (child != NULL); /* No more children */ + } +} diff --git a/src/ecmascript/ecmascript-c.h b/src/ecmascript/ecmascript-c.h index 939032ba..9bb20a84 100644 --- a/src/ecmascript/ecmascript-c.h +++ b/src/ecmascript/ecmascript-c.h @@ -41,6 +41,7 @@ void ecmascript_detach_form_state(struct form_state *fs); void ecmascript_moved_form_state(struct form_state *fs); void *walk_tree_query(dom_node *node, char *selector, int depth); +void walk_tree_query_append(dom_node *root, dom_node *node, char *selector, int depth); extern struct module ecmascript_module; diff --git a/src/ecmascript/spidermonkey/document.cpp b/src/ecmascript/spidermonkey/document.cpp index 9f5b9088..9a045b3a 100644 --- a/src/ecmascript/spidermonkey/document.cpp +++ b/src/ecmascript/spidermonkey/document.cpp @@ -1562,7 +1562,7 @@ document_createElement(JSContext *ctx, unsigned int argc, JS::Value *vp) args.rval().setBoolean(false); return true; } -// TODO + JS::Realm *comp = js::GetContextRealm(ctx); struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp); struct document_view *doc_view = interpreter->vs->doc_view; @@ -1883,7 +1883,6 @@ document_querySelectorAll(JSContext *ctx, unsigned int argc, JS::Value *vp) args.rval().setBoolean(false); return true; } - JS::Realm *comp = js::GetContextRealm(ctx); struct ecmascript_interpreter *interpreter = (struct ecmascript_interpreter *)JS::GetRealmPrivate(comp); struct document_view *doc_view = interpreter->vs->doc_view; @@ -1893,8 +1892,55 @@ document_querySelectorAll(JSContext *ctx, unsigned int argc, JS::Value *vp) args.rval().setNull(); return true; } -// TODO - args.rval().setNull(); + dom_node *doc_root = NULL; /* root element of document */ + /* Get root element */ + dom_exception exc = dom_document_get_document_element(document->dom, &doc_root); + + if (exc != DOM_NO_ERR) { + args.rval().setNull(); + return true; + } + char *selector = jsval_to_string(ctx, args[0]); + + if (!selector) { + dom_node_unref(doc_root); + args.rval().setNull(); + return true; + } + + dom_string *tag_name = NULL; + exc = dom_string_create((const uint8_t *)"B", 1, &tag_name); + + if (exc != DOM_NO_ERR || !tag_name) { + dom_node_unref(doc_root); + mem_free(selector); + args.rval().setNull(); + return true; + } + dom_element *element = NULL; + exc = dom_document_create_element(document->dom, tag_name, &element); + dom_string_unref(tag_name); + + if (exc != DOM_NO_ERR || !element) { + dom_node_unref(doc_root); + mem_free(selector); + args.rval().setNull(); + return true; + } + walk_tree_query_append((dom_node *)element, doc_root, selector, 0); + dom_node_unref(doc_root); + mem_free(selector); + + dom_nodelist *nodes = NULL; + exc = dom_node_get_child_nodes(element, &nodes); + dom_node_unref(element); + + if (exc != DOM_NO_ERR || !nodes) { + args.rval().setNull(); + return true; + } + JSObject *obj = getNodeList(ctx, nodes); + args.rval().setObject(*obj); return true; } diff --git a/test/ecmascript/assert/document.querySelectorAll.html b/test/ecmascript/assert/document.querySelectorAll.html index d1e5df38..c739695f 100644 --- a/test/ecmascript/assert/document.querySelectorAll.html +++ b/test/ecmascript/assert/document.querySelectorAll.html @@ -10,7 +10,7 @@ function myFunction() { console.assert(x.length === 0, 'nonexistent elements'); var y = document.querySelectorAll('p'); - console.assert(y.length === 2, 'Two p'); + console.assert(y.length == 2, 'Two p'); } console.error('document.querySelectorAll.html');