From cea0788405f9a492ac6b447089ba4e711f821c2a Mon Sep 17 00:00:00 2001 From: konn Date: Wed, 11 Jun 2008 09:52:36 +0000 Subject: [PATCH] * Added pseudo selector finder. git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/branches/sandbox@2707 1a406e8e-add9-4483-a2c8-d8cac5b7c224 --- include/chxj_css.h | 1 + src/chxj_css.c | 44 ++++++++- test/chxj_css/test_chxj_css.c | 210 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 1 deletion(-) diff --git a/include/chxj_css.h b/include/chxj_css.h index 26a40b76..760e95b7 100644 --- a/include/chxj_css.h +++ b/include/chxj_css.h @@ -76,6 +76,7 @@ typedef struct __css_current_stylesheet_stack_t { extern css_stylesheet_t *chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, css_stylesheet_t *old_stylesheet, const char *uri); extern void chxj_css_stylesheet_dump(css_stylesheet_t *stylesheet); extern css_selector_t *chxj_css_find_selector(Doc *doc, css_stylesheet_t *stylesheet, Node *node); +extern css_stylesheet_t *chxj_find_pseudo_selectors(Doc *doc, css_stylesheet_t *stylesheet); #endif /* * vim:ts=2 et diff --git a/src/chxj_css.c b/src/chxj_css.c index b784018a..450a7527 100644 --- a/src/chxj_css.c +++ b/src/chxj_css.c @@ -261,6 +261,7 @@ s_search_selector_regexp(Doc *doc, request_rec *r, apr_pool_t *pool, css_stylesh if (chxj_ap_regexec(pattern3, src, pattern3->re_nsub + 1, match, 0) == 0) { DBG(r, "has any parent"); one = chxj_ap_pregsub(pool, "$1",src, pattern3->re_nsub + 1, match); + char *ret = s_cmp_now_node_vs_current_style(doc, r, pool, strrchr(src, *one)+1, pattern4, node->parent); if (ret) { DBG(r, "continue do while"); @@ -599,7 +600,7 @@ s_search_selector(css_stylesheet_t *stylesheet, const char *name) char u = toupper(*name); if (! stylesheet) return NULL; for (cur = stylesheet->selector_head.next; cur != &stylesheet->selector_head; cur = cur->next) { - if ((l == *cur->name || u == *cur->name) && strcasecmp(cur->name, name) == 0) { + if (cur->name && (l == *cur->name || u == *cur->name) && strcasecmp(cur->name, name) == 0) { return cur; } } @@ -947,6 +948,47 @@ s_cmp_now_node_vs_current_style(Doc *doc, request_rec *r, apr_pool_t *pool, char return NULL; } + +/** + * find selector with pseudo class. + * @return new css_stylesheet_t + */ +css_stylesheet_t * +chxj_find_pseudo_selectors(Doc *doc, css_stylesheet_t *stylesheet) +{ + css_selector_t *cur_sel; + css_property_t *cur_prop; + css_stylesheet_t *result; + char *pattern_str = "^a:(link|focus|visited)$"; + ap_regex_t *pattern1 = chxj_ap_pregcomp(doc->pool, pattern_str, AP_REG_EXTENDED|AP_REG_ICASE); + + result = apr_palloc(doc->pool, sizeof(*result)); + if (! result) { + ERR(doc->r, "%s:%d Out of Memory", APLOG_MARK); + return NULL; + } + memset(result, 0, sizeof(*result)); + result->selector_head.next = &result->selector_head; + result->selector_head.ref = &result->selector_head.next; + + for (cur_sel = stylesheet->selector_head.next; cur_sel != &stylesheet->selector_head; cur_sel = cur_sel->next) { + ap_regmatch_t match[256]; + if (chxj_ap_regexec(pattern1, cur_sel->name, pattern1->re_nsub + 1, match, 0) == 0) { + css_selector_t *new_sel = s_new_selector(doc->pool, result, cur_sel->name); + css_property_t *cur_prop; + for (cur_prop = cur_sel->property_head.next; cur_prop != &cur_sel->property_head; cur_prop = cur_prop->next) { + css_property_t *to_prop = s_css_parser_copy_property(doc->pool, cur_prop); + list_insert(to_prop, (&new_sel->property_head)); + } + list_insert(new_sel, (&result->selector_head)); + } + } + + chxj_ap_pregfree(doc->pool, pattern1); + + return result; +} + #if 0 css_stylesheet_t * chxj_css_parse_from_style_tag(apr_pool_t *pool, css_stylesheet_t *old_stylesheet, const char *style_value) diff --git a/test/chxj_css/test_chxj_css.c b/test/chxj_css/test_chxj_css.c index 1ab3b2d4..7192071d 100644 --- a/test/chxj_css/test_chxj_css.c +++ b/test/chxj_css/test_chxj_css.c @@ -87,6 +87,12 @@ void test_chxj_css_find_selector_mix_001(); void test_chxj_css_find_selector_mix_002(); /* p + div p + hr */ void test_chxj_css_find_selector_mix_003(); void test_chxj_css_find_selector_mix_004(); + +/* pseudo */ +void test_chxj_css_find_selector_pseudo_001(); +void test_chxj_css_find_selector_pseudo_002(); +void test_chxj_css_find_selector_pseudo_003(); +void test_chxj_css_find_selector_pseudo_004(); /* pend */ int @@ -150,6 +156,11 @@ main() CU_add_test(css_suite, "test css find_selector with 'mix' 002", test_chxj_css_find_selector_mix_002); CU_add_test(css_suite, "test css find_selector with 'mix' 003", test_chxj_css_find_selector_mix_003); CU_add_test(css_suite, "test css find_selector with 'mix' 004", test_chxj_css_find_selector_mix_004); + + CU_add_test(css_suite, "test css find_pseudo_selector 001", test_chxj_css_find_selector_pseudo_001); + CU_add_test(css_suite, "test css find_pseudo_selector 002", test_chxj_css_find_selector_pseudo_002); + CU_add_test(css_suite, "test css find_pseudo_selector 003", test_chxj_css_find_selector_pseudo_003); + CU_add_test(css_suite, "test css find_pseudo_selector 004", test_chxj_css_find_selector_pseudo_004); /* aend */ CU_basic_run_tests(); @@ -2736,6 +2747,205 @@ void test_chxj_css_find_selector_mix_004() fprintf(stderr, "end %s\n", __func__); #undef TEST_STRING } + + +/* pseudo selector */ +char *test_chxj_serf_get052(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "a:link { display: none }"; + + return css; +} +void test_chxj_css_find_selector_pseudo_001() +{ + Doc doc; + Node *node; + Node *tmp_node; + Node *node_sv; + css_stylesheet_t *ret; + css_selector_t *sel; + int ii; + APR_INIT; + chxj_serf_get = test_chxj_serf_get052; + + fprintf(stderr, "start %s\n", __func__); + doc.r = &r; + qs_init_malloc(&doc); + qs_init_root_node(&doc); + doc.parse_mode = PARSE_MODE_CHTML; + + + apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \ + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css"); + CU_ASSERT(ret != NULL); + + ret = chxj_find_pseudo_selectors(&doc, ret); + CU_ASSERT(ret != NULL); + ii = 0; + for (sel = ret->selector_head.next;ret && sel != &ret->selector_head; sel = sel->next) { + fprintf(stderr, "%s\n", sel->name); + switch(ii) { + case 0: + CU_ASSERT(strcasecmp(sel->name, "a:link") == 0); + break; + } + ii++; + } + APR_TERM; + fprintf(stderr, "end %s\n", __func__); +#undef TEST_STRING +} +char *test_chxj_serf_get053(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "a:visited { display: none }"; + + return css; +} +void test_chxj_css_find_selector_pseudo_002() +{ + Doc doc; + Node *node; + Node *tmp_node; + Node *node_sv; + css_stylesheet_t *ret; + css_selector_t *sel; + int ii; + APR_INIT; + chxj_serf_get = test_chxj_serf_get053; + + fprintf(stderr, "start %s\n", __func__); + doc.r = &r; + qs_init_malloc(&doc); + qs_init_root_node(&doc); + doc.parse_mode = PARSE_MODE_CHTML; + + + apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \ + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css"); + CU_ASSERT(ret != NULL); + + ret = chxj_find_pseudo_selectors(&doc, ret); + CU_ASSERT(ret != NULL); + ii = 0; + for (sel = ret->selector_head.next;ret && sel != &ret->selector_head; sel = sel->next) { + fprintf(stderr, "%s\n", sel->name); + switch(ii) { + case 0: + CU_ASSERT(strcasecmp(sel->name, "a:visited") == 0); + break; + } + ii++; + } + APR_TERM; + fprintf(stderr, "end %s\n", __func__); +#undef TEST_STRING +} + +char *test_chxj_serf_get054(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "a:focus { display: none }"; + + return css; +} +void test_chxj_css_find_selector_pseudo_003() +{ + Doc doc; + Node *node; + Node *tmp_node; + Node *node_sv; + css_stylesheet_t *ret; + css_selector_t *sel; + int ii; + APR_INIT; + chxj_serf_get = test_chxj_serf_get054; + + fprintf(stderr, "start %s\n", __func__); + doc.r = &r; + qs_init_malloc(&doc); + qs_init_root_node(&doc); + doc.parse_mode = PARSE_MODE_CHTML; + + + apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \ + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css"); + CU_ASSERT(ret != NULL); + + ret = chxj_find_pseudo_selectors(&doc, ret); + CU_ASSERT(ret != NULL); + ii = 0; + for (sel = ret->selector_head.next;ret && sel != &ret->selector_head; sel = sel->next) { + fprintf(stderr, "%s\n", sel->name); + switch(ii) { + case 0: + CU_ASSERT(strcasecmp(sel->name, "a:focus") == 0); + break; + } + ii++; + } + APR_TERM; + fprintf(stderr, "end %s\n", __func__); +#undef TEST_STRING +} + +char *test_chxj_serf_get055(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "a:focus { display: none }\n" + "a:link { display: none }\n" + "a { display: none }\n" + "hr { display: none }\n" + "a:visited { display:none }"; + + return css; +} +void test_chxj_css_find_selector_pseudo_004() +{ + Doc doc; + Node *node; + Node *tmp_node; + Node *node_sv; + css_stylesheet_t *ret; + css_selector_t *sel; + int ii; + APR_INIT; + chxj_serf_get = test_chxj_serf_get055; + + fprintf(stderr, "start %s\n", __func__); + doc.r = &r; + qs_init_malloc(&doc); + qs_init_root_node(&doc); + doc.parse_mode = PARSE_MODE_CHTML; + + + apr_uri_parse(p, "http://localhost:888/abc", &r.parsed_uri); \ + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css"); + CU_ASSERT(ret != NULL); + + ret = chxj_find_pseudo_selectors(&doc, ret); + CU_ASSERT(ret != NULL); + ii = 0; + for (sel = ret->selector_head.next;ret && sel != &ret->selector_head; sel = sel->next) { + fprintf(stderr, "%s\n", sel->name); + switch(ii) { + case 0: + CU_ASSERT(strcasecmp(sel->name, "a:focus") == 0); + break; + case 1: + CU_ASSERT(strcasecmp(sel->name, "a:link") == 0); + break; + case 2: + CU_ASSERT(strcasecmp(sel->name, "a:visited") == 0); + break; + } + ii++; + } + APR_TERM; + fprintf(stderr, "end %s\n", __func__); +#undef TEST_STRING +} /* * vim:ts=2 et */ -- 2.11.0