diff options
-rw-r--r-- | apps/browser.c | 87 | ||||
-rw-r--r-- | kernel/features/net.c | 15 | ||||
-rw-r--r-- | libtxt/Makefile | 2 | ||||
-rw-r--r-- | libtxt/html.c | 124 | ||||
-rw-r--r-- | libtxt/inc/html.h | 12 | ||||
-rw-r--r-- | libtxt/xml.c | 4 | ||||
-rw-r--r-- | res/www/index.html | 1 |
7 files changed, 138 insertions, 107 deletions
diff --git a/apps/browser.c b/apps/browser.c index 83292e9..160b626 100644 --- a/apps/browser.c +++ b/apps/browser.c @@ -53,80 +53,6 @@ void print_indent(char *buf, u32 n) strcat(buf, "\t"); } -void parse(void *data, u32 len, char *out) -{ - struct xml_token tokens[128]; - struct xml parser; - xml_init(&parser); - void *buffer = data; - len = strlen(data); - out[0] = '\0'; - enum xml_error err = xml_parse(&parser, buffer, len, tokens, 128); - - if (err != XML_SUCCESS) { - printf("\nXML parse error: %d\n", err); - return; - } - - u32 indent = 0; - char name[16] = { 0 }; - for (u32 i = 0; i < parser.ntokens; i++) { - const struct xml_token *token = tokens + i; - name[0] = '\0'; - switch (token->type) { - case XML_START_TAG: - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - if (html_self_closing(name)) - print_indent(out, indent); - else - print_indent(out, indent++); - strcat(out, name); - strcat(out, "\n"); - break; - case XML_END_TAG: - print_indent(out, --indent); - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - strcat(out, name); - strcat(out, "/\n"); - break; - case XML_CHARACTER: - if (token->end_pos == token->start_pos + 2) { - const char *ptr = (char *)buffer + token->start_pos; - - if (ptr[0] == '\r' && ptr[1] == '\n') - continue; - } - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - char *clean_name = name; - for (u32 j = 0; j < strlen(name); j++) { - if (name[j] == ' ' || name[j] == '\n' || name[j] == '\r' || - name[j] == '\t') { - clean_name++; - } else { - break; - } - } - if (!strlen(clean_name)) - break; - print_indent(out, indent++); - strcat(out, clean_name); - strcat(out, "\n"); - indent--; - break; - default: - break; - } - - i += token->size; - } -} - void on_submit(void *event, struct element *box) { (void)event; @@ -152,22 +78,20 @@ void on_submit(void *event, struct element *box) ip = dns_request(url); } - struct element_text_box *l = output->data; struct element_label *c = code_label->data; struct socket *socket = net_open(S_TCP); if (socket && net_connect(socket, ip, port, NET_TIMEOUT)) { net_send(socket, query, strlen(query)); char buf[4096] = { 0 }; - char parsed[4096] = { 0 }; - if (!net_receive(socket, buf, 4096, NET_TIMEOUT)) + if (!net_receive(socket, buf, 4096, NET_TIMEOUT) || + !html_render(output, http_data(buf), 4096)) return; - parse(http_data(buf), 4096, parsed); - l->text = parsed[0] ? parsed : http_data(buf); + c->text = http_code(buf); c->color_fg = status_color(c->text); } else { - l->text = strdup("Can't connect to server."); + /* l->text = strdup("Can't connect to server."); */ c->text = strdup("000"); c->color_fg = COLOR_RED; } @@ -183,8 +107,7 @@ int main() code_label = gui_add_label(root, 0, 0, FONT_24, "000", COLOR_BLACK, COLOR_WHITE); struct element *text_input = gui_add_text_input(root, LABEL_WIDTH, 0, 100, FONT_24, COLOR_WHITE, COLOR_BLACK); - output = gui_add_text_box(root, 0, FONT_HEIGHT + 2, 100, 100, FONT_16, - "Enter URL and press Enter :)", COLOR_WHITE, COLOR_BLACK); + output = gui_add_container(root, 0, FONT_HEIGHT + 2, 100, 100, COLOR_GREEN); text_input->event.on_submit = on_submit; diff --git a/kernel/features/net.c b/kernel/features/net.c index 3fa28c9..cc46cd4 100644 --- a/kernel/features/net.c +++ b/kernel/features/net.c @@ -863,19 +863,4 @@ void net_install(void) loop(); return; } - - // Request - /* struct socket *socket = net_open(S_TCP); */ - /* if (socket && net_connect(socket, ip(91, 89, 253, 227), 80)) */ - /* net_send(socket, strdup(http_req), strlen(http_req)); */ - /* else */ - /* print("Couldn't connect!\n"); */ - - // Server // TODO: Serve using sockets - /* struct socket *socket2 = net_open(S_TCP); */ - /* socket2->src_port = 8000; */ - /* while (socket2->prot.tcp.state != 3) */ - /* ; */ - /* while (socket2->prot.tcp.state == 3) */ - /* net_send(socket2, strdup(http_res), strlen(http_res)); */ } diff --git a/libtxt/Makefile b/libtxt/Makefile index 3536250..087b54c 100644 --- a/libtxt/Makefile +++ b/libtxt/Makefile @@ -6,7 +6,7 @@ LD = ccache ../cross/opt/bin/i686-elf-ld AR = ccache ../cross/opt/bin/i686-elf-ar WARNINGS = -Wall -Wextra -pedantic-errors -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wno-long-long -CFLAGS = $(WARNINGS) -nostdlib -nostdinc -fno-builtin -mgeneral-regs-only -std=c99 -m32 -Iinc/ -I../libc/inc/ -fPIE -Duserspace -Ofast +CFLAGS = $(WARNINGS) -nostdlib -nostdinc -fno-builtin -mgeneral-regs-only -std=c99 -m32 -Iinc/ -I../libc/inc/ -I../libgui/inc/ -fPIE -Duserspace -Ofast all: libtxt diff --git a/libtxt/html.c b/libtxt/html.c index 0c07323..171de78 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -1,14 +1,19 @@ // MIT License, Copyright (c) 2020 Marvin Borner // HTML parsing is mainly based on the XML parser +#include <assert.h> +#include <gui.h> +#include <html.h> +#include <list.h> +#include <mem.h> #include <print.h> #include <str.h> +#include <xml.h> -int html_self_closing(const char *tag) +static int is_self_closing(const char *tag) { - // TODO: Add 'meta'? - const char *void_elements[] = { "area", "base", "br", "col", "embed", "hr", "img", - "input", "link", "param", "source", "track", "wbr" }; + const char *void_elements[] = { "area", "base", "br", "col", "embed", "hr", "img", + "input", "link", "meta", "param", "source", "track", "wbr" }; for (u32 i = 0; i < sizeof(void_elements) / sizeof(void_elements[0]); ++i) { if (!strcmp(void_elements[i], tag)) @@ -16,3 +21,114 @@ int html_self_closing(const char *tag) } return 0; } + +static struct dom *new_object(const char *tag, struct dom *parent) +{ + struct dom *object = malloc(sizeof(*object)); + object->tag = strdup(tag); + object->parent = parent; + object->content = NULL; + object->children = list_new(); + return object; +} + +static void print_dom(struct dom *dom, u32 level) +{ + struct node *iterator = dom->children->head; + while (iterator != NULL) { + struct dom *obj = iterator->data; + for (u32 i = 0; i < level; i++) + print("\t"); + printf("'%s': '%s'\n", obj->tag, obj->content ? obj->content : ""); + if (obj->children->head) + print_dom(obj, level + 1); + iterator = iterator->next; + } +} + +static struct dom *generate_dom(char *data, u32 length) +{ + struct xml_token tokens[128]; + struct xml parser; + xml_init(&parser); + void *buffer = data; + enum xml_error err = xml_parse(&parser, buffer, length, tokens, 128); + + if (err != XML_SUCCESS && err != XML_ERROR_BUFFERDRY) { + printf("\nXML parse error: %d\n", err); + return 0; + } + + struct dom *root = new_object("root", NULL); + struct dom *current = root; + + char name[256] = { 0 }; + for (u32 i = 0; i < parser.ntokens; i++) { + const struct xml_token *token = tokens + i; + name[0] = '\0'; + switch (token->type) { + case XML_START_TAG: + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + current = new_object(name, current); + printf("Adding %s to %s\n", current->tag, current->parent->tag); + list_add(current->parent->children, current); + break; + case XML_END_TAG: + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + assert(current && !strcmp(name, current->tag)); + current = current->parent; + break; + case XML_CHARACTER: + if (!current) + continue; + + if (token->end_pos == token->start_pos + 2) { + const char *ptr = (char *)buffer + token->start_pos; + + if (ptr[0] == '\r' && ptr[1] == '\n') + continue; + } + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + char *clean_name = name; + for (u32 j = 0; j < strlen(name); j++) { + if (name[j] == ' ' || name[j] == '\n' || name[j] == '\r' || + name[j] == '\t') { + clean_name++; + } else { + break; + } + } + if (!strlen(clean_name)) + break; + current->content = strdup(clean_name); + break; + default: + break; + } + + i += token->size; + } + + print("GENERATED!\n"); + print_dom(root, 0); + return root; +} + +int html_render_dom(struct element *container, struct dom *dom) +{ + (void)container; + (void)dom; + return 1; +} + +int html_render(struct element *container, char *data, u32 length) +{ + struct dom *dom = generate_dom(data, length); + return dom && html_render_dom(container, dom); +} diff --git a/libtxt/inc/html.h b/libtxt/inc/html.h index dd2b59f..4eaca0b 100644 --- a/libtxt/inc/html.h +++ b/libtxt/inc/html.h @@ -4,6 +4,16 @@ #ifndef HTML_H #define HTML_H -int html_self_closing(const char *tag); +#include <def.h> +#include <list.h> + +struct dom { + char *tag; + char *content; + struct dom *parent; + struct list *children; +}; + +int html_render(struct element *container, char *data, u32 length); #endif diff --git a/libtxt/xml.c b/libtxt/xml.c index b92181b..f40b289 100644 --- a/libtxt/xml.c +++ b/libtxt/xml.c @@ -485,10 +485,6 @@ enum xml_error xml_parse(struct xml *state, const char *buffer, u32 buffer_lengt state_commit(state, &temp); } - // TODO: Only for self-closing tags - if (end - lt == 0) - break; - if (end - lt < TAG_MINSIZE) return XML_ERROR_BUFFERDRY; diff --git a/res/www/index.html b/res/www/index.html index 49e1b07..59e08fa 100644 --- a/res/www/index.html +++ b/res/www/index.html @@ -8,5 +8,6 @@ </head> <body> <h1>This is a test page.</h1> + <hr /> </body> </html> |