📄 forms.c
字号:
/* HTML forms parser */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/listmenu.h"#include "bfu/menu.h"#include "document/html/parser/forms.h"#include "document/html/parser/link.h"#include "document/html/parser/stack.h"#include "document/html/parser/parse.h"#include "document/html/parser.h"#include "document/html/renderer.h"#include "document/forms.h"#include "intl/charsets.h"#include "protocol/protocol.h"#include "protocol/uri.h"#include "util/conv.h"#include "util/error.h"#include "util/memdebug.h"#include "util/memlist.h"#include "util/memory.h"#include "util/string.h"/* Unsafe macros */#include "document/html/internal.h"voidhtml_form(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5){ unsigned char *al; struct form *form; html_context->was_br = 1; form = init_form(); if (!form) return; form->method = FORM_METHOD_GET; form->form_num = a - html_context->startf; al = get_attr_val(a, "method", html_context->options); if (al) { if (!strcasecmp(al, "post")) { unsigned char *enctype; enctype = get_attr_val(a, "enctype", html_context->options); form->method = FORM_METHOD_POST; if (enctype) { if (!strcasecmp(enctype, "multipart/form-data")) form->method = FORM_METHOD_POST_MP; else if (!strcasecmp(enctype, "text/plain")) form->method = FORM_METHOD_POST_TEXT_PLAIN; mem_free(enctype); } } mem_free(al); } al = get_attr_val(a, "name", html_context->options); if (al) form->name = al; al = get_attr_val(a, "action", html_context->options); /* The HTML specification at * http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.3 states * that the behavior of an empty action attribute should be undefined. * Mozilla handles action="" as action="<current-URI>" which seems * reasonable. (bug 615) */ if (al && *al) { form->action = join_urls(html_context->base_href, trim_chars(al, ' ', NULL)); mem_free(al); } else { enum uri_component components = URI_ORIGINAL; mem_free_if(al); /* We have to do following for GET method, because we would end * up with two '?' otherwise. */ if (form->method == FORM_METHOD_GET) components = URI_FORM_GET; form->action = get_uri_string(html_context->base_href, components); /* No action URI should contain post data */ assert(!form->action || !strchr(form->action, POST_CHAR)); /* GET method URIs should not have '?'. */ assert(!form->action || form->method != FORM_METHOD_GET || !strchr(form->action, '?')); } al = get_target(html_context->options, a); form->target = al ? al : stracpy(html_context->base_target); html_context->special_f(html_context, SP_FORM, form);}static intget_form_mode(struct html_context *html_context, unsigned char *attr){ if (has_attr(attr, "disabled", html_context->options)) return FORM_MODE_DISABLED; if (has_attr(attr, "readonly", html_context->options)) return FORM_MODE_READONLY; return FORM_MODE_NORMAL;}static struct form_control *init_form_control(enum form_type type, unsigned char *attr, struct html_context *html_context){ struct form_control *fc; fc = mem_calloc(1, sizeof(*fc)); if (!fc) return NULL; fc->type = type; fc->position = attr - html_context->startf; fc->mode = get_form_mode(html_context, attr); return fc;}voidhtml_button(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5){ unsigned char *al; struct form_control *fc; enum form_type type = FC_SUBMIT; html_focusable(html_context, a); al = get_attr_val(a, "type", html_context->options); if (!al) goto no_type_attr; if (!strcasecmp(al, "button")) { type = FC_BUTTON; } else if (!strcasecmp(al, "reset")) { type = FC_RESET; } else if (strcasecmp(al, "submit")) { /* unknown type */ mem_free(al); return; } mem_free(al);no_type_attr: fc = init_form_control(type, a, html_context); if (!fc) return; fc->name = get_attr_val(a, "name", html_context->options); fc->default_value = get_attr_val(a, "value", html_context->options); if (!fc->default_value) { if (fc->type == FC_SUBMIT) fc->default_value = stracpy("Submit"); else if (fc->type == FC_RESET) fc->default_value = stracpy("Reset"); else if (fc->type == FC_BUTTON) fc->default_value = stracpy("Button"); } if (!fc->default_value) fc->default_value = stracpy(""); html_context->special_f(html_context, SP_CONTROL, fc); format.form = fc; format.style.attr |= AT_BOLD;}static voidhtml_input_format(struct html_context *html_context, unsigned char *a, struct form_control *fc){ put_chrs(html_context, " ", 1); html_stack_dup(html_context, ELEMENT_KILLABLE); html_focusable(html_context, a); format.form = fc; if (format.title) mem_free(format.title); format.title = get_attr_val(a, "title", html_context->options); switch (fc->type) { case FC_TEXT: case FC_PASSWORD: case FC_FILE: { int i; format.style.attr |= AT_BOLD; for (i = 0; i < fc->size; i++) put_chrs(html_context, "_", 1); break; } case FC_CHECKBOX: format.style.attr |= AT_BOLD; put_chrs(html_context, "[ ]", 8); break; case FC_RADIO: format.style.attr |= AT_BOLD; put_chrs(html_context, "( )", 8); break; case FC_IMAGE: { unsigned char *al; mem_free_set(&format.image, NULL); al = get_url_val(a, "src", html_context->options); if (!al) al = get_url_val(a, "dynsrc", html_context->options); if (al) { format.image = join_urls(html_context->base_href, al); mem_free(al); } format.style.attr |= AT_BOLD; put_chrs(html_context, "[ ", 7); if (fc->alt) put_chrs(html_context, fc->alt, strlen(fc->alt)); else if (fc->name) put_chrs(html_context, fc->name, strlen(fc->name)); else put_chrs(html_context, "Submit", 6); put_chrs(html_context, " ]", 7); break; } case FC_SUBMIT: case FC_RESET: case FC_BUTTON: format.style.attr |= AT_BOLD; put_chrs(html_context, "[ ", 7); if (fc->default_value) put_chrs(html_context, fc->default_value, strlen(fc->default_value)); put_chrs(html_context, " ]", 7); break; case FC_TEXTAREA: case FC_SELECT: case FC_HIDDEN: INTERNAL("bad control type"); } kill_html_stack_item(html_context, &html_top); put_chrs(html_context, " ", 1);}voidhtml_input(struct html_context *html_context, unsigned char *a, unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5){ unsigned char *al; struct form_control *fc; fc = init_form_control(FC_TEXT, a, html_context); if (!fc) return; al = get_attr_val(a, "type", html_context->options); if (al) { if (!strcasecmp(al, "text")) fc->type = FC_TEXT; else if (!strcasecmp(al, "hidden")) fc->type = FC_HIDDEN; else if (!strcasecmp(al, "button")) fc->type = FC_BUTTON; else if (!strcasecmp(al, "checkbox")) fc->type = FC_CHECKBOX; else if (!strcasecmp(al, "radio")) fc->type = FC_RADIO; else if (!strcasecmp(al, "password")) fc->type = FC_PASSWORD; else if (!strcasecmp(al, "submit")) fc->type = FC_SUBMIT; else if (!strcasecmp(al, "reset")) fc->type = FC_RESET; else if (!strcasecmp(al, "file")) fc->type = FC_FILE; else if (!strcasecmp(al, "image")) fc->type = FC_IMAGE; /* else unknown type, let it default to FC_TEXT. */ mem_free(al); } if (fc->type != FC_FILE) fc->default_value = get_attr_val(a, "value", html_context->options); if (!fc->default_value) { if (fc->type == FC_CHECKBOX) fc->default_value = stracpy("on"); else if (fc->type == FC_SUBMIT) fc->default_value = stracpy("Submit"); else if (fc->type == FC_RESET) fc->default_value = stracpy("Reset"); else if (fc->type == FC_BUTTON) fc->default_value = stracpy("Button"); } if (!fc->default_value) fc->default_value = stracpy(""); fc->name = get_attr_val(a, "name", html_context->options); fc->size = get_num(a, "size", html_context->options); if (fc->size == -1) fc->size = html_context->options->default_form_input_size; fc->size++; if (fc->size > html_context->options->box.width) fc->size = html_context->options->box.width; fc->maxlength = get_num(a, "maxlength", html_context->options); if (fc->maxlength == -1) fc->maxlength = INT_MAX; if (fc->type == FC_CHECKBOX || fc->type == FC_RADIO) fc->default_state = has_attr(a, "checked", html_context->options); if (fc->type == FC_IMAGE) fc->alt = get_attr_val(a, "alt", html_context->options); if (fc->type != FC_HIDDEN) { html_input_format(html_context, a, fc); } html_context->special_f(html_context, SP_CONTROL, fc);}static struct list_menu lnk_menu;static voiddo_html_select(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, struct html_context *html_context){ struct conv_table *ct = html_context->special_f(html_context, SP_TABLE, NULL); struct form_control *fc; struct string lbl = NULL_STRING, orig_lbl = NULL_STRING; unsigned char **values = NULL; unsigned char **labels; unsigned char *name, *t_attr, *en; int namelen; int nnmi = 0; int order = 0; int preselect = -1; int group = 0; int i, max_width; int closing_tag; html_focusable(html_context, attr); init_menu(&lnk_menu);se: en = html;see: html = en; while (html < eof && *html != '<') html++; if (html >= eof) {abort: *end = html;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -