📄 html.c
字号:
if (!name) menu_stack_size--;}void init_menu(void){ menu_stack_size = 0; menu_stack = DUMMY; new_menu_item(stracpy(""), -1, 0);}void free_menu(struct menu_item *m) /* Grrr. Recursion */{ struct menu_item *mm; for (mm = m; mm->text; mm++) { mem_free(mm->text); if (mm->func == MENU_FUNC do_select_submenu) free_menu(mm->data); } mem_free(m);}struct menu_item *detach_menu(void){ struct menu_item *i = NULL; if (menu_stack_size) i = menu_stack[0]; if (menu_stack) mem_free(menu_stack); return i;}void destroy_menu(void){ if (menu_stack && menu_stack != DUMMY) free_menu(menu_stack[0]); detach_menu();}void menu_labels(struct menu_item *m, unsigned char *base, unsigned char **lbls){ unsigned char *bs; for (; m->text; m++) { if (m->func == MENU_FUNC do_select_submenu) { if ((bs = stracpy(base))) { add_to_strn(&bs, m->text); add_to_strn(&bs, " "); menu_labels(m->data, bs, lbls); mem_free(bs); } } else { if ((bs = stracpy(m->hotkey[1] ? (unsigned char *)"" : base))) add_to_strn(&bs, m->text); lbls[(my_intptr_t)m->data] = bs; } }}int menu_contains(struct menu_item *m, int f){ if (m->func != MENU_FUNC do_select_submenu) return (my_intptr_t)m->data == f; for (m = m->data; m->text; m++) if (menu_contains(m, f)) return 1; return 0;}void do_select_submenu(struct terminal *term, struct menu_item *menu, struct session *ses){ struct menu_item *m; int def = get_current_state(ses); int sel = 0; if (def < 0) def = 0; for (m = menu; m->text; m++, sel++) if (menu_contains(m, def)) goto f; sel = 0; f: do_menu_selected(term, menu, ses, sel);}int do_html_select(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f){ struct form_control *fc; unsigned char *t_name, *t_attr, *en; int t_namelen; unsigned char *lbl; int lbl_l; unsigned char *vlbl; int vlbl_l; int nnmi = 0; struct conv_table *ct = special_f(f, SP_TABLE, NULL); unsigned char **val, **lbls; int order, preselect, group; int i, mw; if (has_attr(attr, "multiple")) return 1; find_form_for_input(attr); lbl = NULL; lbl_l = 0; vlbl = NULL; vlbl_l = 0; val = DUMMY; order = 0, group = 0, preselect = -1; init_menu(); se: en = html; see: html = en; while (html < eof && *html != '<') html++; if (html >= eof) { int i; abort: *end = html; if (lbl) mem_free(lbl); if (vlbl) mem_free(vlbl); for (i = 0; i < order; i++) if (val[i]) mem_free(val[i]); mem_free(val); destroy_menu(); *end = en; return 0; } if (lbl) { unsigned char *q, *s = en; int l = html - en; while (l && WHITECHAR(s[0])) s++, l--; while (l && WHITECHAR(s[l-1])) l--; q = convert_string(ct, s, l, d_opt); if (q) add_to_str(&lbl, &lbl_l, q), mem_free(q); add_bytes_to_str(&vlbl, &vlbl_l, s, l); } if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto se; } if (parse_element(html, eof, &t_name, &t_namelen, &t_attr, &en)) { html++; goto se; } if (t_namelen == 7 && !casecmp(t_name, "/SELECT", 7)) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } goto end_parse; } if (t_namelen == 7 && !casecmp(t_name, "/OPTION", 7)) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } goto see; } if (t_namelen == 6 && !casecmp(t_name, "OPTION", 6)) { unsigned char *v, *vx; if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } if (has_attr(t_attr, "disabled")) goto see; if (preselect == -1 && has_attr(t_attr, "selected")) preselect = order; v = get_exact_attr_val(t_attr, "value"); if (!(order & (ALLOC_GR - 1))) { if ((unsigned)order > MAXINT / sizeof(unsigned char *) - ALLOC_GR) overalloc(); if ((unsigned)order > MAXINT / sizeof(char *) - ALLOC_GR) overalloc(); val = mem_realloc(val, (order + ALLOC_GR) * sizeof(unsigned char *)); } val[order++] = v; if ((vx = get_attr_val(t_attr, "label"))) { new_menu_item(convert_string(ct, vx, strlen(vx), d_opt), order - 1, 0); mem_free(vx); } if (!v || !vx) { lbl = init_str(), lbl_l = 0; vlbl = init_str(), vlbl_l = 0; nnmi = !!vx; } goto see; } if ((t_namelen == 8 && !casecmp(t_name, "OPTGROUP", 8)) || (t_namelen == 9 && !casecmp(t_name, "/OPTGROUP", 9))) { if (lbl) { if (!val[order - 1]) val[order - 1] = stracpy(vlbl); if (!nnmi) new_menu_item(lbl, order - 1, 1), lbl = NULL; else mem_free(lbl), lbl = NULL; mem_free(vlbl), vlbl = NULL; } if (group) new_menu_item(NULL, -1, 0), group = 0; } if (t_namelen == 8 && !casecmp(t_name, "OPTGROUP", 8)) { char *la; if (!(la = get_attr_val(t_attr, "label"))) la = stracpy(""); new_menu_item(convert_string(ct, la, strlen(la), d_opt), -1, 0); mem_free(la); group = 1; } goto see; end_parse: *end = en; if (!order) goto abort; fc = mem_calloc(sizeof(struct form_control)); lbls = mem_calloc(order * sizeof(char *)); fc->form_num = last_form_tag ? last_form_tag - startf : 0; fc->ctrl_num = last_form_tag ? attr - last_form_tag : attr - startf; fc->position = attr - startf; fc->method = form.method; fc->action = stracpy(form.action); fc->form_name= stracpy(form.form_name); fc->onsubmit= stracpy(form.onsubmit); fc->name = get_attr_val(attr, "name"); fc->type = FC_SELECT; fc->default_state = preselect < 0 ? 0 : preselect; fc->default_value = order ? stracpy(val[fc->default_state]) : stracpy(""); fc->ro = has_attr(attr, "disabled") ? 2 : has_attr(attr, "readonly") ? 1 : 0; fc->nvalues = order; fc->values = val; fc->menu = detach_menu(); fc->labels = lbls; menu_labels(fc->menu, "", lbls); html_stack_dup(); format.attr |= AT_FIXED; format.fontsize = 3; put_chrs("[", 1, put_chars_f, f); html_stack_dup(); get_js_events(attr); format.form = fc; format.attr |= AT_BOLD | AT_FIXED; format.fontsize = 3; mw = 0; for (i = 0; i < order; i++) if (lbls[i] && utf8len(lbls[i]) > mw) mw = utf8len(lbls[i]); for (i = 0; i < mw; i++) put_chrs("_", 1, put_chars_f, f); kill_html_stack_item(&html_top); put_chrs("]", 1, put_chars_f, f); kill_html_stack_item(&html_top); special_f(ff, SP_CONTROL, fc); return 0;}void html_textarea(unsigned char *a){ internal("This should be never called");}void do_html_textarea(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f){ struct form_control *fc; unsigned char *p, *t_name, *w; int t_namelen; int cols, rows; int i; find_form_for_input(attr); while (html < eof && (*html == '\n' || *html == '\r')) html++; p = html; while (p < eof && *p != '<') { pp: p++; } if (p >= eof) { *end = eof; return; } if (parse_element(p, eof, &t_name, &t_namelen, NULL, end)) goto pp; if (t_namelen != 9 || casecmp(t_name, "/TEXTAREA", 9)) goto pp; fc = mem_calloc(sizeof(struct form_control)); fc->form_num = last_form_tag ? last_form_tag - startf : 0; fc->ctrl_num = last_form_tag ? attr - last_form_tag : attr - startf; fc->position = attr - startf; fc->method = form.method; fc->action = stracpy(form.action); fc->form_name = stracpy(form.form_name); fc->onsubmit = stracpy(form.onsubmit); fc->name = get_attr_val(attr, "name"); fc->type = FC_TEXTAREA;; fc->ro = has_attr(attr, "disabled") ? 2 : has_attr(attr, "readonly") ? 1 : 0; fc->default_value = memacpy(html, p - html); if ((cols = get_num(attr, "cols")) <= 5) cols = HTML_DEFAULT_TEXTAREA_WIDTH; cols++; if ((rows = get_num(attr, "rows")) <= 0) rows = HTML_DEFAULT_TEXTAREA_HEIGHT; if (!F) { if (d_opt->xw && cols > d_opt->xw) cols = d_opt->xw; if (d_opt->yw && rows > d_opt->yw) rows = d_opt->yw;#ifdef G } else { struct style *st = g_get_style(0, 0, d_opt->font_size, G_HTML_DEFAULT_FAMILY "-medium-roman-serif-mono", 0); int uw = g_char_width(st, '_'); g_free_style(st); if (uw && d_opt->xw >= uw + G_SCROLL_BAR_WIDTH && cols > (d_opt->xw - G_SCROLL_BAR_WIDTH) / uw) cols = (d_opt->xw - G_SCROLL_BAR_WIDTH) / uw; if (d_opt->font_size && d_opt->yw >= d_opt->font_size + G_SCROLL_BAR_WIDTH && rows > (d_opt->yw - G_SCROLL_BAR_WIDTH) / d_opt->font_size) rows = (d_opt->yw - G_SCROLL_BAR_WIDTH) / d_opt->font_size;#endif } fc->cols = cols; fc->rows = rows; fc->wrap = 1; if ((w = get_attr_val(attr, "wrap"))) { if (!strcasecmp(w, "hard") || !strcasecmp(w, "physical")) fc->wrap = 2; else if (!strcasecmp(w, "off")) fc->wrap = 0; mem_free(w); } if ((fc->maxlength = get_num(attr, "maxlength")) == -1) fc->maxlength = MAXINT / 4; if (rows > 1) ln_break(1, line_break_f, f); else put_chrs(" ", 1, put_chars_f, f); html_stack_dup(); get_js_events(attr); format.form = fc; format.attr = AT_BOLD | AT_FIXED; if (F) format.attr &= ~AT_BOLD; format.fontsize = 3; for (i = 0; i < rows; i++) { int j; for (j = 0; j < cols; j++) put_chrs("_", 1, put_chars_f, f); if (i < rows - 1) ln_break(1, line_break_f, f); } kill_html_stack_item(&html_top); if (rows > 1) ln_break(1, line_break_f, f); else put_chrs(" ", 1, put_chars_f, f); special_f(f, SP_CONTROL, fc);}void html_iframe(unsigned char *a){ unsigned char *name, *url; if (!(url = get_url_val(a, "src"))) return; if (!(name = get_attr_val(a, "name"))) name = stracpy(""); if (*name) put_link_line("IFrame: ", name, url, d_opt->framename); else put_link_line("", "IFrame", url, d_opt->framename); mem_free(name); mem_free(url);}void html_noframes(unsigned char *a){ if (d_opt->frames) html_skip(a);}void html_frame(unsigned char *a){ unsigned char *name, *u2, *url; if (!(u2 = get_url_val(a, "src"))) { url = stracpy(""); } else { url = join_urls(format.href_base, u2); mem_free(u2); } if (!url) return; name = get_attr_val (a, "name"); if (!name) name = stracpy(url); else if (!name[0]) { /* When name doesn't have a value */ mem_free(name); name = stracpy(url); } if (!d_opt->frames || !html_top.frameset) put_link_line("Frame: ", name, url, ""); else { struct frame_param fp; char *scroll = get_attr_val(a, "scrolling"); fp.name = name; fp.url = url; fp.parent = html_top.frameset; fp.marginwidth = get_num(a, "marginwidth"); fp.marginheight = get_num(a, "marginheight"); fp.scrolling = SCROLLING_AUTO; if (scroll) { if (!strcasecmp(scroll, "no")) fp.scrolling = SCROLLING_NO; else if (!strcasecmp(scroll, "yes")) fp.scrolling = SCROLLING_YES; mem_free(scroll); } if (special_f(ff, SP_USED, NULL)) special_f(ff, SP_FRAME, &fp); } mem_free(name); mem_free(url);}void parse_frame_widths(unsigned char *a, int ww, int www, int **op, int *olp){ unsigned char *aa; int q, qq, i, d, nn; unsigned long n; int *oo, *o; int ol; ol = 0; o = DUMMY; new_ch: while (WHITECHAR(*a)) a++; n = strtoul(a, (char **)(void *)&a, 10); if (n > 10000) n = 10000; q = n; if (*a == '%') q = q * ww / 100; else if (*a != '*') q = (q + (www - 1) / 2) / (www ? www : 1); else if (!(q = -q)) q = -1; if ((unsigned)ol > MAXINT / sizeof(int) - 1) overalloc(); o = mem_realloc(o, (ol + 1) * sizeof(int)); o[ol++] = q; if ((aa = strchr(a, ','))) { a = aa + 1; goto new_ch; } *op = o; *olp = ol; q = gf_val(2 * ol - 1, ol); for (i = 0; i < ol; i++) if (o[i] > 0) q += o[i] - 1; if (q >= ww) { distribute: for (i = 0; i < ol; i++) if (o[i] < 1) o[i] = 1; q -= ww; d = 0; for (i = 0; i < ol; i++) d += o[i]; qq = q; for (i = 0; i < ol; i++) { q -= o[i] - o[i] * (d - qq) / (d ? d : 1); do_not_optimize_here(&d); /* SIGH! gcc 2.7.2.* has an optimizer bug! */ o[i] = o[i] * (d - qq) / (d ? d : 1); } while (q) { nn = 0; for (i = 0; i < ol; i++) { if (q < 0) o[i]++, q++, nn = 1; if (q > 0 && o[i] > 1) o[i]--, q--, nn = 1; if (!q) break; } if (!nn) break; } } else { int nn = 0; for (i = 0; i < ol; i++) if (o[i] < 0) nn = 1; if (!nn) goto distribute; if ((unsigned)ol > MAXINT / sizeof(int)) overalloc(); oo = mem_alloc(ol * sizeof(int)); memcpy(oo, o, ol * sizeof(int)); for (i = 0; i < ol; i++) if (o[i] < 1) o[i] = 1; q = ww - q; d = 0; for (i = 0; i < ol; i++) if (oo[i] < 0) d += -oo[i]; qq = q; for (i = 0; i < ol; i++) if (oo[i] < 0) { o[i] += (-oo[i] * qq / (d ? d : 1)); q -= (-oo[i] * qq / (d ? d : 1)); } if (q < 0) { q = 0; /*internal("parse_frame_widths: q < 0"); may happen when page contains too big values */ } for (i = 0; i < ol; i++) if (oo[i] < 0) { if (q) o[i]++, q--; } if (q > 0) { q = 0; /*internal("parse_frame_widths: q > 0"); may happen when page contains too big values */ } mem_free(oo); } for (i = 0; i < ol; i++) if (!o[i]) { int j; int m = 0; int mj = 0; for (j = 0; j < ol; j++) if (o[j] > m) m = o[j], mj = j; if (m) o[i] = 1, o[mj]--; }}void html_frameset(unsigned char *a){ int x, y; struct frameset_param fp; unsigned char *c, *d; if (!d_opt->frames || !special_f(ff, SP_USED, NULL)) return; if (!(c = get_attr_val(a, "cols"))) c = stracpy("100%"); if (!(d = get_attr_val(a, "rows"))) d = stracpy("100%"); if (!html_top.frameset) { x = d_opt->xw; y = d_opt->yw; } else { struct frameset_desc *f = html_top.frameset; if (f->yp >= f->y) goto free_cd; x = f->f[f->xp + f->yp * f->x].xw; y = f->f[f->xp + f->yp * f->x].yw; } parse_frame_widths(c, x, gf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -