📄 spidermonkey.c
字号:
/* 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); struct jsval_property prop; set_prop_undef(&prop); if (JSVAL_IS_STRING(id)) { form_elements_namedItem(ctx, obj, 1, &id, vp); return JS_TRUE; } else if (!JSVAL_IS_INT(id)) return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_FORM_ELEMENTS_LENGTH: { struct form_control *fc; int counter = 0; foreach (fc, form->items) counter++; set_prop_int(&prop, counter); break; } default: /* Array index. */ form_elements_item(ctx, obj, 1, &id, vp); return JS_TRUE; } value_to_jsval(ctx, vp, &prop); return JS_TRUE;}static JSBoolform_elements_item(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 form_view *form_view = JS_GetPrivate(ctx, parent_form); struct form *form = find_form_by_form_view(document, form_view); struct form_control *fc; union jsval_union v; int counter = -1; int index; struct jsval_property prop; set_prop_undef(&prop); if (argc != 1) return JS_TRUE; jsval_to_value(ctx, &argv[0], JSTYPE_STRING, &v); index = atol(v.string); foreach (fc, form->items) { counter++; if (counter == index) { JSObject *fcobj = get_form_control_object(ctx, parent_form, fc->type, find_form_state(doc_view, fc)); if (fcobj) { set_prop_object(&prop, fcobj); } else { set_prop_undef(&prop); } value_to_jsval(ctx, rval, &prop); return JS_TRUE; } } return JS_TRUE;}static JSBoolform_elements_namedItem(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 form_view *form_view = JS_GetPrivate(ctx, parent_form); struct form *form = find_form_by_form_view(document, form_view); struct form_control *fc; union jsval_union v; struct jsval_property prop; set_prop_undef(&prop); if (argc != 1) return JS_TRUE; jsval_to_value(ctx, &argv[0], JSTYPE_STRING, &v); if (!v.string || !*v.string) return JS_TRUE; foreach (fc, form->items) { if (fc->name && !strcasecmp(v.string, fc->name)) { JSObject *fcobj = get_form_control_object(ctx, parent_form, fc->type, find_form_state(doc_view, fc)); if (fcobj) { set_prop_object(&prop, fcobj); } else { set_prop_undef(&prop); } value_to_jsval(ctx, rval, &prop); return JS_TRUE; } } return JS_TRUE;}static JSBool form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static JSBool form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);static const JSClass form_class = { "form", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, form_get_property, form_set_property, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub};enum form_prop { JSP_FORM_ACTION, JSP_FORM_ELEMENTS, JSP_FORM_ENCODING, JSP_FORM_LENGTH, JSP_FORM_METHOD, JSP_FORM_NAME, JSP_FORM_TARGET};static const JSPropertySpec form_props[] = { { "action", JSP_FORM_ACTION, JSPROP_ENUMERATE }, { "elements", JSP_FORM_ELEMENTS, JSPROP_ENUMERATE }, { "encoding", JSP_FORM_ENCODING, JSPROP_ENUMERATE }, { "length", JSP_FORM_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY }, { "method", JSP_FORM_METHOD, JSPROP_ENUMERATE }, { "name", JSP_FORM_NAME, JSPROP_ENUMERATE }, { "target", JSP_FORM_TARGET, JSPROP_ENUMERATE }, { NULL }};static JSBool form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBool form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static const JSFunctionSpec form_funcs[] = { { "reset", form_reset, 0 }, { "submit", form_submit, 0 }, { NULL }};static JSBoolform_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){ /* DBG("doc %p %s\n", parent_doc, JS_GetStringBytes(JS_ValueToString(ctx, OBJECT_TO_JSVAL(parent_doc)))); */ JSObject *parent_doc = JS_GetParent(ctx, obj); 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 form_view *fv = JS_GetPrivate(ctx, obj); struct form *form = find_form_by_form_view(doc_view->document, fv); struct jsval_property prop; set_prop_undef(&prop); assert(form); if (JSVAL_IS_STRING(id)) { struct form_control *fc; union jsval_union v; jsval_to_value(ctx, &id, JSTYPE_STRING, &v); foreach (fc, form->items) { JSObject *fcobj = NULL; if (!fc->name || strcasecmp(v.string, fc->name)) continue; fcobj = get_form_control_object(ctx, obj, fc->type, find_form_state(doc_view, fc)); if (fcobj) { set_prop_object(&prop, fcobj); } else { set_prop_undef(&prop); } goto convert; } return JS_TRUE; } else if (!JSVAL_IS_INT(id)) return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_FORM_ACTION: set_prop_string(&prop, form->action); break; case JSP_FORM_ELEMENTS: { /* jsform ('form') is form_elements' parent; who knows is that's correct */ JSObject *jsform_elems = JS_NewObject(ctx, (JSClass *) &form_elements_class, NULL, obj); JS_DefineProperties(ctx, jsform_elems, (JSPropertySpec *) form_elements_props); JS_DefineFunctions(ctx, jsform_elems, (JSFunctionSpec *) form_elements_funcs); set_prop_object(&prop, jsform_elems); /* SM will cache this property value for us so we create this * just once per form. */ } break; case JSP_FORM_ENCODING: switch (form->method) { case FORM_METHOD_GET: case FORM_METHOD_POST: set_prop_string(&prop, "application/x-www-form-urlencoded"); break; case FORM_METHOD_POST_MP: set_prop_string(&prop, "multipart/form-data"); break; case FORM_METHOD_POST_TEXT_PLAIN: set_prop_string(&prop, "text/plain"); break; } break; case JSP_FORM_LENGTH: { struct form_control *fc; int counter = 0; foreach (fc, form->items) counter++; set_prop_int(&prop, counter); break; } case JSP_FORM_METHOD: switch (form->method) { case FORM_METHOD_GET: set_prop_string(&prop, "GET"); break; case FORM_METHOD_POST: case FORM_METHOD_POST_MP: case FORM_METHOD_POST_TEXT_PLAIN: set_prop_string(&prop, "POST"); break; } break; case JSP_FORM_NAME: set_prop_string(&prop, form->name); break; case JSP_FORM_TARGET: set_prop_string(&prop, form->target); break; default: INTERNAL("Invalid ID %d in form_get_property().", JSVAL_TO_INT(id)); return JS_TRUE; }convert: value_to_jsval(ctx, vp, &prop); return JS_TRUE;}static JSBoolform_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp){ JSObject *parent_doc = JS_GetParent(ctx, obj); 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 form_view *fv = JS_GetPrivate(ctx, obj); struct form *form = find_form_by_form_view(doc_view->document, fv); union jsval_union v; assert(form); if (!JSVAL_IS_INT(id)) return JS_TRUE; switch (JSVAL_TO_INT(id)) { case JSP_FORM_ACTION: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&form->action, stracpy(v.string)); break; case JSP_FORM_ENCODING: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); if (!strcasecmp(v.string, "application/x-www-form-urlencoded")) { form->method = form->method == FORM_METHOD_GET ? FORM_METHOD_GET : FORM_METHOD_POST; } else if (!strcasecmp(v.string, "multipart/form-data")) { form->method = FORM_METHOD_POST_MP; } else if (!strcasecmp(v.string, "text/plain")) { form->method = FORM_METHOD_POST_TEXT_PLAIN; } break; case JSP_FORM_METHOD: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); if (!strcasecmp(v.string, "GET")) { form->method = FORM_METHOD_GET; } else if (!strcasecmp(v.string, "POST")) { form->method = FORM_METHOD_POST; } break; case JSP_FORM_NAME: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&form->name, stracpy(v.string)); break; case JSP_FORM_TARGET: jsval_to_value(ctx, vp, JSTYPE_STRING, &v); mem_free_set(&form->target, stracpy(v.string)); break; default: INTERNAL("Invalid ID %d in form_set_property().", JSVAL_TO_INT(id)); break; } return JS_TRUE;}static JSBoolform_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSObject *parent_doc = JS_GetParent(ctx, obj); 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 form_view *fv = JS_GetPrivate(ctx, obj); struct form *form = find_form_by_form_view(doc_view->document, fv); struct jsval_property prop; set_prop_boolean(&prop, 0); assert(form); do_reset_form(doc_view, form); draw_forms(doc_view->session->tab->term, doc_view); value_to_jsval(ctx, rval, &prop); return JS_TRUE;}static JSBoolform_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSObject *parent_doc = JS_GetParent(ctx, obj); 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 session *ses = doc_view->session; struct form_view *fv = JS_GetPrivate(ctx, obj); struct form *form = find_form_by_form_view(doc_view->document, fv); struct jsval_property prop; set_prop_boolean(&prop, 0); assert(form); submit_given_form(ses, doc_view, form); value_to_jsval(ctx, rval, &prop); return JS_TRUE;}static JSObject *get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -