#include "qs_parse_string.h"
#include "apr_pools.h"
+#include <libgen.h>
+
/*===========================================================================*/
/* PARSER */
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;
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;
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) {
#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)
}
+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; ii<len; ii++) {
+ char *str = cr_string_peek_raw_str(g_list_nth_data(a_media_list, ii));
+ if (('h' == *str || 'H' == *str) && strcasecmp(str, "handheld") == 0) {
+ flag = 1;
+ break;
+ }
+ if (('a' == *str || 'A' == *str) && strcasecmp(str, "all") == 0) {
+ flag = 1;
+ break;
+ }
+ }
+ if (flag || len == 0) {
+ if (a_uri) {
+ apr_uri_t uri;
+ char *new_url = NULL;
+ char *import_url = cr_string_peek_raw_str(a_uri);
+ char *base_url = NULL;
+
+ fprintf(stderr, "import_url:[%s]\n", import_url);
+ base_url = s_uri_to_base_url(&app_data->r->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)
#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"
#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
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();
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)
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
*/