1 /* The SEE form object implementation. */
15 #include "bfu/dialog.h"
16 #include "cache/cache.h"
17 #include "cookies/cookies.h"
18 #include "dialogs/menu.h"
19 #include "dialogs/status.h"
20 #include "document/html/frames.h"
21 #include "document/document.h"
22 #include "document/forms.h"
23 #include "document/view.h"
24 #include "ecmascript/ecmascript.h"
25 #include "ecmascript/see/checktype.h"
26 #include "ecmascript/see/document.h"
27 #include "ecmascript/see/form.h"
28 #include "ecmascript/see/input.h"
29 #include "ecmascript/see/strings.h"
30 #include "ecmascript/see/window.h"
31 #include "intl/gettext/libintl.h"
32 #include "main/select.h"
33 #include "osdep/newwin.h"
34 #include "osdep/sysname.h"
35 #include "protocol/http/http.h"
36 #include "protocol/uri.h"
37 #include "session/history.h"
38 #include "session/location.h"
39 #include "session/session.h"
40 #include "session/task.h"
41 #include "terminal/tab.h"
42 #include "terminal/terminal.h"
43 #include "util/conv.h"
44 #include "util/memory.h"
45 #include "util/string.h"
46 #include "viewer/text/draw.h"
47 #include "viewer/text/form.h"
48 #include "viewer/text/link.h"
49 #include "viewer/text/vs.h"
51 static void input_get(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*);
52 static void input_put(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*, int);
53 static void js_input_blur(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
54 static void js_input_click(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
55 static void js_input_focus(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
56 static void js_input_select(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
57 static int input_canput(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
58 static int input_hasproperty(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
59 static struct js_input
*js_get_input_object(struct SEE_interpreter
*, struct js_form
*, int);
60 static struct js_input
*js_get_form_control_object(struct SEE_interpreter
*, struct js_form
*, enum form_type
, int);
62 static void js_form_elems_item(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
63 static void js_form_elems_namedItem(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
64 static void form_elems_get(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*);
65 static int form_elems_hasproperty(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
67 static void js_forms_item(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
68 static void js_forms_namedItem(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
69 static void forms_get(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*);
70 static int forms_hasproperty(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
72 static void form_get(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*);
73 static void form_put(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*, struct SEE_value
*, int);
74 static int form_canput(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
75 static int form_hasproperty(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_string
*);
76 static void js_form_reset(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
77 static void js_form_submit(struct SEE_interpreter
*, struct SEE_object
*, struct SEE_object
*, int, struct SEE_value
**, struct SEE_value
*);
80 struct SEE_objectclass js_input_object_class
= {
94 struct SEE_objectclass js_form_elems_class
= {
99 form_elems_hasproperty
,
108 struct SEE_objectclass js_forms_object_class
= {
122 struct SEE_objectclass js_form_class
= {
137 struct SEE_object object
;
138 struct js_form
*parent
;
139 struct SEE_object
*blur
;
140 struct SEE_object
*click
;
141 struct SEE_object
*focus
;
142 struct SEE_object
*select
;
146 struct js_forms_object
{
147 struct SEE_object object
;
148 struct js_document_object
*parent
;
149 struct SEE_object
*item
;
150 struct SEE_object
*namedItem
;
153 struct js_form_elems
{
154 struct SEE_object object
;
155 struct js_form
*parent
;
156 struct SEE_object
*item
;
157 struct SEE_object
*namedItem
;
162 input_get(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
163 struct SEE_string
*p
, struct SEE_value
*res
)
165 struct global_object
*g
= (struct global_object
*)interp
;
166 struct view_state
*vs
= g
->win
->vs
;
167 struct document_view
*doc_view
= vs
->doc_view
;
168 struct document
*document
= doc_view
->document
;
169 struct js_input
*input
= (struct js_input
*)o
;
170 struct js_form
*parent
= input
->parent
;
171 struct form_state
*fs
= &vs
->form_info
[input
->form_number
];
172 struct form_control
*fc
= find_form_control(document
, fs
);
174 struct link
*link
= NULL
;
175 struct SEE_string
*str
;
178 assert(fc
->form
&& fs
);
180 linknum
= get_form_control_link(document
, fc
);
181 /* Hiddens have no link. */
182 if (linknum
>= 0) link
= &document
->links
[linknum
];
183 SEE_SET_UNDEFINED(res
);
185 if (p
== s_accessKey
) {
186 struct SEE_string
*keystr
;
190 keystr
= SEE_string_new(interp
, 0);
192 append_unicode_to_SEE_string(interp
, keystr
,
194 SEE_SET_STRING(res
, keystr
);
195 } else if (p
== s_alt
) {
196 str
= string_to_SEE_string(interp
, fc
->alt
);
197 SEE_SET_STRING(res
, str
);
198 } else if (p
== s_checked
) {
199 SEE_SET_BOOLEAN(res
, fs
->state
);
200 } else if (p
== s_defaultChecked
) {
201 SEE_SET_BOOLEAN(res
, fc
->default_state
);
202 } else if (p
== s_defaultValue
) {
203 /* FIXME (bug 805): convert from the charset of the document */
204 str
= string_to_SEE_string(interp
, fc
->default_value
);
205 SEE_SET_STRING(res
, str
);
206 } else if (p
== s_disabled
) {
207 /* FIXME: <input readonly disabled> --pasky */
208 SEE_SET_BOOLEAN(res
, fc
->mode
== FORM_MODE_DISABLED
);
209 } else if (p
== s_form
) {
210 SEE_SET_OBJECT(res
, (struct SEE_object
*)parent
);
211 } else if (p
== s_maxLength
) {
212 SEE_SET_NUMBER(res
, fc
->maxlength
);
213 } else if (p
== s_name
) {
214 str
= string_to_SEE_string(interp
, fc
->name
);
215 SEE_SET_STRING(res
, str
);
216 } else if (p
== s_readonly
) {
217 /* FIXME: <input readonly disabled> --pasky */
218 SEE_SET_BOOLEAN(res
, fc
->mode
== FORM_MODE_READONLY
);
219 } else if (p
== s_size
) {
220 SEE_SET_NUMBER(res
, fc
->size
);
221 } else if (p
== s_src
) {
222 if (link
&& link
->where_img
) {
223 str
= string_to_SEE_string(interp
, link
->where_img
);
224 SEE_SET_STRING(res
, str
);
226 } else if (p
== s_tabindex
) {
228 /* FIXME: This is WRONG. --pasky */
229 SEE_SET_NUMBER(res
, link
->number
);
231 } else if (p
== s_type
) {
233 case FC_TEXT
: str
= s_text
; break;
234 case FC_PASSWORD
: str
= s_password
; break;
235 case FC_FILE
: str
= s_file
; break;
236 case FC_CHECKBOX
: str
= s_checkbox
; break;
237 case FC_RADIO
: str
= s_radio
; break;
238 case FC_SUBMIT
: str
= s_submit
; break;
239 case FC_IMAGE
: str
= s_image
; break;
240 case FC_RESET
: str
= s_reset
; break;
241 case FC_BUTTON
: str
= s_button
; break;
242 case FC_HIDDEN
: str
= s_hidden
; break;
243 case FC_SELECT
: str
= s_select
; break;
247 SEE_SET_STRING(res
, str
);
249 } else if (p
== s_value
) {
250 str
= string_to_SEE_string(interp
, fs
->value
);
251 SEE_SET_STRING(res
, str
);
252 } else if (p
== s_selectedIndex
) {
253 if (fc
->type
== FC_SELECT
) SEE_SET_NUMBER(res
, fs
->state
);
254 } else if (p
== s_blur
) {
255 SEE_SET_OBJECT(res
, input
->blur
);
256 } else if (p
== s_click
) {
257 SEE_SET_OBJECT(res
, input
->click
);
258 } else if (p
== s_focus
) {
259 SEE_SET_OBJECT(res
, input
->focus
);
260 } else if (p
== s_select
) {
261 SEE_SET_OBJECT(res
, input
->select
);
266 input_put(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
267 struct SEE_string
*p
, struct SEE_value
*val
, int attr
)
269 struct global_object
*g
= (struct global_object
*)interp
;
270 struct view_state
*vs
= g
->win
->vs
;
271 struct document_view
*doc_view
= vs
->doc_view
;
272 struct document
*document
= doc_view
->document
;
273 struct js_input
*input
= (struct js_input
*)o
;
274 struct form_state
*fs
= &vs
->form_info
[input
->form_number
];
275 struct form_control
*fc
= find_form_control(document
, fs
);
277 struct link
*link
= NULL
;
278 unsigned char *string
= NULL
;
281 assert(fc
->form
&& fs
);
283 linknum
= get_form_control_link(document
, fc
);
284 /* Hiddens have no link. */
285 if (linknum
>= 0) link
= &document
->links
[linknum
];
287 if (p
== s_accessKey
) {
288 struct SEE_value conv
;
289 unicode_val_T accesskey
;
291 SEE_ToString(interp
, val
, &conv
);
292 if (conv
.u
.string
->length
)
293 accesskey
= SEE_string_to_unicode(interp
, conv
.u
.string
);
298 link
->accesskey
= accesskey
;
299 } else if (p
== s_alt
) {
300 string
= SEE_value_to_unsigned_char(interp
, val
);
301 mem_free_set(&fc
->alt
, string
);
302 } else if (p
== s_checked
) {
303 if (fc
->type
!= FC_CHECKBOX
&& fc
->type
!= FC_RADIO
)
305 fs
->state
= SEE_ToUint32(interp
, val
);
306 } else if (p
== s_disabled
) {
307 /* FIXME: <input readonly disabled> --pasky */
308 SEE_uint32_t boo
= SEE_ToUint32(interp
, val
);
309 fc
->mode
= (boo
? FORM_MODE_DISABLED
310 : (fc
->mode
== FORM_MODE_READONLY
? FORM_MODE_READONLY
311 : FORM_MODE_NORMAL
));
312 } else if (p
== s_maxLength
) {
313 string
= SEE_value_to_unsigned_char(interp
, val
);
316 fc
->maxlength
= atol(string
);
318 } else if (p
== s_name
) {
319 string
= SEE_value_to_unsigned_char(interp
, val
);
320 mem_free_set(&fc
->name
, string
);
321 } else if (p
== s_readonly
) {
322 SEE_uint32_t boo
= SEE_ToUint32(interp
, val
);
323 fc
->mode
= (boo
? FORM_MODE_READONLY
324 : fc
->mode
== FORM_MODE_DISABLED
? FORM_MODE_DISABLED
326 } else if (p
== s_src
) {
328 string
= SEE_value_to_unsigned_char(interp
, val
);
329 mem_free_set(&link
->where_img
, string
);
331 } else if (p
== s_value
) {
332 if (fc
->type
== FC_FILE
)
334 string
= SEE_value_to_unsigned_char(interp
, val
);
335 mem_free_set(&fs
->value
, string
);
336 if (fc
->type
== FC_TEXT
|| fc
->type
== FC_PASSWORD
)
337 fs
->state
= strlen(fs
->value
);
338 } else if (p
== s_selectedIndex
) {
339 if (fc
->type
== FC_SELECT
) {
340 SEE_uint32_t item
= SEE_ToUint32(interp
, val
);
342 if (item
>=0 && item
< fc
->nvalues
) {
344 mem_free_set(&fs
->value
, stracpy(fc
->values
[item
]));
351 js_input_blur(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
352 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
353 struct SEE_value
*res
)
355 see_check_class(interp
, thisobj
, &js_input_object_class
);
356 SEE_SET_BOOLEAN(res
, 0);
357 /* We are a text-mode browser and there *always* has to be something
358 * selected. So we do nothing for now. (That was easy.) */
362 js_input_click(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
363 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
364 struct SEE_value
*res
)
366 struct global_object
*g
= (struct global_object
*)interp
;
367 struct view_state
*vs
= g
->win
->vs
;
368 struct document_view
*doc_view
= vs
->doc_view
;
369 struct document
*document
= doc_view
->document
;
370 struct session
*ses
= doc_view
->session
;
371 struct js_input
*input
= (
372 see_check_class(interp
, thisobj
, &js_input_object_class
),
373 (struct js_input
*)thisobj
);
374 struct form_state
*fs
= &vs
->form_info
[input
->form_number
];
375 struct form_control
*fc
;
378 SEE_SET_BOOLEAN(res
, 0);
380 fc
= find_form_control(document
, fs
);
383 linknum
= get_form_control_link(document
, fc
);
384 /* Hiddens have no link. */
388 /* Restore old current_link afterwards? */
389 jump_to_link_number(ses
, doc_view
, linknum
);
390 if (enter(ses
, doc_view
, 0) == FRAME_EVENT_REFRESH
)
391 refresh_view(ses
, doc_view
, 0);
393 print_screen_status(ses
);
397 js_input_focus(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
398 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
399 struct SEE_value
*res
)
401 struct global_object
*g
= (struct global_object
*)interp
;
402 struct view_state
*vs
= g
->win
->vs
;
403 struct document_view
*doc_view
= vs
->doc_view
;
404 struct document
*document
= doc_view
->document
;
405 struct session
*ses
= doc_view
->session
;
406 struct js_input
*input
= (
407 see_check_class(interp
, thisobj
, &js_input_object_class
),
408 (struct js_input
*)thisobj
);
409 struct form_state
*fs
= &vs
->form_info
[input
->form_number
];
410 struct form_control
*fc
;
413 SEE_SET_BOOLEAN(res
, 0);
415 fc
= find_form_control(document
, fs
);
418 linknum
= get_form_control_link(document
, fc
);
419 /* Hiddens have no link. */
423 jump_to_link_number(ses
, doc_view
, linknum
);
428 js_input_select(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
429 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
430 struct SEE_value
*res
)
432 see_check_class(interp
, thisobj
, &js_input_object_class
);
433 SEE_SET_BOOLEAN(res
, 0);
434 /* We support no text selecting yet. So we do nothing for now.
435 * (That was easy, too.) */
439 input_canput(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
440 struct SEE_string
*p
)
446 input_hasproperty(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
447 struct SEE_string
*p
)
449 /* all unknown properties return UNDEFINED value */
453 static struct js_input
*
454 js_get_input_object(struct SEE_interpreter
*interp
, struct js_form
*jsform
, int num
)
456 struct js_input
*jsinput
;
460 if (fs
->ecmascript_obj
)
461 return fs
->ecmascript_obj
;
463 /* jsform ('form') is input's parent */
464 /* FIXME: That is NOT correct since the real containing element
465 * should be its parent, but gimme DOM first. --pasky */
466 jsinput
= SEE_NEW(interp
, struct js_input
);
468 jsinput
->object
.objectclass
= &js_input_object_class
;
469 jsinput
->object
.Prototype
= NULL
;
471 jsinput
->blur
= SEE_cfunction_make(interp
, js_input_blur
, s_blur
, 0);
472 jsinput
->click
= SEE_cfunction_make(interp
, js_input_click
, s_click
, 0);
473 jsinput
->focus
= SEE_cfunction_make(interp
, js_input_focus
, s_focus
, 0);
474 jsinput
->select
= SEE_cfunction_make(interp
, js_input_select
, s_select
, 0);
476 jsinput
->form_number
= num
;
477 jsinput
->parent
= jsform
;
481 static struct js_input
*
482 js_get_form_control_object(struct SEE_interpreter
*interp
, struct js_form
*jsform
,
483 enum form_type type
, int num
)
497 return js_get_input_object(interp
, jsform
, num
);
504 INTERNAL("Weird fc->type %d", type
);
513 js_form_elems_item(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
514 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
515 struct SEE_value
*res
)
517 struct global_object
*g
= (struct global_object
*)interp
;
518 struct view_state
*vs
= g
->win
->vs
;
519 struct document_view
*doc_view
= vs
->doc_view
;
520 struct document
*document
= doc_view
->document
;
521 struct js_form_elems
*jsfe
= (
522 see_check_class(interp
, thisobj
, &js_form_elems_class
),
523 (struct js_form_elems
*)thisobj
);
524 struct js_form
*parent_form
= jsfe
->parent
;
525 struct form_view
*fv
= parent_form
->fv
;
526 struct form
*form
= find_form_by_form_view(document
, fv
);
527 struct form_control
*fc
;
528 unsigned char *string
;
532 SEE_SET_UNDEFINED(res
);
535 string
= SEE_value_to_unsigned_char(interp
, argv
[0]);
538 index
= atol(string
);
541 foreach (fc
, form
->items
) {
543 if (counter
== index
) {
544 struct form_state
*fs
= find_form_state(doc_view
, fc
);
547 struct js_input
*fcobj
= js_get_form_control_object(interp
, parent_form
, fc
->type
, fc
->g_ctrl_num
);
550 SEE_SET_OBJECT(res
, (struct SEE_object
*)fcobj
);
559 js_form_elems_namedItem(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
560 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
561 struct SEE_value
*res
)
563 struct global_object
*g
= (struct global_object
*)interp
;
564 struct view_state
*vs
= g
->win
->vs
;
565 struct document_view
*doc_view
= vs
->doc_view
;
566 struct document
*document
= doc_view
->document
;
567 struct js_form_elems
*jsfe
= (
568 see_check_class(interp
, thisobj
, &js_form_elems_class
),
569 (struct js_form_elems
*)thisobj
);
570 struct js_form
*parent_form
= jsfe
->parent
;
571 struct form_view
*fv
= parent_form
->fv
;
572 struct form
*form
= find_form_by_form_view(document
, fv
);
573 struct form_control
*fc
;
574 unsigned char *string
;
576 SEE_SET_UNDEFINED(res
);
579 string
= SEE_value_to_unsigned_char(interp
, argv
[0]);
583 foreach (fc
, form
->items
) {
584 if ((fc
->id
&& !strcasecmp(string
, fc
->id
)) || (fc
->name
&& !strcasecmp(string
, fc
->name
))) {
585 struct form_state
*fs
= find_form_state(doc_view
, fc
);
588 struct js_input
*fcobj
= js_get_form_control_object(interp
, parent_form
, fc
->type
, fc
->g_ctrl_num
);
591 SEE_SET_OBJECT(res
, (struct SEE_object
*)fcobj
);
600 form_elems_get(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
601 struct SEE_string
*p
, struct SEE_value
*res
)
603 struct global_object
*g
= (struct global_object
*)interp
;
604 struct view_state
*vs
= g
->win
->vs
;
605 struct document_view
*doc_view
= vs
->doc_view
;
606 struct document
*document
= doc_view
->document
;
607 struct js_form_elems
*jsfe
= (struct js_form_elems
*)o
;
608 struct js_form
*parent_form
= jsfe
->parent
;
609 struct form_view
*fv
= parent_form
->fv
;
610 struct form
*form
= find_form_by_form_view(document
, fv
);
613 SEE_number_t length
= list_size(&form
->items
);
614 SEE_SET_NUMBER(res
, length
);
615 } else if (p
== s_item
) {
616 SEE_SET_OBJECT(res
, jsfe
->item
);
617 } else if (p
== s_namedItem
) {
618 SEE_SET_OBJECT(res
, jsfe
->namedItem
);
620 unsigned char *string
= SEE_string_to_unsigned_char(p
);
621 struct SEE_value argv
;
622 struct SEE_value
*pargv
= &argv
;
625 SEE_SET_UNDEFINED(res
);
628 SEE_SET_STRING(pargv
, p
);
629 if (string
[0] >= '0' && string
[0] <= '9') {
630 js_form_elems_item(interp
, jsfe
->item
, o
, 1,
633 js_form_elems_namedItem(interp
, jsfe
->namedItem
, o
, 1,
641 form_elems_hasproperty(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
642 struct SEE_string
*p
)
644 /* all unknown properties return UNDEFINED value */
650 js_forms_item(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
651 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
652 struct SEE_value
*res
)
654 struct global_object
*g
= (struct global_object
*)interp
;
655 struct view_state
*vs
= g
->win
->vs
;
656 struct js_forms_object
*fo
= (
657 see_check_class(interp
, thisobj
, &js_forms_object_class
),
658 (struct js_forms_object
*)thisobj
);
659 struct js_document_object
*doc
= fo
->parent
;
660 struct form_view
*fv
;
661 unsigned char *string
;
665 SEE_SET_UNDEFINED(res
);
669 string
= SEE_value_to_unsigned_char(interp
, argv
[0]);
672 index
= atol(string
);
675 foreach (fv
, vs
->forms
) {
677 if (counter
== index
) {
678 struct js_form
*obj
= js_get_form_object(interp
, doc
, fv
);
680 SEE_SET_OBJECT(res
, (struct SEE_object
*)obj
);
687 js_forms_namedItem(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
688 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
689 struct SEE_value
*res
)
691 struct global_object
*g
= (struct global_object
*)interp
;
692 struct view_state
*vs
= g
->win
->vs
;
693 struct document_view
*doc_view
= vs
->doc_view
;
694 struct document
*document
= doc_view
->document
;
695 struct js_forms_object
*fo
= (
696 see_check_class(interp
, thisobj
, &js_forms_object_class
),
697 (struct js_forms_object
*)thisobj
);
698 struct js_document_object
*doc
= fo
->parent
;
700 unsigned char *string
;
702 SEE_SET_UNDEFINED(res
);
706 string
= SEE_value_to_unsigned_char(interp
, argv
[0]);
709 foreach (form
, document
->forms
) {
710 if (form
->name
&& !strcasecmp(string
, form
->name
)) {
711 struct form_view
*fv
= find_form_view(doc_view
, form
);
712 struct js_form
*obj
= js_get_form_object(interp
,
715 SEE_SET_OBJECT(res
, (struct SEE_object
*)obj
);
724 forms_get(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
725 struct SEE_string
*p
, struct SEE_value
*res
)
727 struct global_object
*g
= (struct global_object
*)interp
;
728 struct view_state
*vs
= g
->win
->vs
;
729 struct document_view
*doc_view
= vs
->doc_view
;
730 struct document
*document
= doc_view
->document
;
731 struct js_forms_object
*fo
= (struct js_forms_object
*)o
;
734 SEE_number_t length
= list_size(&document
->forms
);
735 SEE_SET_NUMBER(res
, length
);
736 } else if (p
== s_item
) {
737 SEE_SET_OBJECT(res
, fo
->item
);
738 } else if (p
== s_namedItem
) {
739 SEE_SET_OBJECT(res
, fo
->namedItem
);
741 unsigned char *string
= SEE_string_to_unsigned_char(p
);
742 struct SEE_value argv
;
743 struct SEE_value
*argv1
= &argv
;
746 SEE_SET_UNDEFINED(res
);
749 SEE_SET_STRING(argv1
, p
);
750 if (string
[0] >= '0' && string
[0] <= '9') {
751 js_forms_item(interp
, fo
->item
, o
, 1, &argv1
, res
);
753 js_forms_namedItem(interp
, fo
->namedItem
, o
, 1, &argv1
, res
);
760 forms_hasproperty(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
761 struct SEE_string
*p
)
763 /* all unknown properties return UNDEFINED value */
770 form_get(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
771 struct SEE_string
*p
, struct SEE_value
*res
)
773 struct global_object
*g
= (struct global_object
*)interp
;
774 struct view_state
*vs
= g
->win
->vs
;
775 struct document_view
*doc_view
= vs
->doc_view
;
776 struct js_form
*js_form
= (struct js_form
*)o
;
777 struct form_view
*fv
= js_form
->fv
;
778 struct form
*form
= find_form_by_form_view(doc_view
->document
, fv
);
779 struct SEE_string
*str
;
781 SEE_SET_UNDEFINED(res
);
784 str
= string_to_SEE_string(interp
, form
->action
);
785 SEE_SET_STRING(res
, str
);
786 } else if (p
== s_encoding
) {
787 switch (form
->method
) {
788 case FORM_METHOD_GET
:
789 case FORM_METHOD_POST
:
790 /* "application/x-www-form-urlencoded" */
791 SEE_SET_STRING(res
, s_application_
);
793 case FORM_METHOD_POST_MP
:
794 /* "multipart/form-data" */
795 SEE_SET_STRING(res
, s_multipart_
);
797 case FORM_METHOD_POST_TEXT_PLAIN
:
799 SEE_SET_STRING(res
, s_textplain
);
802 } else if (p
== s_length
) {
803 SEE_number_t num
= list_size(&form
->items
);
804 SEE_SET_NUMBER(res
, num
);
805 } else if (p
== s_method
) {
806 switch (form
->method
) {
807 case FORM_METHOD_GET
:
808 SEE_SET_STRING(res
, s_GET
);
811 case FORM_METHOD_POST
:
812 case FORM_METHOD_POST_MP
:
813 case FORM_METHOD_POST_TEXT_PLAIN
:
814 SEE_SET_STRING(res
, s_POST
);
817 } else if (p
== s_name
) {
818 str
= string_to_SEE_string(interp
, form
->name
);
819 SEE_SET_STRING(res
, str
);
820 } else if (p
== s_target
) {
821 str
= string_to_SEE_string(interp
, form
->target
);
822 SEE_SET_STRING(res
, str
);
823 } else if (p
== s_elements
) {
824 struct js_form_elems
*jsfe
= SEE_NEW(interp
, struct js_form_elems
);
826 jsfe
->object
.objectclass
= &js_form_elems_class
;
827 jsfe
->object
.Prototype
= NULL
;
828 jsfe
->parent
= js_form
;
829 jsfe
->item
= SEE_cfunction_make(interp
, js_form_elems_item
, s_item
, 1);
830 jsfe
->namedItem
= SEE_cfunction_make(interp
, js_form_elems_namedItem
, s_namedItem
, 1);
831 SEE_SET_OBJECT(res
, (struct SEE_object
*)jsfe
);
832 } else if (p
== s_submit
) {
833 SEE_SET_OBJECT(res
, js_form
->submit
);
834 } else if (p
== s_reset
) {
835 SEE_SET_OBJECT(res
, js_form
->reset
);
837 unsigned char *string
= SEE_string_to_unsigned_char(p
);
838 struct form_control
*fc
;
843 foreach(fc
, form
->items
) {
844 struct js_input
*fcobj
= NULL
;
845 struct form_state
*fs
;
847 if ((!fc
->id
|| strcasecmp(string
, fc
->id
)) && (!fc
->name
|| strcasecmp(string
, fc
->name
)))
849 fs
= find_form_state(doc_view
, fc
);
851 fcobj
= js_get_form_control_object(interp
, js_form
, fc
->type
, fc
->g_ctrl_num
);
854 SEE_SET_OBJECT(res
, (struct SEE_object
*)fcobj
);
863 form_put(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
864 struct SEE_string
*p
, struct SEE_value
*val
, int attr
)
866 struct global_object
*g
= (struct global_object
*)interp
;
867 struct view_state
*vs
= g
->win
->vs
;
868 struct document_view
*doc_view
= vs
->doc_view
;
869 struct js_form
*js_form
= (struct js_form
*)o
;
870 struct form_view
*fv
= js_form
->fv
;
871 struct form
*form
= find_form_by_form_view(doc_view
->document
, fv
);
872 unsigned char *string
= SEE_value_to_unsigned_char(interp
, val
);
879 ecmascript_set_action(&form
->action
, string
);
881 mem_free_set(&form
->action
, string
);
883 } else if (p
== s_encoding
) {
884 if (!strcasecmp(string
, "application/x-www-form-urlencoded")) {
885 form
->method
= form
->method
== FORM_METHOD_GET
? FORM_METHOD_GET
887 } else if (!strcasecmp(string
, "multipart/form-data")) {
888 form
->method
= FORM_METHOD_POST_MP
;
889 } else if (!strcasecmp(string
, "text/plain")) {
890 form
->method
= FORM_METHOD_POST_TEXT_PLAIN
;
893 } else if (p
== s_method
) {
894 if (!strcasecmp(string
, "GET")) {
895 form
->method
= FORM_METHOD_GET
;
896 } else if (!strcasecmp(string
, "POST")) {
897 form
->method
= FORM_METHOD_POST
;
900 } else if (p
== s_name
) {
901 mem_free_set(&form
->name
, string
);
902 } else if (p
== s_target
) {
903 mem_free_set(&form
->target
, string
);
908 form_canput(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
909 struct SEE_string
*p
)
915 form_hasproperty(struct SEE_interpreter
*interp
, struct SEE_object
*o
,
916 struct SEE_string
*p
)
922 js_form_reset(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
923 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
924 struct SEE_value
*res
)
926 struct global_object
*g
= (struct global_object
*)interp
;
927 struct view_state
*vs
= g
->win
->vs
;
928 struct document_view
*doc_view
= vs
->doc_view
;
929 struct js_form
*js_form
= (
930 see_check_class(interp
, thisobj
, &js_form_class
),
931 (struct js_form
*)thisobj
);
932 struct form_view
*fv
= js_form
->fv
;
933 struct form
*form
= find_form_by_form_view(doc_view
->document
, fv
);
937 do_reset_form(doc_view
, form
);
938 draw_forms(doc_view
->session
->tab
->term
, doc_view
);
939 SEE_SET_BOOLEAN(res
, 0);
943 js_form_submit(struct SEE_interpreter
*interp
, struct SEE_object
*self
,
944 struct SEE_object
*thisobj
, int argc
, struct SEE_value
**argv
,
945 struct SEE_value
*res
)
947 struct global_object
*g
= (struct global_object
*)interp
;
948 struct view_state
*vs
= g
->win
->vs
;
949 struct document_view
*doc_view
= vs
->doc_view
;
950 struct session
*ses
= doc_view
->session
;
951 struct js_form
*js_form
= (
952 see_check_class(interp
, thisobj
, &js_form_class
),
953 (struct js_form
*)thisobj
);
954 struct form_view
*fv
= js_form
->fv
;
955 struct form
*form
= find_form_by_form_view(doc_view
->document
, fv
);
958 submit_given_form(ses
, doc_view
, form
, 0);
959 SEE_SET_BOOLEAN(res
, 0);
962 struct js_form
*js_get_form_object(struct SEE_interpreter
*interp
,
963 struct js_document_object
*doc
, struct form_view
*fv
)
965 struct js_form
*js_form
;
968 if (fv
->ecmascript_obj
)
969 return fv
->ecmascript_obj
;
971 /* jsdoc ('document') is fv's parent */
972 /* FIXME: That is NOT correct since the real containing element
973 * should be its parent, but gimme DOM first. --pasky */
974 js_form
= SEE_NEW(interp
, struct js_form
);
975 js_form
->object
.objectclass
= &js_form_class
;
976 js_form
->object
.Prototype
= NULL
; /* TODO: use prototype for form */
977 js_form
->parent
= doc
;
978 js_form
->reset
= SEE_cfunction_make(interp
, js_form_reset
, s_reset
, 0);
979 js_form
->submit
= SEE_cfunction_make(interp
, js_form_submit
, s_submit
, 0);
982 fv
->ecmascript_obj
= js_form
;
987 init_js_forms_object(struct ecmascript_interpreter
*interpreter
)
989 struct global_object
*g
= interpreter
->backend_data
;
990 struct SEE_interpreter
*interp
= &g
->interp
;
991 struct SEE_value v
, document
;
992 struct js_forms_object
*forms
= SEE_NEW(interp
,
993 struct js_forms_object
);
995 forms
->object
.objectclass
= &js_forms_object_class
;
996 forms
->object
.Prototype
= NULL
;
998 SEE_OBJECT_GET(interp
, interp
->Global
, s_document
, &document
);
999 SEE_SET_OBJECT(&v
, (struct SEE_object
*)forms
);
1000 SEE_OBJECT_PUT(interp
, document
.u
.object
, s_forms
, &v
, 0);
1002 forms
->item
= SEE_cfunction_make(interp
, js_forms_item
, s_item
, 1);
1003 forms
->namedItem
= SEE_cfunction_make(interp
, js_forms_namedItem
,
1005 forms
->parent
= (struct js_document_object
*)document
.u
.object
;