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

📄 form.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* The SpiderMonkey window object implementation. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "ecmascript/spidermonkey/util.h"#include "bfu/dialog.h"#include "cache/cache.h"#include "cookies/cookies.h"#include "dialogs/menu.h"#include "dialogs/status.h"#include "document/html/frames.h"#include "document/document.h"#include "document/forms.h"#include "document/view.h"#include "ecmascript/ecmascript.h"#include "ecmascript/spidermonkey/form.h"#include "intl/gettext/libintl.h"#include "main/select.h"#include "osdep/newwin.h"#include "osdep/sysname.h"#include "protocol/http/http.h"#include "protocol/uri.h"#include "session/history.h"#include "session/location.h"#include "session/session.h"#include "session/task.h"#include "terminal/tab.h"#include "terminal/terminal.h"#include "util/conv.h"#include "util/memory.h"#include "util/string.h"#include "viewer/text/draw.h"#include "viewer/text/form.h"#include "viewer/text/link.h"#include "viewer/text/vs.h"/* Accordingly to the JS specs, each input type should own object. That'd be a * huge PITA though, however DOM comes to the rescue and defines just a single * HTMLInputElement. The difference could be spotted only by some clever tricky * JS code, but I hope it doesn't matter anywhere. --pasky */static JSBool input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static JSBool input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static const JSClass input_class = {	"input", /* here, we unleash ourselves */	JSCLASS_HAS_PRIVATE,	JS_PropertyStub, JS_PropertyStub,	input_get_property, input_set_property,	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};enum input_prop {	JSP_INPUT_ACCESSKEY,	JSP_INPUT_ALT,	JSP_INPUT_CHECKED,	JSP_INPUT_DEFAULT_CHECKED,	JSP_INPUT_DEFAULT_VALUE,	JSP_INPUT_DISABLED,	JSP_INPUT_FORM,	JSP_INPUT_MAX_LENGTH,	JSP_INPUT_NAME,	JSP_INPUT_READONLY,	JSP_INPUT_SIZE,	JSP_INPUT_SRC,	JSP_INPUT_TABINDEX,	JSP_INPUT_TYPE,	JSP_INPUT_VALUE};/* XXX: Some of those are marked readonly just because we can't change them * safely now. Changing default* values would affect all open instances of the * document, leading to a potential security risk. Changing size and type would * require re-rendering the document (TODO), tabindex would require renumbering * of all links and whatnot. --pasky */static const JSPropertySpec input_props[] = {	{ "accessKey",	JSP_INPUT_ACCESSKEY,	JSPROP_ENUMERATE },	{ "alt",	JSP_INPUT_ALT,		JSPROP_ENUMERATE },	{ "checked",	JSP_INPUT_CHECKED,	JSPROP_ENUMERATE },	{ "defaultChecked",JSP_INPUT_DEFAULT_CHECKED,JSPROP_ENUMERATE },	{ "defaultValue",JSP_INPUT_DEFAULT_VALUE,JSPROP_ENUMERATE },	{ "disabled",	JSP_INPUT_DISABLED,	JSPROP_ENUMERATE },	{ "form",	JSP_INPUT_FORM,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "maxLength",	JSP_INPUT_MAX_LENGTH,	JSPROP_ENUMERATE },	{ "name",	JSP_INPUT_NAME,		JSPROP_ENUMERATE },	{ "readonly",	JSP_INPUT_READONLY,	JSPROP_ENUMERATE },	{ "size",	JSP_INPUT_SIZE,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "src",	JSP_INPUT_SRC,		JSPROP_ENUMERATE },	{ "tabindex",	JSP_INPUT_TABINDEX,	JSPROP_ENUMERATE | JSPROP_READONLY },	{ "type",	JSP_INPUT_TYPE,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "value",	JSP_INPUT_VALUE,	JSPROP_ENUMERATE },	{ NULL }};static JSBool input_blur(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBool input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBool input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBool input_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static const JSFunctionSpec input_funcs[] = {	{ "blur",	input_blur,	0 },	{ "click",	input_click,	0 },	{ "focus",	input_focus,	0 },	{ "select",	input_select,	0 },	{ NULL }};static JSBoolinput_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	JSObject *parent_form = JS_GetParent(ctx, obj);	JSObject *parent_doc = JS_GetParent(ctx, parent_form);	JSObject *parent_win = JS_GetParent(ctx, parent_doc);	struct view_state *vs = JS_GetPrivate(ctx, parent_win);	struct document_view *doc_view = vs->doc_view;	struct document *document = doc_view->document;	struct form_state *fs = JS_GetPrivate(ctx, obj);	struct form_control *fc = find_form_control(document, fs);	int linknum;	struct link *link = NULL;	assert(fc);	assert(fc->form && fs);	if (!JSVAL_IS_INT(id))		return JS_TRUE;	linknum = get_form_control_link(document, fc);	/* Hiddens have no link. */	if (linknum >= 0) link = &document->links[linknum];	undef_to_jsval(ctx, vp);	switch (JSVAL_TO_INT(id)) {	case JSP_INPUT_ACCESSKEY:	{		struct string keystr;		if (!link) break;		init_string(&keystr);		add_accesskey_to_string(&keystr, link->accesskey);		string_to_jsval(ctx, vp, keystr.source);		done_string(&keystr);		break;	}	case JSP_INPUT_ALT:		string_to_jsval(ctx, vp, fc->alt);		break;	case JSP_INPUT_CHECKED:		boolean_to_jsval(ctx, vp, fs->state);		break;	case JSP_INPUT_DEFAULT_CHECKED:		boolean_to_jsval(ctx, vp, fc->default_state);		break;	case JSP_INPUT_DEFAULT_VALUE:		string_to_jsval(ctx, vp, fc->default_value);		break;	case JSP_INPUT_DISABLED:		/* FIXME: <input readonly disabled> --pasky */		boolean_to_jsval(ctx, vp, fc->mode == FORM_MODE_DISABLED);		break;	case JSP_INPUT_FORM:		object_to_jsval(ctx, vp, parent_form);		break;	case JSP_INPUT_MAX_LENGTH:		int_to_jsval(ctx, vp, fc->maxlength);		break;	case JSP_INPUT_NAME:		string_to_jsval(ctx, vp, fc->name);		break;	case JSP_INPUT_READONLY:		/* FIXME: <input readonly disabled> --pasky */		boolean_to_jsval(ctx, vp, fc->mode == FORM_MODE_READONLY);		break;	case JSP_INPUT_SIZE:		int_to_jsval(ctx, vp, fc->size);		break;	case JSP_INPUT_SRC:		if (link && link->where_img)			string_to_jsval(ctx, vp, link->where_img);		break;	case JSP_INPUT_TABINDEX:		if (link)			/* FIXME: This is WRONG. --pasky */			int_to_jsval(ctx, vp, link->number);		break;	case JSP_INPUT_TYPE:	{		unsigned char *s = NULL;		switch (fc->type) {		case FC_TEXT: s = "text"; break;		case FC_PASSWORD: s = "password"; break;		case FC_FILE: s = "file"; break;		case FC_CHECKBOX: s = "checkbox"; break;		case FC_RADIO: s = "radio"; break;		case FC_SUBMIT: s = "submit"; break;		case FC_IMAGE: s = "image"; break;		case FC_RESET: s = "reset"; break;		case FC_BUTTON: s = "button"; break;		case FC_HIDDEN: s = "hidden"; break;		default: INTERNAL("input_get_property() upon a non-input item."); break;		}		string_to_jsval(ctx, vp, s);		break;	}	case JSP_INPUT_VALUE:		string_to_jsval(ctx, vp, fs->value);		break;	default:		INTERNAL("Invalid ID %d in input_get_property().", JSVAL_TO_INT(id));		break;	}	return JS_TRUE;}static JSBoolinput_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	JSObject *parent_form = JS_GetParent(ctx, obj);	JSObject *parent_doc = JS_GetParent(ctx, parent_form);	JSObject *parent_win = JS_GetParent(ctx, parent_doc);	struct view_state *vs = JS_GetPrivate(ctx, parent_win);	struct document_view *doc_view = vs->doc_view;	struct document *document = doc_view->document;	struct form_state *fs = JS_GetPrivate(ctx, obj);	struct form_control *fc = find_form_control(document, fs);	int linknum;	struct link *link = NULL;	assert(fc);	assert(fc->form && fs);	if (!JSVAL_IS_INT(id))		return JS_TRUE;	linknum = get_form_control_link(document, fc);	/* Hiddens have no link. */	if (linknum >= 0) link = &document->links[linknum];	switch (JSVAL_TO_INT(id)) {	case JSP_INPUT_ACCESSKEY:		if (link)			link->accesskey = accesskey_string_to_unicode(jsval_to_string(ctx, vp));		break;	case JSP_INPUT_ALT:		mem_free_set(&fc->alt, stracpy(jsval_to_string(ctx, vp)));		break;	case JSP_INPUT_CHECKED:		if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO)			break;		fs->state = jsval_to_boolean(ctx, vp);		break;	case JSP_INPUT_DISABLED:		/* FIXME: <input readonly disabled> --pasky */		fc->mode = (jsval_to_boolean(ctx, vp) ? FORM_MODE_DISABLED		                      : fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY		                                                       : FORM_MODE_NORMAL);		break;	case JSP_INPUT_MAX_LENGTH:		fc->maxlength = atol(jsval_to_string(ctx, vp));		break;	case JSP_INPUT_NAME:		mem_free_set(&fc->name, stracpy(jsval_to_string(ctx, vp)));		break;	case JSP_INPUT_READONLY:		/* FIXME: <input readonly disabled> --pasky */		fc->mode = (jsval_to_boolean(ctx, vp) ? FORM_MODE_READONLY		                      : fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED		                                                       : FORM_MODE_NORMAL);		break;	case JSP_INPUT_SRC:		if (link) {			mem_free_set(&link->where_img, stracpy(jsval_to_string(ctx, vp)));		}		break;	case JSP_INPUT_VALUE:		if (fc->type == FC_FILE)			break; /* A huge security risk otherwise. */		mem_free_set(&fs->value, stracpy(jsval_to_string(ctx, vp)));		if (fc->type == FC_TEXT || fc->type == FC_PASSWORD)			fs->state = strlen(fs->value);		break;	default:		INTERNAL("Invalid ID %d in input_set_property().", JSVAL_TO_INT(id));		return JS_TRUE;	}	return JS_TRUE;}static JSBoolinput_blur(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	/* We are a text-mode browser and there *always* has to be something	 * selected.  So we do nothing for now. (That was easy.) */	return JS_TRUE;}static JSBoolinput_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	JSObject *parent_form = JS_GetParent(ctx, obj);	JSObject *parent_doc = JS_GetParent(ctx, parent_form);	JSObject *parent_win = JS_GetParent(ctx, parent_doc);	struct view_state *vs = JS_GetPrivate(ctx, parent_win);	struct document_view *doc_view = vs->doc_view;	struct document *document = doc_view->document;	struct session *ses = doc_view->session;	struct form_state *fs = JS_GetPrivate(ctx, obj);	struct form_control *fc;	int linknum;	assert(fs);	fc = find_form_control(document, fs);	assert(fc);	linknum = get_form_control_link(document, fc);	/* Hiddens have no link. */	if (linknum < 0)		return JS_TRUE;	/* Restore old current_link afterwards? */	jump_to_link_number(ses, doc_view, linknum);	if (enter(ses, doc_view, 0) == FRAME_EVENT_REFRESH)		refresh_view(ses, doc_view, 0);	else		print_screen_status(ses);	boolean_to_jsval(ctx, rval, 0);	return JS_TRUE;}static JSBoolinput_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	JSObject *parent_form = JS_GetParent(ctx, obj);	JSObject *parent_doc = JS_GetParent(ctx, parent_form);	JSObject *parent_win = JS_GetParent(ctx, parent_doc);	struct view_state *vs = JS_GetPrivate(ctx, parent_win);	struct document_view *doc_view = vs->doc_view;	struct document *document = doc_view->document;	struct session *ses = doc_view->session;	struct form_state *fs = JS_GetPrivate(ctx, obj);	struct form_control *fc;	int linknum;	assert(fs);	fc = find_form_control(document, fs);	assert(fc);	linknum = get_form_control_link(document, fc);	/* Hiddens have no link. */	if (linknum < 0)		return JS_TRUE;	jump_to_link_number(ses, doc_view, linknum);	boolean_to_jsval(ctx, rval, 0);	return JS_TRUE;}static JSBoolinput_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){	/* We support no text selecting yet.  So we do nothing for now.	 * (That was easy, too.) */	return JS_TRUE;}static JSObject *get_input_object(JSContext *ctx, JSObject *jsform, struct form_state *fs){	if (!fs->ecmascript_obj) {		/* jsform ('form') is input's parent */		/* FIXME: That is NOT correct since the real containing element		 * should be its parent, but gimme DOM first. --pasky */		JSObject *jsinput = JS_NewObject(ctx, (JSClass *) &input_class, NULL, jsform);		JS_DefineProperties(ctx, jsinput, (JSPropertySpec *) input_props);		JS_DefineFunctions(ctx, jsinput, (JSFunctionSpec *) input_funcs);		JS_SetPrivate(ctx, jsinput, fs);		fs->ecmascript_obj = jsinput;	}	return fs->ecmascript_obj;}static JSObject *get_form_control_object(JSContext *ctx, JSObject *jsform, enum form_type type, struct form_state *fs){	switch (type) {		case FC_TEXT:		case FC_PASSWORD:		case FC_FILE:		case FC_CHECKBOX:		case FC_RADIO:		case FC_SUBMIT:		case FC_IMAGE:		case FC_RESET:		case FC_BUTTON:		case FC_HIDDEN:			return get_input_object(ctx, jsform, fs);		case FC_TEXTAREA:		case FC_SELECT:			/* TODO */			return NULL;		default:			INTERNAL("Weird fc->type %d", type);			return NULL;	}}static JSBool form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static const JSClass form_elements_class = {	"elements",	JSCLASS_HAS_PRIVATE,	JS_PropertyStub, JS_PropertyStub,	form_elements_get_property, JS_PropertyStub,	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};static JSBool form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBool form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static const JSFunctionSpec form_elements_funcs[] = {	{ "item",		form_elements_item,		1 },	{ "namedItem",		form_elements_namedItem,	1 },	{ NULL }};/* INTs from 0 up are equivalent to item(INT), so we have to stuff length out * of the way. */enum form_elements_prop { JSP_FORM_ELEMENTS_LENGTH = -1 };static const JSPropertySpec form_elements_props[] = {	{ "length",	JSP_FORM_ELEMENTS_LENGTH,	JSPROP_ENUMERATE | JSPROP_READONLY},	{ NULL }};static JSBoolform_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	JSObject *parent_form = JS_GetParent(ctx, obj);	JSObject *parent_doc = JS_GetParent(ctx, parent_form);	JSObject *parent_win = JS_GetParent(ctx, parent_doc);	struct view_state *vs = JS_GetPrivate(ctx, parent_win);	struct document_view *doc_view = vs->doc_view;	struct document *document = doc_view->document;	struct form_view *form_view = JS_GetPrivate(ctx, parent_form);	struct form *form = find_form_by_form_view(document, form_view);	if (JSVAL_IS_STRING(id)) {		form_elements_namedItem(ctx, obj, 1, &id, vp);		return JS_TRUE;	}

⌨️ 快捷键说明

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