mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
[spidermonkey] document.querySelector
It passes test case.
This commit is contained in:
parent
be67094940
commit
cc718c30b5
@ -97,7 +97,11 @@ static css_error node_presentational_hint(void *pw, void *node,
|
||||
return CSS_OK;
|
||||
}
|
||||
|
||||
|
||||
static css_error
|
||||
resolve_url_empty(void *pw, const char *base, lwc_string *rel, lwc_string **abs)
|
||||
{
|
||||
return CSS_OK;
|
||||
}
|
||||
|
||||
css_error
|
||||
resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs)
|
||||
@ -2309,3 +2313,122 @@ import_css2(struct html_context *html_context, struct uri *uri)
|
||||
// css->import_level--;
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
el_match_selector(const char *selector, void *node)
|
||||
{
|
||||
struct string text;
|
||||
css_error code;
|
||||
size_t size;
|
||||
uint32_t count;
|
||||
css_stylesheet_params params;
|
||||
css_stylesheet *sheet = NULL;
|
||||
css_select_ctx *select_ctx = NULL;
|
||||
css_select_results *style = NULL;
|
||||
uint8_t color_type;
|
||||
css_color color_shade;
|
||||
|
||||
css_media media = {
|
||||
.type = CSS_MEDIA_SCREEN,
|
||||
};
|
||||
|
||||
css_unit_ctx unit_len_ctx = {0};
|
||||
unit_len_ctx.viewport_width = 800; // TODO
|
||||
unit_len_ctx.viewport_height = 600; // TODO
|
||||
unit_len_ctx.device_dpi = F_90; //device_dpi;
|
||||
|
||||
/** \todo Change nsoption font sizes to px. */
|
||||
/// f_size = FDIV(FMUL(F_96, FDIV(INTTOFIX(nsoption_int(font_size)), F_10)), F_72);
|
||||
/// f_min = FDIV(FMUL(F_96, FDIV(INTTOFIX(nsoption_int(font_min_size)), F_10)), F_72);
|
||||
|
||||
unsigned int f_size = FDIV(FMUL(F_96, FDIV(INTTOFIX(50), F_10)), F_72); // TODO
|
||||
unsigned int f_min = FDIV(FMUL(F_96, FDIV(INTTOFIX(50), F_10)), F_72); // TODO
|
||||
|
||||
unit_len_ctx.font_size_default = f_size;
|
||||
unit_len_ctx.font_size_minimum = f_min;
|
||||
void *ret = NULL;
|
||||
|
||||
params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
|
||||
params.level = CSS_LEVEL_21;
|
||||
params.charset = "UTF-8";
|
||||
params.url = "foo";
|
||||
params.title = "foo";
|
||||
params.allow_quirks = false;
|
||||
params.inline_style = false;
|
||||
params.resolve = resolve_url_empty;
|
||||
params.resolve_pw = NULL;
|
||||
params.import = NULL;
|
||||
params.import_pw = NULL;
|
||||
params.color = NULL;
|
||||
params.color_pw = NULL;
|
||||
params.font = NULL;
|
||||
params.font_pw = NULL;
|
||||
|
||||
if (!selector) {
|
||||
return NULL;
|
||||
}
|
||||
if (!init_string(&text)) {
|
||||
return NULL;
|
||||
}
|
||||
add_to_string(&text, selector);
|
||||
add_to_string(&text, "{color:#123456}");
|
||||
|
||||
/* create a stylesheet */
|
||||
code = css_stylesheet_create(¶ms, &sheet);
|
||||
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_stylesheet_append_data(sheet, (const uint8_t *) text.source, text.length);
|
||||
|
||||
if (code != CSS_OK && code != CSS_NEEDDATA) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_stylesheet_data_done(sheet);
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_stylesheet_size(sheet, &size);
|
||||
|
||||
/* prepare a selection context containing the stylesheet */
|
||||
code = css_select_ctx_create(&select_ctx);
|
||||
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR, NULL);
|
||||
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_select_ctx_count_sheets(select_ctx, &count);
|
||||
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
code = css_select_style(select_ctx, node, &unit_len_ctx, &media, NULL, &selection_handler, 0, &style);
|
||||
|
||||
if (code != CSS_OK) {
|
||||
goto empty;
|
||||
}
|
||||
|
||||
color_type = css_computed_color(style->styles[CSS_PSEUDO_ELEMENT_NONE], &color_shade);
|
||||
|
||||
if (color_type && color_shade == 0xff123456) {
|
||||
ret = node;
|
||||
}
|
||||
|
||||
empty:
|
||||
if (style) {
|
||||
css_select_results_destroy(style);
|
||||
}
|
||||
if (select_ctx) {
|
||||
css_select_ctx_destroy(select_ctx);
|
||||
}
|
||||
if (sheet) {
|
||||
css_stylesheet_destroy(sheet);
|
||||
}
|
||||
done_string(&text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ struct string;
|
||||
void *document_parse_text(const char *charset, char *data, size_t length);
|
||||
void *document_parse(struct document *document, struct string *source);
|
||||
void free_document(void *doc);
|
||||
void *el_match_selector(const char *selector, void *node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1819,6 +1819,62 @@ document_getElementsByTagName(JSContext *ctx, unsigned int argc, JS::Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
void *
|
||||
walk_tree_query(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 NULL;
|
||||
}
|
||||
|
||||
if (res = el_match_selector(selector, node)) {
|
||||
/* There was an error; return */
|
||||
return res;
|
||||
}
|
||||
/* 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 NULL;
|
||||
} 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 */
|
||||
res = walk_tree_query(child, selector, depth);
|
||||
/* There was an error; return */
|
||||
if (res) {
|
||||
dom_node_unref(child);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* 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 NULL;
|
||||
}
|
||||
|
||||
dom_node_unref(child);
|
||||
child = next_child;
|
||||
} while (child != NULL); /* No more children */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
document_querySelector(JSContext *ctx, unsigned int argc, JS::Value *vp)
|
||||
{
|
||||
@ -1841,8 +1897,31 @@ document_querySelector(JSContext *ctx, unsigned int argc, JS::Value *vp)
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
// TODO
|
||||
args.rval().setNull();
|
||||
dom_node *root = NULL; /* root element of document */
|
||||
/* Get root element */
|
||||
dom_exception exc = dom_document_get_document_element(document->dom, &root);
|
||||
|
||||
if (exc != DOM_NO_ERR) {
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
char *selector = jsval_to_string(ctx, args[0]);
|
||||
|
||||
if (!selector) {
|
||||
dom_node_unref(root);
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
}
|
||||
void *ret = walk_tree_query(root, selector, 0);
|
||||
mem_free(selector);
|
||||
dom_node_unref(root);
|
||||
|
||||
if (!ret) {
|
||||
args.rval().setNull();
|
||||
} else {
|
||||
JSObject *el = getElement(ctx, ret);
|
||||
args.rval().setObject(*el);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ function myFunction() {
|
||||
|
||||
var y = document.querySelector('.b');
|
||||
console.assert(!(y === null), 'Class b');
|
||||
var inp = y.innerHTML;
|
||||
console.assert(inp === 'Class b.', 'Class b.');
|
||||
}
|
||||
|
||||
console.error('document.querySelector.html');
|
||||
|
Loading…
Reference in New Issue
Block a user