Files

213 lines
4.7 KiB
HolyC

I64 roundUp(I64 numToRound, I64 multiple) {
if (multiple == 0)
return numToRound;
I64 remainder = Abs(numToRound) % multiple;
if (remainder == 0)
return numToRound;
if (numToRound < 0)
return -(Abs(numToRound) - remainder);
else
return numToRound + multiple - remainder;
}
#define WEB_RESPONSE_BUFFER_SIZE 1048576 * 4
U8 *web_page_buffer = CAlloc(WEB_RESPONSE_BUFFER_SIZE);
U8 *web_resource_buffer = CAlloc(WEB_RESPONSE_BUFFER_SIZE);
HttpUrl *web_current_url = NULL;
/* clang-format off */
#include "TGL";
#include "Src/Doc";
#include "Src/Json";
#include "Src/MD5";
#include "Src/HTMLTokenizer";
#include "Src/HTMLRenderer";
/* clang-format on */
class WebPage {
U8 sig[4];
@http_url *url;
U8 title[STR_LEN];
CDoc *render_doc;
JsonArray *animated_sprites;
I64 num_of_animated_sprites;
};
class WebSession {
U8 sig[4];
JsonArray *history;
I64 page_index;
};
WebPage *@init_new_webpage() {
WebPage *p = CAlloc(sizeof(WebPage));
MemCpy(&p->sig, "WebP", 4); // WebPage class signature
p->render_doc = DocNew;
DocMax(p->render_doc);
p->animated_sprites =
Json.CreateArray(); // Create array to store animated sprite data
return p;
}
I64 Navigate(CDoc *doc, U8 *url_string) {
if (!url_string) {
PopUpOk("ERROR: URL string can not be empty.");
return -1;
}
U8 buf[512];
WebPage *p = @init_new_webpage;
StrPrint(buf, "web_current_url: 0x%08x\n", web_current_url);
@vbox_debug_print(buf);
p->url = @expand_url_from_string(url_string);
StrPrint(buf, "new p->url is: 0x%08x\n", p->url);
@vbox_debug_print(buf);
if (!p->url) {
PopUpOk(url_string);
return 0;
}
// Store current parsed URL instance
if (p->url) {
web_current_url = p->url;
StrPrint(buf, "Set web_current_url to: 0x%08x\n", p->url);
@vbox_debug_print(buf);
}
CDoc *render_doc = p->render_doc;
DocClear(render_doc);
progress1 = 0;
progress1_max = 1;
StrPrint(progress1_desc, "Loading web page ...");
MemSet(web_page_buffer, NULL, WEB_RESPONSE_BUFFER_SIZE);
@http_response *resp = @http_get(p->url, web_page_buffer);
U8 *buffer = resp->body.data;
I64 content_length = 0;
I64 content_type = 0;
I64 i;
for (i = 0; i < resp->headers.count; i++) {
if (!StrICmp(resp->headers.header[i]->key, "Content-Length")) {
content_length = Str2I64(resp->headers.header[i]->value);
// i = resp->headers.count;
}
if (!StrICmp(resp->headers.header[i]->key, "Content-Type")) {
if (!MemCmp(resp->headers.header[i]->value, "text/html", 9))
content_type = 1;
// i = resp->headers.count;
}
}
if (content_type == 0) {
// text/plain
DocClear(render_doc);
DocPrint(render_doc, "\dWW\d\dFG,8\d");
DocPutS(render_doc, buffer);
goto navigate_finish;
}
I64 num_of_images = 0;
StrPrint(progress1_desc, "Processing HTML data ...");
Node *node_tree = @html_tokenize_and_create_node_tree(
buffer, WEB_RESPONSE_BUFFER_SIZE, &num_of_images);
progress1_max = num_of_images;
DocClear(render_doc);
DocPrint(render_doc, "\dWW\d\dFG,8\d");
@render_node_tree(NULL, render_doc, node_tree);
@calculate_indents_for_sprites(render_doc);
navigate_finish:
progress1_max = 0;
DocTop(render_doc);
DocClear(DocPut);
DocInsDoc(DocPut, render_doc);
DocTop(DocPut);
// JsonItem *history_item = CAlloc(sizeof(JsonItem));
// history_item->value = p;
// Json.AppendItem(s->history, p);
// s->page_index++;
return 0;
}
U0 @init_new_websession(CDoc *doc) {
WebSession *s = CAlloc(sizeof(WebSession));
MemCpy(&s->sig, "WebS", 4); // WebSession class signature
s->history = Json.CreateArray(); // Create array to store web page history
s->page_index = -1; // Current page index in history array
doc->user_data = s; // Assign WebSession class instance to specified CDoc
}
Bool @cmd_go_to_url(CTask *doc) {
U8 *url_string = @popup_get_str("Web - World Wide Web browser for TempleOS",
"Go to URL: ");
if (url_string) {
if (StrLen(url_string)) {
Navigate(doc, url_string);
return TRUE;
}
}
return FALSE;
}
U0 @init_web_cache_folder() {
U8 buf[512];
StrCpy(buf, "::/Tmp");
if (!FileFind(buf))
DirMk(buf);
StrCpy(buf + StrLen(buf), "/Web");
if (!FileFind(buf))
DirMk(buf);
StrCpy(buf + StrLen(buf), "/Cache");
if (!FileFind(buf))
DirMk(buf);
}
U0 Web() {
web_current_url = NULL;
U8 *res;
@init_web_cache_folder;
@task_doc_push('Web');
//@init_new_websession(DocPut);
if (!@cmd_go_to_url(DocPut))
goto web_exit;
while (1) {
res = GetStr;
if (!StrCmp(res, ""))
goto web_exit;
}
web_exit:
DocClear(DocPut);
@task_doc_pop;
}