From 15eb860550c98fb4dca774a54110f4a8de562995 Mon Sep 17 00:00:00 2001 From: konn Date: Fri, 23 May 2008 09:21:54 +0000 Subject: [PATCH] * added import_style. git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/branches/sandbox@2651 1a406e8e-add9-4483-a2c8-d8cac5b7c224 --- configure.ac | 1 + include/chxj_apache.h | 2 + src/chxj_css.c | 108 ++++++++++++++-- test/chxj_css/test_chxj_css.c | 295 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 398 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index b11b0a7c..cf2e336f 100644 --- a/configure.ac +++ b/configure.ac @@ -264,6 +264,7 @@ AC_CHECK_HEADERS([apr_shm.h apr_global_mutex.h]) AC_CHECK_HEADERS([apr.h]) AC_CHECK_HEADERS([ap_config.h]) AC_CHECK_HEADERS([ap_regex.h],use_pcre_flag="no",use_pcre_flag="yes") +AC_CHECK_HEADERS([libgen.h]) if test "x$use_pcre_flag" = "xyes" ; then if test "x$with_pcre_config" = "x" ; then AC_PATH_PROG(PCRE_CONFIG, pcre-config, no, /usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin) diff --git a/include/chxj_apache.h b/include/chxj_apache.h index 7b3a6857..95c6125a 100644 --- a/include/chxj_apache.h +++ b/include/chxj_apache.h @@ -26,6 +26,7 @@ # include "apr.h" # include "apr_pools.h" # include "apr_tables.h" +# include "apr_uri.h" # define APLOG_EMERG 0 /* system is unusable */ # define APLOG_ALERT 1 /* action must be taken immediately */ # define APLOG_CRIT 2 /* critical conditions */ @@ -72,6 +73,7 @@ typedef struct test_request_rec { char *args; char *hostname; char *unparsed_uri; + apr_uri_t parsed_uri; } request_rec; diff --git a/src/chxj_css.c b/src/chxj_css.c index 10e3f120..f49b8b97 100644 --- a/src/chxj_css.c +++ b/src/chxj_css.c @@ -20,6 +20,8 @@ #include "qs_parse_string.h" #include "apr_pools.h" +#include + /*===========================================================================*/ /* PARSER */ @@ -32,6 +34,9 @@ static css_property_t *s_css_parser_copy_property(apr_pool_t *pool, css_property static css_selector_t *s_new_selector(apr_pool_t *pool, css_stylesheet_t *stylesheet, char *name); static css_selector_t *s_search_selector(css_stylesheet_t *stylesheet, const char *name); static void s_merge_property(css_selector_t *sel, css_property_t *tgt); +static void s_css_parser_from_uri_import_style(CRDocHandler *a_this, GList *a_media_list, CRString *a_uri, CRString *a_uri_default_ns, CRParsingLocation *a_location); +static char *s_path_to_fullurl(apr_pool_t *pool, const char *base_url, const char *base_path, const char *uri); +static char *s_uri_to_base_url(apr_uri_t *uri, apr_pool_t *pool); struct css_app_data { css_stylesheet_t *stylesheet; @@ -52,15 +57,20 @@ chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, css_stylesheet_t *old_ enum CRStatus ret; char *css = NULL; char *charset = NULL; + char *full_url = NULL; apr_size_t srclen; apr_size_t next_pos; css_stylesheet_t *stylesheet = NULL; struct css_app_data app_data; + char *base_url; DBG(r, "start chxj_css_parse_from_uri()"); - css = chxj_serf_get(r, pool, uri); + base_url = s_uri_to_base_url(&r->parsed_uri, pool); + full_url = s_path_to_fullurl(pool, base_url, r->parsed_uri.path, uri); + + css = chxj_serf_get(r, pool, full_url); if (css == NULL) { ERR(r, "%s:%d end chxj_css_parse_from_uri(): serf_get failed: url:[%s]", APLOG_MARK, uri); return NULL; @@ -94,18 +104,19 @@ chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, css_stylesheet_t *old_ stylesheet->selector_head.ref = &stylesheet->selector_head.next; memset(&app_data, 0, sizeof(struct css_app_data)); - app_data.stylesheet = stylesheet; - app_data.selector_list = NULL; + app_data.stylesheet = stylesheet; + app_data.selector_list = NULL; app_data.selector_count = 0; - app_data.pool = pool; - app_data.error_occured = 0; - app_data.r = r; + app_data.pool = pool; + app_data.error_occured = 0; + app_data.r = r; sac_handler->app_data = &app_data; sac_handler->start_selector = s_css_parser_from_uri_start_selector; sac_handler->end_selector = s_css_parser_from_uri_end_selector; sac_handler->property = s_css_parser_from_uri_property; + sac_handler->import_style = s_css_parser_from_uri_import_style; ret = cr_parser_set_sac_handler(parser, sac_handler); if (ret != CR_OK) { @@ -135,14 +146,14 @@ chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, css_stylesheet_t *old_ #undef list_insert #undef list_remove #define list_insert(node, point) do { \ - node->ref = point->ref; \ + node->ref = point->ref; \ *node->ref = node; \ node->next = point; \ point->ref = &node->next; \ } while (0) #define list_remove(node) do { \ - *node->ref = node->next; \ + *node->ref = node->next; \ node->next->ref = node->ref; \ } while (0) @@ -351,6 +362,87 @@ s_css_parser_get_charset(apr_pool_t *pool, const char *src, apr_size_t *next_pos } +static void +s_css_parser_from_uri_import_style(CRDocHandler *a_this, GList *a_media_list, CRString *a_uri, CRString *a_uri_default_ns, CRParsingLocation *a_location) +{ + CB_INIT; + ERROR_OCCORED; + guint ii = 0; + guint len = g_list_length(a_media_list); + int flag = 0; + + for (ii=0; iir->parsed_uri, app_data->pool); + new_url = s_path_to_fullurl(app_data->pool, base_url, app_data->r->parsed_uri.path, import_url); + fprintf(stderr, "base_url:[%s]\n", base_url); + fprintf(stderr, "new_url:[%s]\n", new_url); +/* +css_stylesheet_t * chxj_css_parse_from_uri(request_rec *r, apr_pool_t *pool, css_stylesheet_t *old_stylesheet, const char *uri) +*/ + } + } +} + + +static char * +s_path_to_fullurl(apr_pool_t *pool, const char *base_url, const char *base_path, const char *uri) +{ + char *new_url = NULL; + if (chxj_starts_with(uri, "http")) { + return uri; + } + + if (*uri == '/') { + return apr_pstrcat(pool, base_url, uri, NULL); + } + + new_url = apr_pstrcat(pool, base_url, base_path, NULL); + if (new_url[strlen(new_url)-1] == '/') { + new_url = apr_pstrcat(pool, new_url, uri, NULL); + } + else { + new_url = apr_pstrcat(pool, new_url, "/", uri, NULL); + } + return new_url; +} + + +static char * +s_uri_to_base_url(apr_uri_t *uri, apr_pool_t *pool) +{ + char *new_url = apr_psprintf(pool, "%s://%s", uri->scheme, uri->hostname); + if (strcmp(uri->scheme, "http") == 0) { + if (uri->port != 80 && uri->port != 0) { + new_url = apr_pstrcat(pool, new_url, apr_psprintf(pool, ":%d", uri->port), NULL); + } + } + else if (strcmp(uri->scheme, "https") == 0) { + if (uri->port != 443 && uri->port != 0) { + new_url = apr_pstrcat(pool, new_url, apr_psprintf(pool, ":%d", uri->port), NULL); + } + } + return new_url; +} + + #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 1e84c5fa..1187ef3c 100644 --- a/test/chxj_css/test_chxj_css.c +++ b/test/chxj_css/test_chxj_css.c @@ -9,6 +9,7 @@ #include "chxj_apache.h" #include "apr.h" #include "apr_strings.h" +#include "apr_uri.h" #include "chxj_serf.h" #include "chxj_css.h" #include "chxj_serf.c" @@ -16,11 +17,18 @@ #include "chxj_encoding.c" #include "chxj_url_encode.c" #include "chxj_apache.c" +#include "chxj_str_util.c" void test_chxj_css_parse_from_uri_001(); void test_chxj_css_parse_from_uri_002(); +void test_chxj_css_parse_from_uri_003(); +void test_chxj_css_parse_from_uri_004(); +void test_chxj_css_parse_from_uri_005(); +void test_chxj_css_parse_from_uri_006(); +void test_chxj_css_parse_from_uri_007(); +void test_chxj_css_parse_from_uri_008(); /* pend */ int @@ -32,6 +40,12 @@ main() CU_add_test(css_suite, "test css 001", test_chxj_css_parse_from_uri_001); CU_add_test(css_suite, "test css 002", test_chxj_css_parse_from_uri_002); + CU_add_test(css_suite, "test css 003", test_chxj_css_parse_from_uri_003); + CU_add_test(css_suite, "test css 004", test_chxj_css_parse_from_uri_004); + CU_add_test(css_suite, "test css 005", test_chxj_css_parse_from_uri_005); + CU_add_test(css_suite, "test css 006", test_chxj_css_parse_from_uri_006); + CU_add_test(css_suite, "test css 007", test_chxj_css_parse_from_uri_007); + CU_add_test(css_suite, "test css 008", test_chxj_css_parse_from_uri_008); /* aend */ CU_basic_run_tests(); @@ -105,6 +119,7 @@ void test_log_error(const char *file, int line, int level, apr_status_t status, apr_pool_create(&p, NULL); \ r.pool = p; \ r.hostname = apr_pstrdup(p, "localhost"); \ + apr_uri_parse(p, "http://localhost/abc", &r.parsed_uri); \ } \ while (0) @@ -203,6 +218,286 @@ void test_chxj_css_parse_from_uri_002() APR_TERM; } + + + +char *test_chxj_serf_get003(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "@import url(\"hoge.css\");\nhtml,body { display: none }\nhtml,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_003() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get003; + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "http://localhost/hoge.css"); + CU_ASSERT(ret != NULL); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} + + + + +char *test_chxj_serf_get004(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "@import url(\"hoge.css\");\nhtml,body { display: none }\nhtml,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_004() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get004; + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "/hoge.css"); + CU_ASSERT(ret != NULL); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} + + +char *test_chxj_serf_get005(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "html,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_005() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get005; + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "hoge.css"); + CU_ASSERT(ret != NULL); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} + + + +char *test_chxj_serf_get006(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "html,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_006() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get006; + + ret = chxj_css_parse_from_uri(&r, r.pool, NULL, "../hoge.css"); + CU_ASSERT(ret != NULL); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} + + + +char *test_chxj_serf_get007(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "html,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_007() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get007; + + 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); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} + + + +char *test_chxj_serf_get008(request_rec *r, apr_pool_t *ppool, const char *uri_path) +{ + static char *css = "html,body { display: none }"; + + return css; +} +void test_chxj_css_parse_from_uri_008() +{ + css_stylesheet_t *ret; + APR_INIT; + chxj_serf_get = test_chxj_serf_get008; + + 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); + { + css_selector_t *cur; + int ii = 0; + int jj = 0; + for (cur = ret->selector_head.next; cur != &ret->selector_head; cur = cur->next) { + css_property_t *cur_prop; + switch(ii) { + case 0: CU_ASSERT(strcmp(cur->name, "html") == 0); break; + case 1: CU_ASSERT(strcmp(cur->name, "body") == 0); break; + } + jj = 0; + for (cur_prop = cur->property_head.next; cur_prop != &cur->property_head; cur_prop = cur_prop->next) { + switch (jj) { + case 0: + CU_ASSERT(strcmp(cur_prop->name, "display") == 0); + CU_ASSERT(strcmp(cur_prop->value, "none") == 0); + break; + } + jj++; + } + CU_ASSERT(jj == 1); + ii++; + } + CU_ASSERT(ii == 2); + } + + + APR_TERM; +} /* * vim:ts=2 et */ -- 2.11.0