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

📄 session.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
voidcheck_questions_queue(struct session *ses){	while (!list_empty(questions_queue)) {		struct questions_entry *q = questions_queue.next;		q->callback(ses, q->data);		del_from_list(q);		mem_free(q);	}}voidadd_questions_entry(void (*callback)(struct session *, void *), void *data){	struct questions_entry *q = mem_alloc(sizeof(*q));	if (!q) return;	q->callback = callback;	q->data	    = data;	add_to_list(questions_queue, q);}#ifdef CONFIG_SCRIPTINGstatic voidmaybe_pre_format_html(struct cache_entry *cached, struct session *ses){	struct fragment *fragment;	unsigned char *src;	int len;	static int pre_format_html_event = EVENT_NONE;	if (!cached || cached->preformatted || list_empty(cached->frag))		return;	fragment = get_cache_fragment(cached);	if (!fragment) return;	src = fragment->data;	len = fragment->length;	set_event_id(pre_format_html_event, "pre-format-html");	trigger_event(pre_format_html_event, &src, &len, ses, struri(cached->uri));	if (src && src != fragment->data) {		add_fragment(cached, 0, src, len);		truncate_entry(cached, len, 1);		cached->incomplete = 0; /* XXX */		mem_free(src);	}	cached->preformatted = 1;}#endifstatic intcheck_incomplete_redirects(struct cache_entry *cached){	assert(cached);	cached = follow_cached_redirects(cached);	if (cached && !cached->redirect) {		/* XXX: This is not quite true, but does that difference		 * matter here? */		return cached->incomplete;	}	return 0;}intsession_is_loading(struct session *ses){	struct download *download = get_current_download(ses);	if (!download) return 0;	if (!is_in_result_state(download->state))		return 1;	/* The validness of download->cached (especially the download struct in	 * ses->loading) is hard to maintain so check before using it.	 * Related to bug 559. */	if (download->cached	    && cache_entry_is_valid(download->cached)	    && check_incomplete_redirects(download->cached))		return 1;	return 0;}voiddoc_loading_callback(struct download *download, struct session *ses){	int submit = 0;	if (is_in_result_state(download->state)) {#ifdef CONFIG_SCRIPTING		maybe_pre_format_html(download->cached, ses);#endif		if (ses->display_timer != -1) {			kill_timer(ses->display_timer);			ses->display_timer = -1;		}		draw_formatted(ses, 1);		if (get_cmd_opt_bool("auto-submit")) {			if (!list_empty(ses->doc_view->document->forms)) {				get_cmd_opt_bool("auto-submit") = 0;				submit = 1;			}		}		load_frames(ses, ses->doc_view);		load_css_imports(ses, ses->doc_view);		load_ecmascript_imports(ses, ses->doc_view);		process_file_requests(ses);		if (ses->doc_view->document->refresh		    && get_opt_bool("document.browse.refresh")) {			start_document_refresh(ses->doc_view->document->refresh,					       ses);		}		if (download->state != S_OK) {			print_error_dialog(ses, download->state,					   ses->doc_view->document->uri,					   download->pri);		}	} else if (is_in_transfering_state(download->state)	           && ses->display_timer == -1) {		display_timer(ses);	}	check_questions_queue(ses);	print_screen_status(ses);#ifdef CONFIG_GLOBHIST	if (download->conn && download->pri != PRI_CSS) {		unsigned char *title = ses->doc_view->document->title;		struct uri *uri = download->conn->proxied_uri;		add_global_history_item(struri(uri), title, time(NULL));	}#endif	if (submit) auto_submit_form(ses);}static voidfile_loading_callback(struct download *download, struct file_to_load *ftl){	if (ftl->download.cached) {		if (ftl->cached) object_unlock(ftl->cached);		ftl->cached = ftl->download.cached;		object_lock(ftl->cached);	}	/* FIXME: We need to do content-type check here! However, we won't	 * handle properly the "Choose action" dialog now :(. */	if (ftl->cached && !ftl->cached->redirect_get && download->pri != PRI_CSS) {		struct session *ses = ftl->ses;		struct uri *loading_uri = ses->loading_uri;		unsigned char *target_frame = ses->task.target_frame;		ses->loading_uri = ftl->uri;		ses->task.target_frame = ftl->target_frame;		ses_chktype(ses, &ftl->download, ftl->cached, 1);		ses->loading_uri = loading_uri;		ses->task.target_frame = target_frame;	}	doc_loading_callback(download, ftl->ses);}static struct file_to_load *request_additional_file(struct session *ses, unsigned char *name, struct uri *uri, int pri){	struct file_to_load *ftl;	if (uri->protocol == PROTOCOL_UNKNOWN) {		return NULL;	}	/* XXX: We cannot run the external handler here, because	 * request_additional_file() is called many times for a single URL	 * (normally the foreach() right below catches them all). Anyway,	 * having <frame src="mailto:foo"> would be just weird, wouldn't it?	 * --pasky */	if (get_protocol_external_handler(uri->protocol)) {		return NULL;	}	foreach (ftl, ses->more_files) {		if (compare_uri(ftl->uri, uri, URI_BASE)) {			if (ftl->pri > pri) {				ftl->pri = pri;				change_connection(&ftl->download, &ftl->download, pri, 0);			}			return NULL;		}	}	ftl = mem_calloc(1, sizeof(*ftl));	if (!ftl) return NULL;	ftl->uri = get_uri_reference(uri);	ftl->target_frame = stracpy(name);	ftl->download.callback = (void (*)(struct download *, void *)) file_loading_callback;	ftl->download.data = ftl;	ftl->pri = pri;	ftl->ses = ses;	add_to_list(ses->more_files, ftl);	return ftl;}static voidload_additional_file(struct file_to_load *ftl, struct document_view *doc_view,		     enum cache_mode cache_mode){	struct uri *referrer = doc_view && doc_view->document			     ? doc_view->document->uri : NULL;	load_uri(ftl->uri, referrer, &ftl->download, ftl->pri, cache_mode, -1);}voidprocess_file_requests(struct session *ses){	struct file_to_load *ftl;	struct document_view *doc_view = current_frame(ses);	int more;	if (ses->status.processing_file_requests) return;	ses->status.processing_file_requests = 1;	do {		more = 0;		foreach (ftl, ses->more_files) {			if (ftl->req_sent)				continue;			ftl->req_sent = 1;			load_additional_file(ftl, doc_view, CACHE_MODE_NORMAL);			more = 1;		}	} while (more);	ses->status.processing_file_requests = 0;}static voiddialog_goto_url_open(void *data){	dialog_goto_url((struct session *) data, NULL);}/* Returns 0 if the first session was not properly initialized and * setup_session() should be called on the session as well. */static intsetup_first_session(struct session *ses, struct uri *uri){	struct terminal *term = ses->tab->term;	if (!*get_opt_str("protocol.http.user_agent")) {		info_box(term, 0,			 N_("Warning"), ALIGN_CENTER,			 N_("You have empty string in protocol.http.user_agent - "			 "this was a default value in the past, substituted by "			 "default ELinks User-Agent string. However, currently "			 "this means that NO User-Agent HEADER "		 	 "WILL BE SENT AT ALL - if this is really what you want, "			 "set its value to \" \", otherwise please delete line "			 "with this settings from your configuration file (if you "			 "have no idea what I'm talking about, just do this), so "			 "that correct default setting will be used. Apologies for "			 "any inconvience caused."));	}	if (!get_opt_bool("config.saving_style_w")) {		get_opt_bool("config.saving_style_w") = 1;		get_opt_rec(config_options, "config.saving_style_w")->flags |= OPT_TOUCHED;		if (get_opt_int("config.saving_style") != 3) {			info_box(term, 0,				 N_("Warning"), ALIGN_CENTER,				 N_("You have option config.saving_style set to "				 "a de facto obsolete value. The configuration "				 "saving algorithms of ELinks were changed from "				 "the last time you upgraded ELinks. Now, only "				 "those options which you actually changed are "				 "saved to the configuration file, instead of "				 "just all the options. This simplifies our "				 "situation greatly when we see that some option "				 "has inappropriate default value or we need to "				 "change semantic of some option in a subtle way. "				 "Thus, we recommend you to change the value of "				 "config.saving_style option to 3 in order to get "				 "the \"right\" behaviour. Apologies for any "				 "inconvience caused."));		}	}	if (first_use) {		/* Only open the goto URL dialog if no URI was passed on the		 * command line. */		void *handler = uri ? NULL : dialog_goto_url_open;		first_use = 0;		msg_box(term, NULL, 0,			N_("Welcome"), ALIGN_CENTER,			N_("Welcome to ELinks!\n\n"			"Press ESC for menu. Documentation is available in "			"Help menu."),			ses, 1,			N_("~OK"), handler, B_ENTER | B_ESC);		/* If there is no URI the goto dialog will pop up so there is		 * no need to call setup_session(). */		if (!uri) return 1;#ifdef CONFIG_BOOKMARKS	} else if (!uri && get_opt_bool("ui.sessions.auto_restore")) {		unsigned char *folder;		folder = get_opt_str("ui.sessions.auto_save_foldername");		open_bookmark_folder(ses, folder);		return 1;#endif	}	/* If there's a URI to load we have to call */	return 0;}/* First load the current URI of the base session. In most cases it will just * be fetched from the cache so that the new tab will not appear ``empty' while * loading the real URI or showing the goto URL dialog. */static voidsetup_session(struct session *ses, struct uri *uri, struct session *base){	if (base && have_location(base))		goto_uri(ses, cur_loc(base)->vs.uri);	if (uri) {		goto_uri(ses, uri);	} else if (!goto_url_home(ses)) {		if (get_opt_bool("ui.startup_goto_dialog")) {			dialog_goto_url_open(ses);		}	}}struct session *init_session(struct session *base_session, struct terminal *term,	     struct uri *uri, int in_background){	struct session *ses = mem_calloc(1, sizeof(*ses));	if (!ses) return NULL;	ses->tab = init_tab(term, ses, tabwin_func);	if (!ses->tab) {		mem_free(ses);		return NULL;	}	create_history(&ses->history);	init_list(ses->scrn_frames);	init_list(ses->more_files);	init_list(ses->type_queries);	ses->task.type = TASK_NONE;	ses->display_timer = -1;#ifdef CONFIG_LEDS	init_led_panel(&ses->status.leds);	ses->status.ssl_led = register_led(ses, 0);	ses->status.insert_mode_led = register_led(ses, 1);	ses->status.ecmascript_led = register_led(ses, 2);	ses->status.popup_led = register_led(ses, 3);#endif	ses->status.force_show_status_bar = -1;	ses->status.force_show_title_bar = -1;	add_to_list(sessions, ses);	/* Update the status -- most importantly the info about whether to the	 * show the title, tab and status bar -- _before_ loading the URI so	 * the document cache is not filled with useless documents if the	 * content is already cached.	 *	 * For big document it also reduces memory usage quite a bit because	 * (atleast that is my interpretation --jonas) the old document will	 * have a chance to be released before rendering a new one. A few	 * numbers when opening a new tab while viewing debians package list	 * for unstable:	 *	 * 9307 jonas     15   0 34252  30m 5088 S  0.0 12.2   0:03.63 elinks-old	 * 9305 jonas     15   0 17060  13m 5088 S  0.0  5.5   0:02.07 elinks-new	 */	update_status();	/* Check if the newly inserted session is the only in the list and do	 * the special setup for the first session, */	if (!list_is_singleton(sessions) || !setup_first_session(ses, uri)) {		setup_session(ses, uri, base_session);	}	if (!in_background)		switch_to_tab(term, get_tab_number(ses->tab), -1);	return ses;}static voidinit_remote_session(struct session *ses, enum remote_session_flags *remote_ptr,		    struct uri *uri){	enum remote_session_flags remote = *remote_ptr;	if (remote & SES_REMOTE_CURRENT_TAB) {		goto_uri(ses, uri);		/* Mask out the current tab flag */		*remote_ptr = remote & ~SES_REMOTE_CURRENT_TAB;		/* Remote session was masked out. Open all following URIs in		 * new tabs, */		if (!*remote_ptr)			*remote_ptr = SES_REMOTE_NEW_TAB;

⌨️ 快捷键说明

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