<!DOCTYPE html>
<html>
<head>
-<style>
-#a /*css comment*/
-{
- color:blue;
- text-align:center;
-}
-
-p.red
-{
- color:red;
-}
-</style>
+<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
--- /dev/null
+#a /*css comment*/
+{
+ color:blue;
+ text-align:center;
+}
+
+p.red
+{
+ color:red;
+}
int abc_css_parse(abc_obj_t* css)
{
- abc_char_t* c;
- abc_char_t* c2;
- abc_io_t* io = abc_io_array[ABC_PROTO_STR];
+ scf_string_t* spath = NULL;
+ abc_char_t* c;
+ abc_char_t* c2;
+ abc_io_t* io = NULL;
+ abc_obj_t* href;
+ char* path;
+ int n;
+
+ switch (css->type)
+ {
+ case ABC_HTML_STYLE:
+ if (!css->text)
+ return 0;
+
+ n = 0;
+ io = abc_io_array[ABC_PROTO_STR];
+ path = css->text->data;
+ break;
+
+ case ABC_HTML_LINK:
+ href = abc_obj_get_attr(css, ABC_HTML_ATTR_HREF);
+ if (!href)
+ return 0;
+
+ n = __io_url_path(&io, &spath, css->file->data, href->value->data);
+ if (n < 0)
+ return n;
+
+ path = spath->data;
+ break;
+ default:
+ return 0;
+ break;
+ };
+
+ scf_logw("css->file: %s, path: %s\n", css->file->data, path);
css->io.proto = io->proto;
css->io.priv = NULL;
css->text_line = 1;
css->text_pos = 0;
- int ret = io->open(&css->io, css->text->data);
+ int ret = io->open(&css->io, path + n);
+ if (spath) {
+ scf_string_free(spath);
+ spath = NULL;
+ }
if (ret < 0)
return ret;
scf_list_t* l;
scf_list_t* l2;
+ scf_list_t* l3;
+ abc_obj_t* head;
abc_obj_t* css;
abc_obj_t* label;
abc_obj_t* attr;
- css = abc_obj_find_type(html->root, ABC_HTML_STYLE);
- if (!css)
+ head = abc_obj_find_type(html->root, ABC_HTML_HEAD);
+ if (!head)
return 0;
- for (l = scf_list_head(&css->childs); l != scf_list_sentinel(&css->childs); l = scf_list_next(l)) {
- label = scf_list_data(l, abc_obj_t, list);
+ for (l = scf_list_head(&head->childs); l != scf_list_sentinel(&head->childs); l = scf_list_next(l)) {
+ css = scf_list_data(l, abc_obj_t, list);
- if (ABC_CSS_ID == label->type || ABC_CSS_CLASS == label->type)
+ if (ABC_HTML_LINK == css->type)
{
- attr = abc_obj_get_attr(obj, label->type);
+ attr = abc_obj_get_attr(css, ABC_HTML_ATTR_TYPE);
if (!attr)
continue;
- if (strcmp(attr->value->data, label->text->data + label->css_dot + 1))
+ if (strcmp(attr->value->data, "text/css"))
continue;
- if (label->css_dot > 0) {
- if (strncmp(obj->keys[0], label->text->data, label->css_dot))
+ } else if (ABC_HTML_STYLE != css->type)
+ continue;
+
+ for (l2 = scf_list_head(&css->childs); l2 != scf_list_sentinel(&css->childs); l2 = scf_list_next(l2)) {
+ label = scf_list_data(l2, abc_obj_t, list);
+
+ if (ABC_CSS_ID == label->type || ABC_CSS_CLASS == label->type)
+ {
+ attr = abc_obj_get_attr(obj, label->type);
+ if (!attr)
continue;
- }
- } else if (label->type != obj->type)
- continue;
+ if (strcmp(attr->value->data, label->text->data + label->css_dot + 1))
+ continue;
+
+ if (label->css_dot > 0) {
+ if (strncmp(obj->keys[0], label->text->data, label->css_dot))
+ continue;
+ }
- for (l2 = scf_list_head(&label->attrs); l2 != scf_list_sentinel(&label->attrs); l2 = scf_list_next(l2)) {
- attr = scf_list_data(l2, abc_obj_t, list);
+ } else if (label->type != obj->type)
+ continue;
- abc_recursive_set_attr(obj, attr->type, attr->value->data);
+ for (l3 = scf_list_head(&label->attrs); l3 != scf_list_sentinel(&label->attrs); l3 = scf_list_next(l3)) {
+ attr = scf_list_data(l3, abc_obj_t, list);
+
+ abc_recursive_set_attr(obj, attr->type, attr->value->data);
+ }
}
}
// HTML attrs
static char* src_keys[] = {"src", "源", NULL};
+static char* rel_keys[] = {"rel", "关系", NULL};
static char* href_keys[] = {"href", "地址", NULL};
static char* width_keys[] = {"width", "宽度", NULL};
static char* head_keys[] = {"head", "头部", NULL};
static char* body_keys[] = {"body", "主体", NULL};
static char* form_keys[] = {"form", "表单", NULL};
+static char* link_keys[] = {"link", "链接", NULL};
static char* div_keys[] = {"div", "分区", NULL};
static char* img_keys[] = {"img", "图片", NULL};
{font_color_keys, "blue", ABC_HTML_ATTR_FONT_COLOR, 0},
};
+static html_attr_t link_attrs[] =
+{
+ {rel_keys, "", ABC_HTML_ATTR_REL, ABC_HTML_FLAG_SHOW},
+ {type_keys, "", ABC_HTML_ATTR_TYPE, ABC_HTML_FLAG_SHOW},
+ {href_keys, "", ABC_HTML_ATTR_HREF, ABC_HTML_FLAG_SHOW},
+};
+
static html_attr_t img_attrs[] =
{
{src_keys, "", ABC_HTML_ATTR_SRC, ABC_HTML_FLAG_SHOW},
{a_keys, ABC_HTML_A, abc_number_of(a_attrs), a_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{img_keys, ABC_HTML_IMG, abc_number_of(img_attrs), img_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE | ABC_HTML_FLAG_SHOW},
+ {link_keys, ABC_HTML_LINK, abc_number_of(link_attrs), link_attrs, ABC_HTML_FLAG_OPEN | ABC_HTML_FLAG_SHOW},
{form_keys, ABC_HTML_FORM, abc_number_of(form_attrs), form_attrs, ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
{input_keys, ABC_HTML_INPUT, abc_number_of(input_attrs), input_attrs, ABC_HTML_FLAG_OPEN | ABC_HTML_FLAG_SHOW},
{
html_label_t* label;
abc_obj_t* obj;
+ abc_obj_t* type;
scf_string_t* key = scf_string_cstr_len(c->utf8, c->len);
return -1;
break;
- case ABC_HTML_STYLE:
- if (obj->text) {
- scf_logi("\033[33mcss: %s\033[0m\n", obj->text->data);
+ case ABC_HTML_LINK:
+ type = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
+ if (!type)
+ break;
- if (abc_css_parse(obj) < 0)
- return -1;
- }
+ if (strcmp(type->value->data, "text/css"))
+ break;
+
+ case ABC_HTML_STYLE:
+ if (abc_css_parse(obj) < 0)
+ return -1;
break;
case ABC_HTML_VIDEO:
int (*post )(abc_io_t* io, const char* path, scf_string_t* content);
};
-abc_char_t* __io_pop_char (abc_io_t* io);
-void __io_push_char(abc_io_t* io, abc_char_t* c);
+abc_char_t* __io_pop_char (abc_io_t* io);
+void __io_push_char(abc_io_t* io, abc_char_t* c);
+int __io_url_path (abc_io_t** io, scf_string_t** spath, const char* main, const char* current);
#endif
c->next = io->tmp_list;
io->tmp_list = c;
}
+
+int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const char* current)
+{
+ scf_string_t* path = scf_string_alloc();
+ if (!path)
+ return -ENOMEM;
+
+ int prefix = -1;
+ int proto;
+ int ret;
+
+ if (main) {
+ if ('.' == main[0] || '/' == main[0]) {
+ prefix = 0;
+ proto = ABC_PROTO_FILE;
+
+ } else if (!strncmp(main, "file://", 7)) {
+ prefix = 7;
+ proto = ABC_PROTO_FILE;
+
+ } else if (!strncmp(main, "http://", 7)) {
+ prefix = 7;
+ proto = ABC_PROTO_HTTP;
+ } else {
+ scf_loge("proto of '%s' NOT support\n", main);
+
+ scf_string_free(path);
+ return -EINVAL;
+ }
+
+ const char* p = main + prefix;
+ const char* p2 = NULL;
+
+ while (*p) {
+ if ('/' == *p)
+ p2 = p;
+ p++;
+ }
+
+ if (!p2)
+ p2 = p;
+
+ ret = scf_string_cat_cstr_len(path, main, (size_t)(p2 - main));
+ if (ret < 0) {
+ scf_string_free(path);
+ return ret;
+ }
+ }
+
+ if (!strncmp(current, "file://", 7)) {
+ prefix = 7;
+ proto = ABC_PROTO_FILE;
+
+ ret = scf_string_copy_cstr(path, current);
+
+ } else if (!strncmp(current, "http://", 7)) {
+ prefix = 7;
+ proto = ABC_PROTO_HTTP;
+
+ ret = scf_string_copy_cstr(path, current);
+ } else {
+ if (prefix < 0) {
+ prefix = 0;
+ proto = ABC_PROTO_FILE;
+
+ } else if ('/' != current[0]) {
+
+ ret = scf_string_cat_cstr_len(path, "/", 1);
+ if (ret < 0) {
+ scf_string_free(path);
+ return ret;
+ }
+ }
+
+ ret = scf_string_cat_cstr(path, current);
+ }
+
+ if (ret < 0) {
+ scf_string_free(path);
+ return ret;
+ }
+
+ *io = abc_io_array[proto];
+ *spath = path;
+ return prefix;
+}
ABC_HTML_SCRIPT,
ABC_HTML_STYLE,
+ ABC_HTML_LINK,
ABC_HTML_B,
ABC_HTML_I,
ABC_HTML_ATTR_HREF,
ABC_HTML_ATTR_SRC,
+ ABC_HTML_ATTR_REL,
ABC_HTML_ATTR_FOR,
return 0;
}
+int scf_string_copy_cstr_len(scf_string_t* s0, const char* str, size_t len)
+{
+ scf_string_t s1;
+ s1.capacity = -1;
+ s1.len = len;
+ s1.data = (char*)str;
+
+ return scf_string_copy(s0, &s1);
+}
+
+int scf_string_copy_cstr(scf_string_t* s0, const char* str)
+{
+ return scf_string_copy_cstr_len(s0, str, strlen(str));
+}
+
int scf_string_cat(scf_string_t* s0, const scf_string_t* s1)
{
if (!s0 || !s1 || !s0->data || !s1->data)
int scf_string_cmp_cstr_len(const scf_string_t* s0, const char* str, size_t len);
int scf_string_copy(scf_string_t* s0, const scf_string_t* s1);
+int scf_string_cat (scf_string_t* s0, const scf_string_t* s1);
-int scf_string_cat(scf_string_t* s0, const scf_string_t* s1);
+int scf_string_copy_cstr(scf_string_t* s0, const char* str);
+int scf_string_cat_cstr (scf_string_t* s0, const char* str);
-int scf_string_cat_cstr(scf_string_t* s0, const char* str);
-
-int scf_string_cat_cstr_len(scf_string_t* s0, const char* str, size_t len);
+int scf_string_copy_cstr_len(scf_string_t* s0, const char* str, size_t len);
+int scf_string_cat_cstr_len (scf_string_t* s0, const char* str, size_t len);
int scf_string_match_kmp(const scf_string_t* T, const scf_string_t* P, scf_vector_t* offsets);
int scf_string_match_kmp_cstr(const uint8_t* T, const uint8_t* P, scf_vector_t* offsets);
[ABC_HTML_SCRIPT] = abc_layout_empty,
[ABC_HTML_STYLE] = abc_layout_empty,
+ [ABC_HTML_LINK] = abc_layout_empty,
[ABC_HTML_B] = abc_layout_h1,
[ABC_HTML_I] = abc_layout_h1,
[ABC_HTML_SCRIPT] = &abc_render_empty,
[ABC_HTML_STYLE] = &abc_render_empty,
+ [ABC_HTML_LINK] = &abc_render_empty,
[ABC_HTML_B] = &abc_render_h1,
[ABC_HTML_I] = &abc_render_h1,