⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 html.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
	{"mediumturquoise",	0x48D1CC},	{"mediumvioletred",	0xC71585},	{"midnightblue",	0x191970},	{"mintcream",		0xF5FFFA},	{"mistyrose",		0xFFE4E1},	{"moccasin",		0xFFE4B5},	{"navajowhite",		0xFFDEAD},	{"navy",		0x000080},	{"oldlace",		0xFDF5E6},	{"olive",		0x808000},	{"olivedrab",		0x6B8E23},	{"orange",		0xFFA500},	{"orangered",		0xFF4500},	{"orchid",		0xDA70D6},	{"palegoldenrod",	0xEEE8AA},	{"palegreen",		0x98FB98},	{"paleturquoise",	0xAFEEEE},	{"palevioletred",	0xDB7093},	{"papayawhip",		0xFFEFD5},	{"peachpuff",		0xFFDAB9},	{"peru",		0xCD853F},	{"pink",		0xFFC0CB},	{"plum",		0xDDA0DD},	{"powderblue",		0xB0E0E6},	{"purple",		0x800080},	{"red",			0xFF0000},	{"rosybrown",		0xBC8F8F},	{"royalblue",		0x4169E1},	{"saddlebrown",		0x8B4513},	{"salmon",		0xFA8072},	{"sandybrown",		0xF4A460},	{"seagreen",		0x2E8B57},	{"seashell",		0xFFF5EE},	{"sienna",		0xA0522D},	{"silver",		0xC0C0C0},	{"skyblue",		0x87CEEB},	{"slateblue",		0x6A5ACD},	{"slategray",		0x708090},	{"snow",		0xFFFAFA},	{"springgreen",		0x00FF7F},	{"steelblue",		0x4682B4},	{"tan",			0xD2B48C},	{"teal",		0x008080},	{"thistle",		0xD8BFD8},	{"tomato",		0xFF6347},	{"turquoise",		0x40E0D0},	{"violet",		0xEE82EE},	{"wheat",		0xF5DEB3},	{"white",		0xFFFFFF},	{"whitesmoke",		0xF5F5F5},	{"yellow",		0xFFFF00},	{"yellowgreen",		0x9ACD32},};#define endof(T) ((T)+sizeof(T)/sizeof(*(T)))int decode_color(unsigned char *str, struct rgb *col){	unsigned long ch;	if (*str != '#') {		struct color_spec *cs;		for (cs = color_specs; cs < endof(color_specs); cs++)			if (!strcasecmp(cs->name, str)) {				ch = cs->rgb;				goto found;			}		str--;	}	str++;	if (strlen(str) == 6) {		char *end;		ch = strtoul(str, &end, 16);		if (!*end && ch < 0x1000000) {found:			col->r = ch / 0x10000;			col->g = ch / 0x100 % 0x100;			col->b = ch % 0x100;			return 0;		}	}	return -1;}int get_color(unsigned char *a, unsigned char *c, struct rgb *rgb){	char *at;	int r = -1;	if (d_opt->col >= 1 || F) if ((at = get_attr_val(a, c))) {		r = decode_color(at, rgb);		mem_free(at);	}	return r;}int get_bgcolor(unsigned char *a, struct rgb *rgb){	if (d_opt->col < 2 && !F) return -1;	return get_color(a, "bgcolor", rgb);}unsigned char *get_target(unsigned char *a){	return get_attr_val(a, "target");}void kill_html_stack_item(struct html_element *e){	html_format_changed = 1;	if (e->dontkill == 2) {		internal("trying to kill unkillable element");		return;	}	if (!e || (void *)e == &html_stack) {		internal("trying to free bad html element");		return;	}	if (e->attr.fontface) mem_free(e->attr.fontface);	if (e->attr.link) mem_free(e->attr.link);	if (e->attr.target) mem_free(e->attr.target);	if (e->attr.image) mem_free(e->attr.image);	if (e->attr.href_base) mem_free(e->attr.href_base);	if (e->attr.target_base) mem_free(e->attr.target_base);	if (e->attr.select) mem_free(e->attr.select);	free_js_event_spec(e->attr.js_event);	del_from_list(e);	mem_free(e);	/*if ((void *)(html_stack.next) == &html_stack || !html_stack.next) {		debug("killing last element");	}*/}static inline void kill_elem(char *e){	if ((size_t)html_top.namelen == strlen(e) && !casecmp(html_top.name, e, html_top.namelen))		kill_html_stack_item(&html_top);}#ifdef DEBUGvoid debug_stack(void){	struct html_element *e;	printf("HTML stack debug: \n");	foreachback(e, html_stack) {		int i;		printf("\"");		for (i = 0; i < e->namelen; i++) printf("%c", e->name[i]);		printf("\"\n");	}	printf("%c", 7);	fflush(stdout);	sleep(1);}#endifvoid html_stack_dup(void){	struct html_element *e;	struct html_element *ep;	html_format_changed = 1;	if ((void *)(ep = html_stack.next) == &html_stack || !html_stack.next) {		internal("html stack empty");		return;	}	e = mem_alloc(sizeof(struct html_element));	memcpy(e, ep, sizeof(struct html_element));	e->attr.fontface = stracpy(ep->attr.fontface);	e->attr.link = stracpy(ep->attr.link);	e->attr.target = stracpy(ep->attr.target);	e->attr.image = stracpy(ep->attr.image);	e->attr.href_base = stracpy(ep->attr.href_base);	e->attr.target_base = stracpy(ep->attr.target_base);	e->attr.select = stracpy(ep->attr.select);	copy_js_event_spec(&e->attr.js_event, ep->attr.js_event);	/*if (e->name) {		if (e->attr.link) set_mem_comment(e->attr.link, e->name, e->namelen);		if (e->attr.target) set_mem_comment(e->attr.target, e->name, e->namelen);		if (e->attr.image) set_mem_comment(e->attr.image, e->name, e->namelen);		if (e->attr.href_base) set_mem_comment(e->attr.href_base, e->name, e->namelen);		if (e->attr.target_base) set_mem_comment(e->attr.target_base, e->name, e->namelen);		if (e->attr.select) set_mem_comment(e->attr.select, e->name, e->namelen);	}*/	e->name = e->options = NULL;	e->namelen = 0;	e->dontkill = 0;	add_to_list(html_stack, e);}#ifdef JSvoid get_js_event(unsigned char *a, unsigned char *name, unsigned char **where){	unsigned char *v;	if ((v = get_attr_val(a, name))) {		if (*where) mem_free(*where);		*where = v;	}}int get_js_events_x(struct js_event_spec **spec, unsigned char *a){	if (!has_attr(a, "onkeyup") && !has_attr(a, "onkeydown") && !has_attr(a,"onkeypress") && !has_attr(a,"onchange") && !has_attr(a, "onfocus") && !has_attr(a,"onblur") && !has_attr(a, "onclick") && !has_attr(a, "ondblclick") && !has_attr(a, "onmousedown") && !has_attr(a, "onmousemove") && !has_attr(a, "onmouseout") && !has_attr(a, "onmouseover") && !has_attr(a, "onmouseup")) return 0;	create_js_event_spec(spec);	get_js_event(a, "onclick", &(*spec)->click_code);	get_js_event(a, "ondblclick", &(*spec)->dbl_code);	get_js_event(a, "onmousedown", &(*spec)->down_code);	get_js_event(a, "onmouseup", &(*spec)->up_code);	get_js_event(a, "onmouseover", &(*spec)->over_code);	get_js_event(a, "onmouseout", &(*spec)->out_code);	get_js_event(a, "onmousemove", &(*spec)->move_code);	get_js_event(a, "onfocus", &(*spec)->focus_code);	get_js_event(a, "onblur", &(*spec)->blur_code);	get_js_event(a, "onchange", &(*spec)->change_code);	get_js_event(a, "onkeypress", &(*spec)->keypress_code);	get_js_event(a, "onkeyup", &(*spec)->keyup_code);	get_js_event(a, "onkeydown", &(*spec)->keydown_code);	return 1;}int get_js_events(unsigned char *a){	return get_js_events_x(&format.js_event, a);}#elseint get_js_events_x(struct js_event_spec **spec, unsigned char *a){	return 0;}int get_js_events(unsigned char *a){	return 0;}#endifvoid *ff;int (*put_chars_f)(void *, unsigned char *, int);void (*line_break_f)(void *);void *(*special_f)(void *, int, ...);unsigned char *eoff;unsigned char *eofff;unsigned char *startf;int line_breax;int pos;int putsp;int was_br;int table_level;int empty_format;void ln_break(int n, void (*line_break)(void *), void *f){	if (!n || html_top.invisible) return;	while (n > line_breax) line_breax++, line_break(f);	pos = 0;	putsp = -1;}void put_chrs(unsigned char *start, int len, int (*put_chars)(void *, unsigned char *, int), void *f){	if (par_format.align == AL_NO) putsp = 0;	if (!len || html_top.invisible) return;	if (putsp == 1) pos += put_chars(f, " ", 1), putsp = -1;	if (putsp == -1) {		if (start[0] == ' ') start++, len--;		putsp = 0;	}	if (!len) {		putsp = -1;		if (par_format.align == AL_NO) putsp = 0;		return;	}	if (start[len - 1] == ' ') putsp = -1;	if (par_format.align == AL_NO) putsp = 0;	was_br = 0;	pos += put_chars(f, start, len);	line_breax = 0;}void kill_until(int ls, ...){	int l;	struct html_element *e = &html_top;	if (ls) e = e->next;	while ((void *)e != &html_stack) {		int sk = 0;		va_list arg;		va_start(arg, ls);		while (1) {			char *s = va_arg(arg, char *);			if (!s) break;			if (!*s) sk++;			else if ((size_t)e->namelen == strlen(s) && !casecmp(e->name, s, strlen(s))) {				if (!sk) {					if (e->dontkill) break;					va_end(arg);					goto killll;				}				else if (sk == 1) {					va_end(arg);					goto killl;				} else break;			}		}		va_end(arg);		if (e->dontkill || (e->namelen == 5 && !casecmp(e->name, "TABLE", 5))) break;		if (e->namelen == 2 && upcase(e->name[0]) == 'T' && (upcase(e->name[1]) == 'D' || upcase(e->name[1]) == 'H' || upcase(e->name[1]) == 'R')) break;		e = e->next;	}	return;	killl:	e = e->prev;	killll:	l = 0;	while ((void *)e != &html_stack) {		if (ls && e == html_stack.next) break;		if (e->linebreak > l) l = e->linebreak;		e = e->prev;		kill_html_stack_item(e->next);	}	ln_break(l, line_break_f, ff);}int get_num(unsigned char *a, unsigned char *n){	char *al;	if ((al = get_attr_val(a, n))) {		char *end;		unsigned long s = strtoul(al, &end, 10);		if (!*al || *end || s > 10000) s = -1;		mem_free(al);		return s;	}	return -1;}/* trunc somehow clips the maximum values. Use 0 to disable truncastion. */int parse_width(unsigned char *w, int trunc){	unsigned char *end;	int p = 0;	long s;	int l;	int limit = par_format.width - (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN);	while (WHITECHAR(*w)) w++;	for (l = 0; w[l] && w[l] != ','; l++) ;	while (l && WHITECHAR(w[l - 1])) l--;	if (!l) return -1;	if (w[l - 1] == '%') l--, p = 1;	while (l && WHITECHAR(w[l - 1])) l--;	if (!l) return -1;	s = strtoul((char *)w, (char **)(void *)&end, 10);	if (end - w < l || s < 0 || s > 10000) return -1;	if (p) {		if (trunc) {#ifdef G			if (trunc == 3) {				return -1;				/*				limit = d_opt->yw - G_SCROLL_BAR_WIDTH;				if (limit < 0) limit = 0;				*/			}#endif			s = s * limit / 100;		}		else return -1;	} else s = (s + (gf_val(HTML_CHAR_WIDTH, 1) - 1) / 2) / gf_val(HTML_CHAR_WIDTH, 1);	if (trunc == 1 && s > limit) s = limit;	if (s < 0) s = 0;	return s;}/* trunc somehow clips the maximum values. Use 0 to disable truncastion. */int get_width(unsigned char *a, unsigned char *n, int trunc){	int r;	unsigned char *w;	if (!(w = get_attr_val(a, n))) return -1;	r = parse_width(w, trunc);	mem_free(w);	return r;}/*int form_num;struct form form = { 0, NULL, 0 };int g_ctrl_num;*/struct form form = { NULL, NULL, NULL, NULL, 0, 0 };unsigned char *last_form_tag;unsigned char *last_form_attr;unsigned char *last_input_tag;static inline void set_link_attr(void){	memcpy(!(format.attr & AT_INVERT) ? &format.fg : &format.bg, &format.clink, sizeof(struct rgb));}void put_link_line(unsigned char *prefix, unsigned char *linkname, unsigned char *link, unsigned char *target){	html_stack_dup();	ln_break(1, line_break_f, ff);	if (format.link) mem_free(format.link), format.link = NULL;	if (format.target) mem_free(format.target), format.target = NULL;	format.form = NULL;	put_chrs(prefix, strlen(prefix), put_chars_f, ff);	html_format_changed = 1;	format.link = join_urls(format.href_base, link);	format.target = stracpy(target);	set_link_attr();	put_chrs(linkname, strlen(linkname), put_chars_f, ff);	ln_break(1, line_break_f, ff);	kill_html_stack_item(&html_top);}void html_span(unsigned char *a) { }void html_bold(unsigned char *a){ 	get_js_events(a); 	format.attr |= AT_BOLD; }void html_italic(unsigned char *a){	get_js_events(a);	format.attr |= AT_ITALIC;}void html_underline(unsigned char *a){	get_js_events(a); 	format.attr |= AT_UNDERLINE;}void html_fixed(unsigned char *a){	get_js_events(a);	format.attr |= AT_FIXED;}void html_invert(unsigned char *a){	struct rgb rgb;	get_js_events(a);	memcpy(&rgb, &format.fg, sizeof(struct rgb));	memcpy(&format.fg, &format.bg, sizeof(struct rgb));	memcpy(&format.bg, &rgb, sizeof(struct rgb));	format.attr ^= AT_INVERT;}void html_a(unsigned char *a){	char *al;	int ev = get_js_events(a);	if ((al = get_url_val(a, "href"))) {		char *all = al;		while (all[0] == ' ') all++;		while (all[0] && all[strlen(all) - 1] == ' ') all[strlen(all) - 1] = 0;		if (format.link) mem_free(format.link);		format.link = join_urls(format.href_base, all);		mem_free(al);		if ((al = get_target(a))) {			if (format.target) mem_free(format.target);			format.target = al;		} else {			if (format.target) mem_free(format.target);			format.target = stracpy(format.target_base);		}		/*format.attr ^= AT_BOLD;*/		set_link_attr();	} else if (!ev) kill_html_stack_item(&html_top);	if ((al = get_attr_val(a, "name"))) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -