mirror of
https://git.checksum.fail/alec/Web.git
synced 2026-05-26 17:49:08 +00:00
213 lines
4.7 KiB
HolyC
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;
|
|
}
|