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

📄 spidermonkey.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 5 页
字号:
	JSCLASS_HAS_PRIVATE,	JS_PropertyStub, JS_PropertyStub,	unibar_get_property, unibar_set_property,	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};static const JSClass statusbar_class = {	"statusbar",	JSCLASS_HAS_PRIVATE,	JS_PropertyStub, JS_PropertyStub,	unibar_get_property, unibar_set_property,	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};enum unibar_prop { JSP_UNIBAR_VISIBLE };static const JSPropertySpec unibar_props[] = {	{ "visible",	JSP_UNIBAR_VISIBLE,	JSPROP_ENUMERATE },	{ NULL }};static JSBoolunibar_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	JSObject *parent = JS_GetParent(ctx, obj);	struct view_state *vs = JS_GetPrivate(ctx, parent);	struct document_view *doc_view = vs->doc_view;	struct session_status *status = &doc_view->session->status;	unsigned char *bar = JS_GetPrivate(ctx, obj);	struct jsval_property prop;	set_prop_undef(&prop);	if (!JSVAL_IS_INT(id))		return JS_TRUE;	switch (JSVAL_TO_INT(id)) {	case JSP_UNIBAR_VISIBLE:#define unibar_fetch(bar) \	set_prop_boolean(&prop, status->force_show_##bar##_bar >= 0 \	          ? status->force_show_##bar##_bar \	          : status->show_##bar##_bar)		switch (*bar) {		case 's':			unibar_fetch(status);			break;		case 't':			unibar_fetch(title);			break;		default:			set_prop_boolean(&prop, 0);			break;		}#undef unibar_fetch		break;	default:		INTERNAL("Invalid ID %d in unibar_get_property().", JSVAL_TO_INT(id));		return JS_TRUE;	}	value_to_jsval(ctx, vp, &prop);	return JS_TRUE;}static JSBoolunibar_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	JSObject *parent = JS_GetParent(ctx, obj);	struct view_state *vs = JS_GetPrivate(ctx, parent);	struct document_view *doc_view = vs->doc_view;	struct session_status *status = &doc_view->session->status;	unsigned char *bar = JS_GetPrivate(ctx, obj);	union jsval_union v;	if (!JSVAL_IS_INT(id))		return JS_TRUE;	switch (JSVAL_TO_INT(id)) {	case JSP_UNIBAR_VISIBLE:		jsval_to_value(ctx, vp, JSTYPE_BOOLEAN, &v);#define unibar_set(bar) \	status->force_show_##bar##_bar = v.boolean;		switch (*bar) {		case 's':			unibar_set(status);			break;		case 't':			unibar_set(title);			break;		default:			v.boolean = 0;			break;		}		register_bottom_half((void (*)(void*)) update_status, NULL);#undef unibar_set		break;	default:		INTERNAL("Invalid ID %d in unibar_set_property().", JSVAL_TO_INT(id));		return JS_TRUE;	}	return JS_TRUE;}static JSBool navigator_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static const JSClass navigator_class = {	"navigator",	JSCLASS_HAS_PRIVATE,	JS_PropertyStub, JS_PropertyStub,	navigator_get_property, JS_PropertyStub,	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};enum navigator_prop {	JSP_NAVIGATOR_APP_CODENAME,	JSP_NAVIGATOR_APP_NAME,	JSP_NAVIGATOR_APP_VERSION,	JSP_NAVIGATOR_LANGUAGE,	/* JSP_NAVIGATOR_MIME_TYPES, */	JSP_NAVIGATOR_PLATFORM,	/* JSP_NAVIGATOR_PLUGINS, */	JSP_NAVIGATOR_USER_AGENT,};static const JSPropertySpec navigator_props[] = {	{ "appCodeName",	JSP_NAVIGATOR_APP_CODENAME,	JSPROP_ENUMERATE | JSPROP_READONLY },	{ "appName",		JSP_NAVIGATOR_APP_NAME,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "appVersion",		JSP_NAVIGATOR_APP_VERSION,	JSPROP_ENUMERATE | JSPROP_READONLY },	{ "language",		JSP_NAVIGATOR_LANGUAGE,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "platform",		JSP_NAVIGATOR_PLATFORM,		JSPROP_ENUMERATE | JSPROP_READONLY },	{ "userAgent",		JSP_NAVIGATOR_USER_AGENT,	JSPROP_ENUMERATE | JSPROP_READONLY },	{ NULL }};static JSBoolnavigator_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){	struct jsval_property prop;	set_prop_undef(&prop);	if (!JSVAL_IS_INT(id))		return JS_TRUE;	switch (JSVAL_TO_INT(id)) {	case JSP_NAVIGATOR_APP_CODENAME:		set_prop_string(&prop, "Mozilla"); /* More like a constant nowadays. */		break;	case JSP_NAVIGATOR_APP_NAME:		/* This evil hack makes the compatibility checking .indexOf()		 * code find what it's looking for. */		set_prop_string(&prop, "ELinks (roughly compatible with Netscape Navigator, Mozilla and Microsoft Internet Explorer)");		break;	case JSP_NAVIGATOR_APP_VERSION:		set_prop_string(&prop, VERSION);		break;	case JSP_NAVIGATOR_LANGUAGE:#ifdef ENABLE_NLS		if (get_opt_bool("protocol.http.accept_ui_language"))			set_prop_string(&prop, language_to_iso639(current_language));		else#endif			set_prop_undef(&prop);		break;	case JSP_NAVIGATOR_PLATFORM:		set_prop_string(&prop, system_name);		break;	case JSP_NAVIGATOR_USER_AGENT:	{		/* FIXME: Code duplication. */		unsigned char *optstr = get_opt_str("protocol.http.user_agent");		if (*optstr && strcmp(optstr, " ")) {			unsigned char *ustr, ts[64] = "";			static unsigned char custr[256];			if (!list_empty(terminals)) {				unsigned int tslen = 0;				struct terminal *term = terminals.prev;				ulongcat(ts, &tslen, term->width, 3, 0);				ts[tslen++] = 'x';				ulongcat(ts, &tslen, term->height, 3, 0);			}			ustr = subst_user_agent(optstr, VERSION_STRING, system_name, ts);			if (ustr) {				safe_strncpy(custr, ustr, 256);				mem_free(ustr);				set_prop_string(&prop, custr);			} else{				set_prop_undef(&prop);			}		}	}		break;	default:		INTERNAL("Invalid ID %d in navigator_get_property().", JSVAL_TO_INT(id));		return JS_TRUE;	}	value_to_jsval(ctx, vp, &prop);	return JS_TRUE;}/*** The ELinks interface */static JSRuntime *jsrt;static voiderror_reporter(JSContext *ctx, const char *message, JSErrorReport *report){	struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);	struct terminal *term;	unsigned char *strict, *exception, *warning, *error;	struct string msg;	assert(interpreter && interpreter->vs && interpreter->vs->doc_view	       && interpreter->vs->doc_view->session	       && interpreter->vs->doc_view->session->tab);	if_assert_failed goto reported;	term = interpreter->vs->doc_view->session->tab->term;#ifdef CONFIG_LEDS	interpreter->vs->doc_view->session->status.ecmascript_led->value = 'J';#endif	if (!get_opt_bool("ecmascript.error_reporting")	    || !init_string(&msg))		goto reported;	strict	  = JSREPORT_IS_STRICT(report->flags) ? " strict" : "";	exception = JSREPORT_IS_EXCEPTION(report->flags) ? " exception" : "";	warning   = JSREPORT_IS_WARNING(report->flags) ? " warning" : "";	error	  = !report->flags ? " error" : "";	add_format_to_string(&msg, _("A script embedded in the current "			"document raised the following%s%s%s%s", term),			strict, exception, warning, error);	add_to_string(&msg, ":\n\n");	add_to_string(&msg, message);	if (report->linebuf && report->tokenptr) {		int pos = report->tokenptr - report->linebuf;		add_format_to_string(&msg, "\n\n%s\n.%*s^%*s.",			       report->linebuf,			       pos - 2, " ",			       strlen(report->linebuf) - pos - 1, " ");	}	info_box(term, MSGBOX_FREE_TEXT, N_("JavaScript Error"), ALIGN_CENTER,		 msg.source);reported:	/* Im clu'les. --pasky */	JS_ClearPendingException(ctx);}static JSBoolsafeguard(JSContext *ctx, JSScript *script){	struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);	int max_exec_time = get_opt_int("ecmascript.max_exec_time");	if (time(NULL) - interpreter->exec_start > max_exec_time) {		struct terminal *term = interpreter->vs->doc_view->session->tab->term;		/* A killer script! Alert! */		info_box(term, MSGBOX_FREE_TEXT,			 N_("JavaScript Emergency"), ALIGN_LEFT,			 msg_text(term,				  N_("A script embedded in the current document was running\n"				  "for more than %d seconds. This probably means there is\n"				  "a bug in the script and it could have halted the whole\n"				  "ELinks, so the script execution was interrupted."),				  max_exec_time));		return JS_FALSE;	}	return JS_TRUE;}static voidsetup_safeguard(struct ecmascript_interpreter *interpreter,                JSContext *ctx){	interpreter->exec_start = time(NULL);	JS_SetBranchCallback(ctx, safeguard);}voidspidermonkey_init(void){	jsrt = JS_NewRuntime(0x400000UL);}voidspidermonkey_done(void){	JS_DestroyRuntime(jsrt);	JS_ShutDown();}void *spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter){	JSContext *ctx;	JSObject *window_obj, *document_obj, *forms_obj, *location_obj,	         *statusbar_obj, *menubar_obj, *navigator_obj;	assert(interpreter);	ctx = JS_NewContext(jsrt, 8192 /* Stack allocation chunk size */);	if (!ctx)		return NULL;	interpreter->backend_data = ctx;	JS_SetContextPrivate(ctx, interpreter);	/* TODO: Make JSOPTION_STRICT and JSOPTION_WERROR configurable. */#ifndef JSOPTION_COMPILE_N_GO#define JSOPTION_COMPILE_N_GO 0 /* Older SM versions don't have it. */#endif	/* XXX: JSOPTION_COMPILE_N_GO will go (will it?) when we implement	 * some kind of bytecode cache. (If we will ever do that.) */	JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_COMPILE_N_GO);	JS_SetErrorReporter(ctx, error_reporter);	window_obj = JS_NewObject(ctx, (JSClass *) &window_class, NULL, NULL);	if (!window_obj) {		spidermonkey_put_interpreter(interpreter);		return NULL;	}	JS_InitStandardClasses(ctx, window_obj);	JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props);	JS_DefineFunctions(ctx, window_obj, (JSFunctionSpec *) window_funcs);	JS_SetPrivate(ctx, window_obj, interpreter->vs);	document_obj = JS_InitClass(ctx, window_obj, NULL,				    (JSClass *) &document_class, NULL, 0,				    (JSPropertySpec *) document_props,				    (JSFunctionSpec *) document_funcs,				    NULL, NULL);	forms_obj = JS_InitClass(ctx, document_obj, NULL,				    (JSClass *) &forms_class, NULL, 0,				    (JSPropertySpec *) forms_props,				    (JSFunctionSpec *) forms_funcs,				    NULL, NULL);	location_obj = JS_InitClass(ctx, window_obj, NULL,				    (JSClass *) &location_class, NULL, 0,				    (JSPropertySpec *) location_props,				    (JSFunctionSpec *) location_funcs,				    NULL, NULL);	menubar_obj = JS_InitClass(ctx, window_obj, NULL,				   (JSClass *) &menubar_class, NULL, 0,				   (JSPropertySpec *) unibar_props, NULL,				   NULL, NULL);	JS_SetPrivate(ctx, menubar_obj, "t");	statusbar_obj = JS_InitClass(ctx, window_obj, NULL,				     (JSClass *) &statusbar_class, NULL, 0,				     (JSPropertySpec *) unibar_props, NULL,				     NULL, NULL);	JS_SetPrivate(ctx, statusbar_obj, "s");	navigator_obj = JS_InitClass(ctx, window_obj, NULL,				     (JSClass *) &navigator_class, NULL, 0,				     (JSPropertySpec *) navigator_props, NULL,				     NULL, NULL);	return ctx;}voidspidermonkey_put_interpreter(struct ecmascript_interpreter *interpreter){	JSContext *ctx;	assert(interpreter);	ctx = interpreter->backend_data;	JS_DestroyContext(ctx);	interpreter->backend_data = NULL;}voidspidermonkey_eval(struct ecmascript_interpreter *interpreter,                  struct string *code){	JSContext *ctx;	jsval rval;	assert(interpreter);	ctx = interpreter->backend_data;	setup_safeguard(interpreter, ctx);	JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx),	                  code->source, code->length, "", 0, &rval);}unsigned char *spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter,			     struct string *code){	JSContext *ctx;	jsval rval;	union jsval_union v;	assert(interpreter);	ctx = interpreter->backend_data;	setup_safeguard(interpreter, ctx);	if (JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx),			      code->source, code->length, "", 0, &rval)	    == JS_FALSE) {		return NULL;	}	if (JSVAL_IS_VOID(rval)) {		/* Undefined value. */		return NULL;	}	jsval_to_value(ctx, &rval, JSTYPE_STRING, &v);	if (!v.string) return NULL;	return stracpy(v.string);}intspidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter,			   struct string *code){	JSContext *ctx;	jsval rval;	union jsval_union v;	assert(interpreter);	ctx = interpreter->backend_data;	setup_safeguard(interpreter, ctx);	if (JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx),			      code->source, code->length, "", 0, &rval)	    == JS_FALSE) {		return -1;	}	if (JSVAL_IS_VOID(rval)) {		/* Undefined value. */		return -1;	}	jsval_to_value(ctx, &rval, JSTYPE_BOOLEAN, &v);	return v.boolean;}

⌨️ 快捷键说明

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