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

📄 link.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Links viewing/manipulation handling *//* $Id: link.c,v 1.309.2.6 2005/05/01 21:00:42 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/listmenu.h"#include "bfu/menu.h"#include "dialogs/menu.h"#include "dialogs/status.h"#include "document/document.h"#include "document/forms.h"#include "document/html/parser.h"#include "document/html/renderer.h"#include "document/options.h"#include "document/view.h"#include "ecmascript/ecmascript.h"#include "intl/gettext/libintl.h"#include "protocol/uri.h"#include "sched/session.h"#include "sched/task.h"#include "terminal/color.h"#include "terminal/draw.h"#include "terminal/kbd.h"#include "terminal/screen.h"#include "terminal/tab.h"#include "terminal/terminal.h"#include "util/conv.h"#include "util/error.h"#include "util/memory.h"#include "util/object.h"#include "util/string.h"#include "viewer/text/form.h"#include "viewer/text/link.h"#include "viewer/text/search.h"#include "viewer/text/textarea.h"#include "viewer/text/view.h"#include "viewer/text/vs.h"/* Perhaps some of these would be more fun to have in viewer/common/, dunno. * --pasky */static intcurrent_link_evhook(struct document_view *doc_view, enum script_event_hook_type type){#ifdef CONFIG_ECMASCRIPT	struct link *link;	struct script_event_hook *evhook;	assert(doc_view && doc_view->vs);	link = get_current_link(doc_view);	if (!link) return -1;	if (!link->event_hooks) return -1;	if (!doc_view->vs->ecmascript) return -1;	foreach (evhook, *link->event_hooks) {		struct string src = INIT_STRING(evhook->src, strlen(evhook->src));		if (evhook->type != type) continue;		/* TODO: Some even handlers return a bool. */		if (!ecmascript_eval_boolback(doc_view->vs->ecmascript, &src))			return 0;	}	return 1;#else	return -1;#endif}#define current_link_hover(dv) \do { \	current_link_evhook(dv, SEVHOOK_ONMOUSEOVER); \	current_link_evhook(dv, SEVHOOK_ONHOVER); \	current_link_evhook(dv, SEVHOOK_ONFOCUS); \} while (0)#define current_link_blur(dv) \do { \	current_link_evhook(dv, SEVHOOK_ONMOUSEOUT); \	current_link_evhook(dv, SEVHOOK_ONBLUR); \} while (0)voidset_link(struct document_view *doc_view){	assert(doc_view);	if_assert_failed return;	if (current_link_is_visible(doc_view)) return;	find_link_page_down(doc_view);}static inline intget_link_cursor_offset(struct document_view *doc_view, struct link *link){	struct form_control *fc;	struct form_state *fs;	switch (link->type) {		case LINK_CHECKBOX:			return 1;		case LINK_BUTTON:			return 2;		case LINK_FIELD:			fc = get_link_form_control(link);			fs = find_form_state(doc_view, fc);			return fs ? fs->state - fs->vpos : 0;		case LINK_AREA:			fc = get_link_form_control(link);			fs = find_form_state(doc_view, fc);			return fs ? area_cursor(fc, fs) : 0;		case LINK_HYPERTEXT:		case LINK_MAP:		case LINK_SELECT:			return 0;	}	return 0;}/* Allocate doc_view->link_bg with enough space to save the colour * and attributes of each point of the given link plus one byte * for the template character. Initialise that template character * with the colour and attributes appropriate for an active link. */static inline struct screen_char *init_link_drawing(struct document_view *doc_view, struct link *link, int invert){	struct document_options *doc_opts;	struct screen_char *template;	enum color_flags color_flags;	enum color_mode color_mode;	struct color_pair colors;	/* Allocate an extra background char to work on here. */	doc_view->link_bg = mem_alloc((1 + link->npoints) * sizeof(*doc_view->link_bg));	if (!doc_view->link_bg) return NULL;	doc_view->link_bg_n = link->npoints;	/* Setup the template char. */	template = &doc_view->link_bg[link->npoints].c;	template->attr = SCREEN_ATTR_STANDOUT;	/* For the color mode options we use the options set for the document.	 * But for the active link options we prefer to use the global	 * global_doc_opts since it is kept up to date by an option change	 * hook. However if it is not available fall back to use the options	 * from the viewed document. */	doc_opts = &doc_view->document->options;	color_flags = (doc_opts->color_flags | COLOR_DECREASE_LIGHTNESS);	color_mode = doc_opts->color_mode;	if (global_doc_opts) doc_opts = global_doc_opts;	if (doc_opts->underline_active_link)		template->attr |= SCREEN_ATTR_UNDERLINE;	if (doc_opts->bold_active_link)		template->attr |= SCREEN_ATTR_BOLD;	if (doc_opts->color_active_link) {		colors.foreground = doc_opts->active_link_fg;		colors.background = doc_opts->active_link_bg;	} else {		colors.foreground = link->color.foreground;		colors.background = link->color.background;	}	if (doc_opts->invert_active_link && invert) {		swap_values(color_t, colors.foreground, colors.background);		/* Highlight text-input form-fields correctly if contrast		 * correction is needed. */		if (link_is_textinput(link)) {			/* Make sure to use the options belonging to the			 * current document when checking for fg and bg color			 * usage. */			doc_opts = &doc_view->document->options;			/* Are we fallen angels who didn't want to believe that			 * nothing /is/ nothing and so were born to lose our			 * loved ones and dear friends one by one and finally			 * our own life, to see it proved? --Kerouac */			/* Wipe out all default correction for 16 color mode */			color_flags = (color_flags & ~COLOR_INCREASE_CONTRAST);			/* Make contrast correction invert things properly */			color_flags |= COLOR_ENSURE_INVERTED_CONTRAST;		}	}	set_term_color(template, &colors, color_flags, color_mode);	return template;}/* Save the current link's colours and attributes to doc_view->link_bg * and give it the appropriate colour and attributes for an active link. */voiddraw_current_link(struct session *ses, struct document_view *doc_view){	struct terminal *term = ses->tab->term;	struct screen_char *template;	struct link *link;	int cursor_offset;	int xpos, ypos;	int i;	assert(term && doc_view && doc_view->vs);	if_assert_failed return;	assert(ses->tab == get_current_tab(term));	if_assert_failed return;	assertm(!doc_view->link_bg, "link background not empty");	if_assert_failed mem_free(doc_view->link_bg);	link = get_current_link(doc_view);	if (!link) return;	i = !link_is_textinput(link) || ses->insert_mode == INSERT_MODE_OFF;	template = init_link_drawing(doc_view, link, i);	if (!template) return;	xpos = doc_view->box.x - doc_view->vs->x;	ypos = doc_view->box.y - doc_view->vs->y;	if (ses->insert_mode == INSERT_MODE_OFF	    && ses->navigate_mode == NAVIGATE_CURSOR_ROUTING) {		/* If we are navigating using cursor routing and not editing a		 * text-input form-field never set the cursor. */		cursor_offset = -1;	} else {		cursor_offset = get_link_cursor_offset(doc_view, link);	}	for (i = 0; i < link->npoints; i++) {		int x = link->points[i].x + xpos;		int y = link->points[i].y + ypos;		struct screen_char *co;		if (!is_in_box(&doc_view->box, x, y)) {			doc_view->link_bg[i].x = -1;			doc_view->link_bg[i].y = -1;			continue;		}		doc_view->link_bg[i].x = x;		doc_view->link_bg[i].y = y;		co = get_char(term, x, y);		copy_screen_chars(&doc_view->link_bg[i].c, co, 1);		if (i == cursor_offset) {			int blockable = (!link_is_textinput(link)					 && co->color != template->color);			set_cursor(term, x, y, blockable);			set_window_ptr(ses->tab, x, y);		} 		template->data = co->data; 		copy_screen_chars(co, template, 1);		set_screen_dirty(term->screen, y, y);	}}voidfree_link(struct document_view *doc_view){	assert(doc_view);	if_assert_failed return;	mem_free_set(&doc_view->link_bg, NULL);	doc_view->link_bg_n = 0;}/* Restore the colours and attributes that the active link had * before it was selected. */voidclear_link(struct terminal *term, struct document_view *doc_view){	assert(term && doc_view);	if_assert_failed return;	if (doc_view->link_bg) {		struct link_bg *link_bg = doc_view->link_bg;		int i;		for (i = doc_view->link_bg_n - 1; i >= 0; i--) {			struct link_bg *bgchar = &link_bg[i];			if (bgchar->x != -1 && bgchar->y != -1) {				struct terminal_screen *screen = term->screen;				struct screen_char *co;				co = get_char(term, bgchar->x, bgchar->y);				copy_screen_chars(co, &bgchar->c, 1);				set_screen_dirty(screen, bgchar->y, bgchar->y);			}		}		free_link(doc_view);	}}struct link *get_first_link(struct document_view *doc_view){	struct link *link, *undef;	struct document *document;	int height;	int i;	assert(doc_view && doc_view->document);	if_assert_failed return NULL;	document = doc_view->document;	if (!document->lines1) return NULL;	height = doc_view->vs->y + doc_view->box.height;	link = undef = document->links + document->nlinks;	for (i = int_max(0, doc_view->vs->y);	     i < int_min(height, document->height);	     i++) {		if (document->lines1[i]		    && document->lines1[i] < link)			link = document->lines1[i];	}	return (link == undef) ? NULL : link;}struct link *get_last_link(struct document_view *doc_view){	struct link *link = NULL;	struct document *document;	int height;	int i;	assert(doc_view && doc_view->document);	if_assert_failed return NULL;	document = doc_view->document;	if (!document->lines2) return NULL;	height = doc_view->vs->y + doc_view->box.height;	for (i = int_max(0, doc_view->vs->y);	     i < int_min(height, document->height);	     i++)		if (document->lines2[i] > link)			link = document->lines2[i];	return link;}static inline intlink_in_view_x(struct document_view *doc_view, struct link *link){	int i, dx, width;	assert(doc_view && link);	if_assert_failed return 0;	dx = doc_view->vs->x;	width = doc_view->box.width;	for (i = 0; i < link->npoints; i++) {		int x = link->points[i].x - dx;		if (x >= 0 && x < width)			return 1;	}	return 0;}intlink_in_view_y(struct document_view *doc_view, struct link *link){	int i, dy, height;	assert(doc_view && link);	if_assert_failed return 0;	dy = doc_view->vs->y;	height = doc_view->box.height;	for (i = 0; i < link->npoints; i++) {		int y = link->points[i].y - dy;		if (y >= 0 && y < height)			return 1;	}	return 0;}intlink_in_view(struct document_view *doc_view, struct link *link){	assert(doc_view && link);	if_assert_failed return 0;	return link_in_view_y(doc_view, link) && link_in_view_x(doc_view, link);}intcurrent_link_is_visible(struct document_view *doc_view){	struct link *link;

⌨️ 快捷键说明

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