Applications/Internet/Cyberia.app: Initial support for FORM method=get
Now we can search with simple engines like Wiby and FrogFind.
This commit is contained in:
parent
4ef542cf32
commit
ebfaa0254c
1 changed files with 169 additions and 14 deletions
|
@ -37,17 +37,81 @@ class @browser
|
||||||
U8* search_query;
|
U8* search_query;
|
||||||
};
|
};
|
||||||
|
|
||||||
@browser* browser = CAlloc(sizeof(@browser));
|
@browser* browser = CAlloc(sizeof(@browser), Fs);
|
||||||
|
|
||||||
|
I64 @cyberia_is_alphanum(I64 c)
|
||||||
|
{
|
||||||
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
U8* @cyberia_urlencode_str(U8* str, I64* output_len)
|
||||||
|
{
|
||||||
|
if (str == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
I64 len = StrLen(str);
|
||||||
|
U8* encoded_str = NULL;
|
||||||
|
U8* dest;
|
||||||
|
I64 encoded_len = 0;
|
||||||
|
U8* p;
|
||||||
|
I64 c;
|
||||||
|
Bool contains_plus = FALSE;
|
||||||
|
|
||||||
|
// First pass: calculate the exact required length
|
||||||
|
p = str;
|
||||||
|
while (*p) {
|
||||||
|
c = *p;
|
||||||
|
// Check if the character should NOT be encoded
|
||||||
|
if (@cyberia_is_alphanum(c) || c == '-' || c == '_' || c == '.') {
|
||||||
|
encoded_len++;
|
||||||
|
} else if (c == ' ') {
|
||||||
|
encoded_len++; // Will be replaced by '+'
|
||||||
|
contains_plus = TRUE;
|
||||||
|
} else {
|
||||||
|
encoded_len += 3; // Will be replaced by %XX
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_len = encoded_len;
|
||||||
|
|
||||||
|
if (encoded_len == StrLen(str) && !contains_plus)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
// Allocate memory for the encoded string + null terminator
|
||||||
|
encoded_str = CAlloc(encoded_len + 1, browser->task);
|
||||||
|
if (!encoded_str)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Second pass: build the encoded string
|
||||||
|
dest = encoded_str;
|
||||||
|
p = str;
|
||||||
|
while (*p) {
|
||||||
|
c = *p;
|
||||||
|
if (@cyberia_is_alphanum(c) || c == '-' || c == '_' || c == '.') {
|
||||||
|
*dest++ = c;
|
||||||
|
} else if (c == ' ') {
|
||||||
|
*dest++ = '+';
|
||||||
|
} else {
|
||||||
|
StrPrint(dest, "%%%02X", c);
|
||||||
|
dest += 3;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
*dest = '\0';
|
||||||
|
return encoded_str;
|
||||||
|
}
|
||||||
|
|
||||||
browser->history = Json.CreateArray(Fs);
|
browser->history = Json.CreateArray(Fs);
|
||||||
browser->history_index = -1;
|
browser->history_index = -1;
|
||||||
browser->renderer = NULL;
|
browser->renderer = NULL;
|
||||||
browser->task = Fs;
|
browser->task = Fs;
|
||||||
browser->fetch_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE);
|
browser->fetch_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE, browser->task);
|
||||||
browser->go_to_url_string = NULL;
|
browser->go_to_url_string = NULL;
|
||||||
browser->javascript_link_handlers = Json.CreateObject(Fs);
|
browser->javascript_link_handlers = Json.CreateObject(Fs);
|
||||||
browser->lazyload_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE);
|
browser->lazyload_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE, browser->task);
|
||||||
browser->lazyload_timeout_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE);
|
browser->lazyload_timeout_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE, browser->task);
|
||||||
|
|
||||||
U0 @cyberia_win_close(Window* win)
|
U0 @cyberia_win_close(Window* win)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +160,96 @@ U0 @cyberia_link_clicked(Widget* widget)
|
||||||
Spawn(&@cyberia_navigate);
|
Spawn(&@cyberia_navigate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_collect_form_nodes(JsonArray* array, @html_dom_node* node)
|
||||||
|
{
|
||||||
|
if (!array || !node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!StrICmp(node->tagName, "input") || !StrICmp(node->tagName, "textarea")) {
|
||||||
|
if (node->attributes->@("name")) {
|
||||||
|
array->append(node, JSON_NUMBER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
I64 i;
|
||||||
|
if (node->children->length) {
|
||||||
|
for (i = 0; i < node->children->length; i++)
|
||||||
|
@cyberia_collect_form_nodes(array, node->children->@(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U0 @cyberia_form_submit_clicked(Widget* widget)
|
||||||
|
{
|
||||||
|
if (!widget || !widget->data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@html_dom_node* form_node = @self_or_ancestor_matches_tag_name(widget->data, "form");
|
||||||
|
|
||||||
|
if (!form_node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!form_node->attributes->@("method"))
|
||||||
|
form_node->attributes->set("method", "get", JSON_STRING);
|
||||||
|
|
||||||
|
if (!form_node->attributes->@("action"))
|
||||||
|
form_node->attributes->set("action", "#", JSON_STRING);
|
||||||
|
|
||||||
|
I64 i;
|
||||||
|
U8* method = form_node->attributes->@("method");
|
||||||
|
U8* action = @resolve_href(browser->renderer, form_node->attributes->@("action"));
|
||||||
|
@html_dom_node* element_node;
|
||||||
|
|
||||||
|
"method: \"%s\", action: \"%s\"\n", method, action;
|
||||||
|
|
||||||
|
JsonArray* form_elements = Json.CreateArray(browser->renderer->task);
|
||||||
|
@cyberia_collect_form_nodes(form_elements, form_node);
|
||||||
|
"form element count: %d\n", form_elements->length;
|
||||||
|
|
||||||
|
U8 get_request_str[1024];
|
||||||
|
|
||||||
|
if (!StrICmp(method, "get")) {
|
||||||
|
StrPrint(get_request_str, "%s?", action);
|
||||||
|
for (i = 0; i < form_elements->length; i++) {
|
||||||
|
element_node = form_elements->@(i);
|
||||||
|
U8* name = element_node->attributes->@("name");
|
||||||
|
U8* raw_value = "";
|
||||||
|
U8* encoded_value = NULL;
|
||||||
|
I64 encoded_value_length = 0;
|
||||||
|
Widget* element_gui_widget = element_node->attributes->@("cyberiaGuiWidget");
|
||||||
|
switch (element_gui_widget->type) {
|
||||||
|
case WIDGET_TYPE_CHECKBOX:
|
||||||
|
if (element_gui_widget(CheckBoxWidget*)->checked) {
|
||||||
|
raw_value = @t(element_node->attributes->@("value"), element_node->attributes->@("value"), "on");
|
||||||
|
} else {
|
||||||
|
raw_value = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WIDGET_TYPE_INPUT:
|
||||||
|
raw_value = &element_gui_widget(TextInputWidget*)->text;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded_value = @cyberia_urlencode_str(raw_value, &encoded_value_length);
|
||||||
|
|
||||||
|
if (encoded_value) {
|
||||||
|
String.Append(get_request_str, "%s=%s", name, encoded_value);
|
||||||
|
if (i < form_elements->length - 1)
|
||||||
|
String.Append(get_request_str, "&");
|
||||||
|
if (encoded_value_length != StrLen(raw_value)) {
|
||||||
|
Free(encoded_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StrCpy(&addressbar1->text, &get_request_str);
|
||||||
|
"get_request_str: %s\n", get_request_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(action);
|
||||||
|
Spawn(&@cyberia_navigate);
|
||||||
|
}
|
||||||
|
|
||||||
U0 @cyberia_refresh_clicked()
|
U0 @cyberia_refresh_clicked()
|
||||||
{
|
{
|
||||||
if (refreshbtn1->disabled)
|
if (refreshbtn1->disabled)
|
||||||
|
@ -203,6 +357,7 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
|
||||||
renderer->images = NULL;
|
renderer->images = NULL;
|
||||||
renderer->link_pointer = Compositor.theme.pointer.link;
|
renderer->link_pointer = Compositor.theme.pointer.link;
|
||||||
renderer->link_callback = &@cyberia_link_clicked;
|
renderer->link_callback = &@cyberia_link_clicked;
|
||||||
|
renderer->form_submit_callback = &@cyberia_form_submit_clicked;
|
||||||
renderer->widgets_base = widgets_base->next;
|
renderer->widgets_base = widgets_base->next;
|
||||||
renderer->status_widget = status1;
|
renderer->status_widget = status1;
|
||||||
renderer->background_widget = background1;
|
renderer->background_widget = background1;
|
||||||
|
@ -280,7 +435,7 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
|
||||||
return;
|
return;
|
||||||
StrCpy(&addressbar1->text, resolved_location);
|
StrCpy(&addressbar1->text, resolved_location);
|
||||||
Free(resolved_location);
|
Free(resolved_location);
|
||||||
@cyberia_navigate;
|
@cyberia_navigate(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,31 +456,31 @@ U0 @cyberia_navigate(Bool refresh = FALSE)
|
||||||
while (append->next) {
|
while (append->next) {
|
||||||
append = append->next;
|
append = append->next;
|
||||||
}
|
}
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = controlsbackdrop1;
|
append->next->widget = controlsbackdrop1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = backbtn1;
|
append->next->widget = backbtn1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = fwdbtn1;
|
append->next->widget = fwdbtn1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = refreshbtn1;
|
append->next->widget = refreshbtn1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = addressbar1;
|
append->next->widget = addressbar1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = statusbackdrop1;
|
append->next->widget = statusbackdrop1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = status1;
|
append->next->widget = status1;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = status2;
|
append->next->widget = status2;
|
||||||
append = append->next;
|
append = append->next;
|
||||||
append->next = CAlloc(sizeof(@window_widgets_list));
|
append->next = CAlloc(sizeof(@window_widgets_list), browser->task);
|
||||||
append->next->widget = vscroll1;
|
append->next->widget = vscroll1;
|
||||||
vscroll1->scroll = 0;
|
vscroll1->scroll = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue