OSDN Git Service

* added import_style.
authorkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Fri, 23 May 2008 09:21:54 +0000 (09:21 +0000)
committerkonn <konn@1a406e8e-add9-4483-a2c8-d8cac5b7c224>
Fri, 23 May 2008 09:21:54 +0000 (09:21 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/modchxj/mod_chxj/branches/sandbox@2651 1a406e8e-add9-4483-a2c8-d8cac5b7c224

configure.ac
include/chxj_apache.h
src/chxj_css.c
test/chxj_css/test_chxj_css.c

index b11b0a7..cf2e336 100644 (file)
@@ -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)
index 7b3a685..95c6125 100644 (file)
@@ -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;
 
 
index 10e3f12..f49b8b9 100644 (file)
@@ -20,6 +20,8 @@
 #include "qs_parse_string.h"
 #include "apr_pools.h"
 
+#include <libgen.h>
+
 
 /*===========================================================================*/
 /* 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; 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)
index 1e84c5f..1187ef3 100644 (file)
@@ -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"
 #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
  */