📄 spidermonkey.c
字号:
return JS_TRUE; jsval_to_value(ctx, &argv[0], JSTYPE_STRING, &v); if (!v.string || !*v.string) return JS_TRUE; info_box(vs->doc_view->session->tab->term, MSGBOX_FREE_TEXT, N_("JavaScript Alert"), ALIGN_CENTER, stracpy(v.string)); value_to_jsval(ctx, rval, &prop); return JS_TRUE;}struct delayed_open { struct session *ses; struct uri *uri;};static voiddelayed_open(void *data){ struct delayed_open *deo = data; assert(deo); open_uri_in_new_tab(deo->ses, deo->uri, 0, 0); done_uri(deo->uri); mem_free(deo);}static JSBoolwindow_open(JSContext *ctx, JSObject *obj, uintN argc,jsval *argv, jsval *rval){ struct view_state *vs = JS_GetPrivate(ctx, obj); struct document_view *doc_view = vs->doc_view; struct session *ses = doc_view->session; union jsval_union v; unsigned char *url; struct uri *uri; static time_t ratelimit_start; static int ratelimit_count; struct jsval_property prop; set_prop_undef(&prop); if (get_opt_bool("ecmascript.block_window_opening")) {#ifdef CONFIG_LEDS ses->status.popup_led->value = 'P';#endif return JS_TRUE; } if (argc < 1) return JS_TRUE; /* Ratelimit window opening. Recursive window.open() is very nice. * We permit at most 20 tabs in 2 seconds. The ratelimiter is very * rough but shall suffice against the usual cases. */ if (!ratelimit_start || time(NULL) - ratelimit_start > 2) { ratelimit_start = time(NULL); ratelimit_count = 0; } else { ratelimit_count++; if (ratelimit_count > 20) return JS_TRUE; } jsval_to_value(ctx, &argv[0], JSTYPE_STRING, &v); url = v.string; assert(url); /* TODO: Support for window naming and perhaps some window features? */ url = join_urls(doc_view->document->uri, trim_chars(url, ' ', 0)); if (!url) return JS_TRUE; uri = get_uri(url, 0); mem_free(url); if (!uri) return JS_TRUE; if (!get_cmd_opt_bool("no-connect") && !get_cmd_opt_bool("no-home") && !get_cmd_opt_bool("anonymous") && can_open_in_new(ses->tab->term)) { open_uri_in_new_window(ses, uri, ENV_ANY); set_prop_boolean(&prop, 1); } else { /* When opening a new tab, we might get rerendered, losing our * context and triggerring a disaster, so postpone that. */ struct delayed_open *deo = mem_calloc(1, sizeof(*deo)); if (deo) { deo->ses = ses; deo->uri = get_uri_reference(uri); register_bottom_half((void (*)(void *)) delayed_open, deo); set_prop_boolean(&prop, 1); } } done_uri(uri); value_to_jsval(ctx, rval, &prop); return JS_TRUE;}/* 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; struct jsval_property prop; set_prop_undef(&prop); assert(fc); assert(fc->form && fs); linknum = get_form_control_link(document, fc); /* Hiddens have no link. */ if (linknum >= 0) link = &document->links[linknum]; if (!JSVAL_IS_INT(id)) return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_INPUT_ACCESSKEY: { struct string keystr; if (!link) { set_prop_undef(&prop); break; } init_string(&keystr); make_keystroke(&keystr, link->accesskey, 0, 0); set_prop_string(&prop, keystr.source); done_string(&keystr); break; } case JSP_INPUT_ALT: set_prop_string(&prop, fc->alt); break; case JSP_INPUT_CHECKED: set_prop_boolean(&prop, fs->state); break; case JSP_INPUT_DEFAULT_CHECKED: set_prop_boolean(&prop, fc->default_state); break; case JSP_INPUT_DEFAULT_VALUE: set_prop_string(&prop, fc->default_value); break; case JSP_INPUT_DISABLED: /* FIXME: <input readonly disabled> --pasky */ set_prop_boolean(&prop, fc->mode == FORM_MODE_DISABLED); break; case JSP_INPUT_FORM: set_prop_object(&prop, parent_form); break; case JSP_INPUT_MAX_LENGTH: set_prop_int(&prop, fc->maxlength); break; case JSP_INPUT_NAME: set_prop_string(&prop, fc->name); break; case JSP_INPUT_READONLY: /* FIXME: <input readonly disabled> --pasky */ set_prop_boolean(&prop, fc->mode == FORM_MODE_READONLY); break; case JSP_INPUT_SIZE: set_prop_int(&prop, fc->size); break; case JSP_INPUT_SRC: if (link && link->where_img) set_prop_string(&prop, link->where_img); else set_prop_undef(&prop); break; case JSP_INPUT_TABINDEX: if (link) /* FIXME: This is WRONG. --pasky */ set_prop_int(&prop, link->number); else set_prop_undef(&prop); break; case JSP_INPUT_TYPE: switch (fc->type) { case FC_TEXT: set_prop_string(&prop, "text"); break; case FC_PASSWORD: set_prop_string(&prop, "password"); break; case FC_FILE: set_prop_string(&prop, "file"); break; case FC_CHECKBOX: set_prop_string(&prop, "checkbox"); break; case FC_RADIO: set_prop_string(&prop, "radio"); break; case FC_SUBMIT: set_prop_string(&prop, "submit"); break; case FC_IMAGE: set_prop_string(&prop, "image"); break; case FC_RESET: set_prop_string(&prop, "reset"); break; case FC_BUTTON: set_prop_string(&prop, "button"); break; case FC_HIDDEN: set_prop_string(&prop, "hidden"); break; default: INTERNAL("input_get_property() upon a non-input item."); break; } break; case JSP_INPUT_VALUE: set_prop_string(&prop, fs->value); break; default: INTERNAL("Invalid ID %d in input_get_property().", JSVAL_TO_INT(id)); return JS_TRUE; } value_to_jsval(ctx, vp, &prop); 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; union jsval_union v; assert(fc); assert(fc->form && fs); linknum = get_form_control_link(document, fc); /* Hiddens have no link. */ if (linknum >= 0) link = &document->links[linknum]; if (!JSVAL_IS_INT(id)) return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_INPUT_ACCESSKEY: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); if (link) link->accesskey = read_key(v.string); break; case JSP_INPUT_ALT: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&fc->alt, stracpy(v.string)); break; case JSP_INPUT_CHECKED: if (fc->type != FC_CHECKBOX && fc->type != FC_RADIO) break; jsval_to_value(ctx, vp, JSTYPE_BOOLEAN, &v); fs->state = v.boolean; break; case JSP_INPUT_DISABLED: /* FIXME: <input readonly disabled> --pasky */ jsval_to_value(ctx, vp, JSTYPE_BOOLEAN, &v); fc->mode = (v.boolean ? FORM_MODE_DISABLED : fc->mode == FORM_MODE_READONLY ? FORM_MODE_READONLY : FORM_MODE_NORMAL); break; case JSP_INPUT_MAX_LENGTH: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); fc->maxlength = atol(v.string); break; case JSP_INPUT_NAME: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&fc->name, stracpy(v.string)); break; case JSP_INPUT_READONLY: /* FIXME: <input readonly disabled> --pasky */ jsval_to_value(ctx, vp, JSTYPE_BOOLEAN, &v); fc->mode = (v.boolean ? FORM_MODE_READONLY : fc->mode == FORM_MODE_DISABLED ? FORM_MODE_DISABLED : FORM_MODE_NORMAL); break; case JSP_INPUT_SRC: if (link) { jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&link->where_img, stracpy(v.string)); } break; case JSP_INPUT_VALUE: if (fc->type == FC_FILE) break; /* A huge security risk otherwise. */ jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&fs->value, stracpy(v.string)); 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; struct jsval_property prop; set_prop_boolean(&prop, 0); 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); value_to_jsval(ctx, rval, &prop); 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; struct jsval_property prop; set_prop_boolean(&prop, 0); 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); value_to_jsval(ctx, rval, &prop); 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -