1 /* jsint.c
2 * (c) 2002 Mikulas Patocka (Vrxni Ideolog), Petr 'Brain' Kulhavy
3 * This file is a part of the Links program, relased under GPL.
4 */
5
6 /*
7 * Ve vsech upcallech plati, ze pokud dostanu ID nejakeho objektu, tak
8 * javascript ma k tomu objektu pristupova prava. Jinymi slovy pristupova prava
9 * se testuji v upcallech jen, aby se neco neproneslo vratnici ven. Dovnitr se
10 * muze donaset vsechno, co si javascript donese, na to ma prava.
11 *
12 * Navic vsechny upcally dostanou pointer na f_data_c, kde bezi javascript,
13 * takze se bude moci testovat, zda javascript nesaha na f_data_c, ke kteremu
14 * nema pristupova prava.
15 *
16 * Brain
17 */
18
19 /* Uctovani pameti:
20 * js_mem_alloc/js_mem_free se bude pouzivat na struktury fax_me_tender
21 * dale se bude pouzivat take ve funkcich pro praci s cookies, protoze string
22 * cookies v javascript_context se tez alokuje pomoci js_mem_alloc/js_mem_free.
23 */
24
25 /*
26 Retezce:
27
28 vsechny retezce v ramci javascriptu jsou predavany v kodovani f_data->cp
29 (tedy tak, jak prisly v dokumentu ze site)
30 */
31
32
33 #include "links.h"
34
35 #ifdef JS
36
37 tcount jsint_execute_seq = 0;
38
39 #include "struct.h"
40 #include "ipret.h"
41 #include "builtin_keys.h"
42
43 /*
44 vypisuje to: jaky kod byl zarazen do fronty. jaky kod byl predan interpretu do js_execute_code. jaky kod byl vykonan a ukoncen intepretem jsint_done_execution
45 #define TRACE_EXECUTE
46 */
47
48 struct js_request {
49 list_entry_1st
50 int onclick_submit; /* >=0 (znamena cislo formulare) pokud tohle je request onclick handleru u submit tlacitka nebo onsubmit handleru */
51 int onsubmit; /* dtto pro submit handler */
52 struct links_event ev; /* event, ktery se ma poslat pri uspechu */
53 int write_pos; /* document.write position from END of document. -1 if document.write cannot be used */
54 int wrote; /* this request called document.write */
55 int len;
56 tcount seq;
57 list_entry_last
58 unsigned char code[1];
59 };
60
61
62 /* set_cookies bude parsovat takhle:
63 * +....=............;...............................+ <- tohle je strinzik
64 * ^ ^
65 * najdu 1. rovnase a za nim 1. strednik, najdu nasledujici rovnase a
66 * nasledujici strednik, pokud to bude platne (&'='<&';') a 2. jmeno bude
67 * "expires", tak to je furt jedna cookie -> poslu Mikulasovi.
68 *
69 * kdyz ne, tak je to jina susenka a poslu to 1. Mikulasovi
70 *
71 * pokud najdu ';' a za nim whitespace, za kterym neni rovnase, tak od toho
72 * stredniku je to garbaz, kterou vratim do strinziku (fd->js->ctx->cookies)
73 */
74
75 /* sets all cookies in fd>js->ctx->cookies */
76 /* final_flush means, that set_cookies was called from jsint_done_execution */
77
78
79
80
81
82
83 /* JESTLI V TYHLE FUNKCI BUDE NEJAKA BUGA, tak za to muze PerM, Clock a pan GNU,
84 * ktery tady kolem rusili, ze jsem se nemohl soustredit. Takze se s
85 * pripadnejma reklamacema obratte na ne!
86 *
87 * Brain
88 */
89
90 /* prototypes */
91 static void jsint_send_event(struct f_data_c *fd, struct links_event *ev);
92 static int jsint_create(struct f_data_c *);
93 static void jsint_done_execution(void *);
94 static int jsint_can_access(struct f_data_c *, struct f_data_c *);
95 static struct f_data_c *jsint_find_recursive(struct f_data_c *, long); /* line 89 */
96 static void *jsint_find_object(struct f_data_c *, long);
97 static long *add_id(long *, int *, long );
98 static long *add_fd_id(long *, int *, long, long, unsigned char *);
99 static void add_all_recursive_in_fd(long **, int *, struct f_data_c *, struct f_data_c *);
100
101
jsint_set_cookies(struct f_data_c * fd,int final_flush)102 void jsint_set_cookies(struct f_data_c *fd, int final_flush)
103 {
104 unsigned char *str;
105 unsigned char *next;
106 unsigned char *eq1, *semic1, *eq2, *semic2;
107
108 if(!(fd->js)||!(fd->js->ctx))internal_error("jsint_set_cookies called with NULL context.\n");
109 if (!(fd->js->ctx->cookies)||!(fd->rq))return; /* cookies string is empty, nothing to set */
110 str=fd->js->ctx->cookies;
111
112 a_znova:
113 eq1=strchr(str,'=');
114 semic1=strchr(str,';');
115
116 if (!*str||(!final_flush&&!semic1)) /* na konci neni strednik a skript jeste bezi, takze to musime vratit do stringu a vypadnout */
117 {
118 unsigned char *bla=NULL;
119 if (*str)bla=stracpy1(str);
120 js_mem_free(fd->js->ctx->cookies);
121 fd->js->ctx->cookies=bla;
122 return;
123 }
124
125 /* ted se v str bud vyskytuje strednik, nebo skript uz skoncil */
126
127 if (semic1&&eq1>semic1) /* '=' je za ';' takze to pred strednikem a strednik skipnem */
128 {
129 str=semic1+1;
130 goto a_znova;
131 }
132
133 next=semic1?semic1+1:str+strlen(cast_const_char str);
134 if (!eq1) /* neni tam '=', takze to preskocime */
135 {
136 str=next;
137 goto a_znova;
138 }
139
140 /* ted by to mela bejt regulerni susenka */
141
142 next_par:
143 eq2=NULL,semic2=NULL;
144 if (semic1!=NULL)
145 {
146 eq2=strchr(semic1+1,'=');
147 semic2=strchr(semic1+1,';');
148 }
149
150 if (eq2&&semic1&&(final_flush||semic2))
151 {
152 unsigned char *p=strstr(semic1+1,"expires");
153 if (!p)p=strstr(semic1+1,"Expires");
154 if (!p)p=strstr(semic1+1,"EXPIRES");
155 if (!p)p=strstr(semic1+1,"domain");
156 if (!p)p=strstr(semic1+1,"Domain");
157 if (!p)p=strstr(semic1+1,"DOMAIN");
158 if (!p)p=strstr(semic1+1,"path");
159 if (!p)p=strstr(semic1+1,"Path");
160 if (!p)p=strstr(semic1+1,"PATH");
161 if (!p)p=strstr(semic1+1,"comment");
162 if (!p)p=strstr(semic1+1,"Comment");
163 if (!p)p=strstr(semic1+1,"COMMENT");
164 if (!p)p=strstr(semic1+1,"max-age");
165 if (!p)p=strstr(semic1+1,"Max-age");
166 if (!p)p=strstr(semic1+1,"Max-Age");
167 if (!p)p=strstr(semic1+1,"MAX-AGE");
168 if (!p)p=strstr(semic1+1,"version");
169 if (!p)p=strstr(semic1+1,"Version");
170 if (!p)p=strstr(semic1+1,"VERSION");
171 if (p&&p>semic1&&p<eq2) /* za 1. prirazenim nasleduje "expires=", takze to je porad jedna susenka */
172 {
173 next=semic2?semic2+1:str+strlen(cast_const_char str);
174 semic1=semic2;
175 goto next_par;
176 }
177 }
178
179 if (*next)next[-1]=0;
180
181 for (;*str&&WHITECHAR(*str);str++); /* skip whitechars */
182
183 /*debug("set_cookie: \"%s\"", str);*/
184 set_cookie(fd->rq->url, str);
185
186 str=next;
187 goto a_znova;
188 }
189
190
jsint_object_type(long to_je_on_Padre)191 int jsint_object_type(long to_je_on_Padre)
192 {
193 return to_je_on_Padre&JS_OBJ_MASK;
194 }
195
196
jsint_create(struct f_data_c * fd)197 static int jsint_create(struct f_data_c *fd)
198 {
199 struct js_state *js;
200
201 if (fd->js) internal_error("javascript state present");
202 js = mem_calloc(sizeof(struct js_state));
203 if (!(js->ctx = js_create_context(fd, ((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT))) {
204 mem_free(js);
205 return 1;
206 }
207 init_list(js->queue);
208 fd->js = js;
209 return 0;
210 }
211
jsint_destroy(struct f_data_c * fd)212 void jsint_destroy(struct f_data_c *fd)
213 {
214 struct js_state *js = fd->js;
215 fd->script_t = 0;
216 if (!js) return;
217 fd->js = NULL;
218 pr(js_destroy_context(js->ctx)) return;
219 if (js->src) mem_free(js->src);
220 if (js->active) mem_free(js->active);
221 js_zaflaknuto_pameti -= js->newdata;
222 free_list(struct js_request, js->queue);
223 mem_free(js);
224 }
225
226 /* for <a href="javascript:..."> */
javascript_func(struct session * ses,unsigned char * hlavne_ze_je_vecirek)227 void javascript_func(struct session *ses, unsigned char *hlavne_ze_je_vecirek)
228 {
229 unsigned char *code=get_url_data(hlavne_ze_je_vecirek);
230
231 jsint_execute_code(current_frame(ses),code,strlen(cast_const_char code),-1,-1,-1, NULL);
232 }
233
jsint_send_event(struct f_data_c * fd,struct links_event * ev)234 static void jsint_send_event(struct f_data_c *fd, struct links_event *ev)
235 {
236 if (!ev || !ev->b) return;
237 send_event(fd->ses, ev);
238 }
239
240 /* executes or queues javascript code in frame:
241 write_pos is number of bytes from the position where document.write should write to the end of document
242 write_pos == -1 if it is not from <SCRIPT> statement and cannot use document.write
243 */
244 /* data je cislo formulare pro onclick submit handler, jinak se nepouziva */
245 /* ev je udalost, ktera se ma znovu poslat, pokud bylo vraceno true */
jsint_execute_code(struct f_data_c * fd,unsigned char * code,int len,int write_pos,int onclick_submit,int onsubmit,struct links_event * ev)246 void jsint_execute_code(struct f_data_c *fd, unsigned char *code, int len, int write_pos, int onclick_submit, int onsubmit, struct links_event *ev)
247 {
248 struct js_request *r, *q;
249 struct list_head *lq;
250
251 for (;code&&len&&*code&&((*code)==' '||(*code)==9||(*code)==13||(*code)==10);code++,len--);
252
253 /*
254 FUJ !!!!
255 if (!casecmp(code, cast_uchar "javascript:",strlen(cast_const_char "javascript:")))code+=strlen(cast_const_char "javascript:");
256 */
257
258 if (len >= 11 && !casecmp(code, "javascript:", 11)) code += 11, len -= 11;
259
260 if (!js_enable) {
261 jsint_send_event(fd, ev);
262 return;
263 }
264
265 #ifdef TRACE_EXECUTE
266 fprintf(stderr, "Submitted: ^^%.*s^^\n", len, code);
267 #endif
268
269 if (!fd->js && jsint_create(fd)) {
270 jsint_send_event(fd, ev);
271 return;
272 }
273 if ((unsigned)len > MAXINT - sizeof(struct js_request)) overalloc();
274 r = mem_calloc(sizeof(struct js_request) + len);
275 r->seq = jsint_execute_seq++;
276 r->write_pos = write_pos;
277 r->len = len;
278 r->onclick_submit = onclick_submit;
279 r->onsubmit = onsubmit;
280 memcpy(r->code, code, len);
281 if (ev) memcpy(&r->ev, ev, sizeof(struct links_event));
282 if (write_pos == -1) {
283 add_to_list_end(fd->js->queue, r);
284 } else {
285 /* add it beyond all <SCRIPT> requests but before non-<SCRIPT> ones */
286 foreach(struct js_request, q, lq, fd->js->queue) if (q->write_pos == -1) break;
287 add_before_list_entry(lq, &r->list_entry);
288 }
289 jsint_run_queue(fd);
290 }
291
jsint_done_execution(void * fd_)292 static void jsint_done_execution(void *fd_)
293 {
294 struct f_data_c *fd = (struct f_data_c *)fd_;
295 struct js_request *r, *to_exec;
296 struct list_head *lr;
297 struct js_state *js = fd->js;
298 struct links_event ev = { 0, 0, 0, 0 };
299 if (!js) {
300 internal_error("no js in frame");
301 return;
302 }
303 if (!js->active) {
304 internal_error("jsint_done_execution: completion function called on inactive js");
305 return;
306 }
307
308 #ifdef TRACE_EXECUTE
309 fprintf(stderr, "Done: ^^%.*s^^\n", js->active->len, js->active->code);
310 #endif
311
312 /* accept all cookies set by the script */
313 jsint_set_cookies(fd,1);
314
315 /* js->active obsahuje request prave dobehnuteho skriptu */
316
317 /* dobehl onclick_handler a nezaplatil (vratil false), budou se dit veci */
318 if (js->active->ev.b && js->ctx->zaplatim)
319 memcpy(&ev, &js->active->ev, sizeof(struct links_event));
320 if (js->active->onclick_submit >=0 && !js->ctx->zaplatim)
321 {
322 /* pokud je handler od stejneho formulare, jako je defered, tak odlozeny skok znicime a zlikvidujem prislusny onsubmit handler z fronty */
323 if (js->active->onclick_submit == fd->ses->defered_data)
324 {
325 foreach(struct js_request, r, lr,js->queue)
326 /* to je onsubmit od naseho formulare, tak ho smazem */
327 if (r->onsubmit == js->active->onclick_submit)
328 {
329 del_from_list(r);
330 mem_free(r);
331 break; /* zadny dalsi onsubmit tohoto formulare uz nebude */
332 }
333 ses_destroy_defered_jump(fd->ses);
334 }
335 }
336
337 if (js->active->write_pos == -1) mem_free(js->active), js->active = NULL;
338 else {
339 r = js->active; js->active = NULL;
340 if (r->wrote) js->wrote = 1;
341 jsint_scan_script_tags(fd);
342 if (!f_is_finished(fd->f_data)) {
343 fd->done = 0;
344 fd->parsed_done = 0;
345 }
346 if (js->wrote && fd->script_t == -1) {
347 fd->done = 0;
348 fd->parsed_done = 0;
349 fd_loaded(NULL, fd);
350 js->wrote = 0;
351 }
352 mem_free(r);
353 }
354
355 to_exec = js->active;
356 if (!to_exec && !list_empty(fd->js->queue)) to_exec = list_struct(fd->js->queue.next, struct js_request);
357 if (fd->ses->defered_url && (!to_exec || (to_exec->seq > fd->ses->defered_seq && to_exec->write_pos == -1)))
358 {
359 unsigned char *url, *target;
360
361 url=stracpy(fd->ses->defered_url);
362 target=stracpy(fd->ses->defered_url);
363
364 goto_url_f(fd->ses,NULL,url,target,fd->ses->defered_target_base,fd->ses->defered_data,0,0,0);
365 mem_free(url);
366 mem_free(target);
367 }
368 else
369 jsint_run_queue(fd);
370 jsint_send_event(fd, &ev);
371 }
372
jsint_run_queue(struct f_data_c * fd)373 void jsint_run_queue(struct f_data_c *fd)
374 {
375 struct js_request *r;
376 struct js_state *js = fd->js;
377
378 if ((!fd->done && fd->f_data) || !js || js->active || list_empty(js->queue)) return;
379
380 r = list_struct(js->queue.next, struct js_request);
381 del_from_list(r);
382 js->active = r;
383 #ifdef TRACE_EXECUTE
384 fprintf(stderr, "Executing: ^^%.*s^^\n", r->len, r->code);
385
386 #endif
387 pr(js_execute_code(js->ctx, r->code, r->len, jsint_done_execution)) {};
388 }
389
390 /* returns: 1 - source is modified by document.write
391 0 - original source
392 */
393
jsint_get_source(struct f_data_c * fd,unsigned char ** start,size_t * len)394 int jsint_get_source(struct f_data_c *fd, unsigned char **start, size_t *len)
395 {
396 struct js_state *js = fd->js;
397
398 if (!js || !js->src) return 0;
399 if (start) *start = js->src;
400 if (len) *len = (size_t)js->srclen;
401 return 1;
402 }
403
404 /*
405 * tests if script running in frame "running" can access document in frame "accessed"
406 * 0=no permission, 1=permission OK
407 */
jsint_can_access(struct f_data_c * running,struct f_data_c * accessed)408 static int jsint_can_access(struct f_data_c *running, struct f_data_c *accessed)
409 {
410 int a;
411 unsigned char *h1, *h2;
412 if (!running || !accessed || !running->rq || !accessed->rq) return 0;
413
414 h1 = get_host_name(running->rq->url);
415 h2 = get_host_name(accessed->rq->url);
416 a = !casestrcmp(h1, h2);
417 mem_free(h1);
418 mem_free(h2);
419 return a;
420 }
421
422
423 /* doc_id is real document id, whithout any type */
424 /* fd must be a valid pointer */
jsint_find_recursive(struct f_data_c * fd,long doc_id)425 static struct f_data_c *jsint_find_recursive(struct f_data_c *fd, long doc_id)
426 {
427 struct f_data_c *sub, *fdd;
428 struct list_head *lsub;
429 if (fd->id == doc_id) return fd;
430 foreach(struct f_data_c, sub, lsub, fd->subframes) {
431 if ((fdd = jsint_find_recursive(sub, doc_id))) return fdd;
432 }
433 return NULL;
434 }
435
436 /*
437 * This function finds document that has given ID
438 */
jsint_find_document(long doc_id)439 struct f_data_c *jsint_find_document(long doc_id)
440 {
441 struct f_data_c *fd;
442 struct session *ses;
443 struct list_head *lses;
444 int type=jsint_object_type(doc_id);
445
446 if (type!=JS_OBJ_T_DOCUMENT&&type!=JS_OBJ_T_FRAME)
447 {unsigned char txt[256]; snprintf(txt,256,"jsint_find_document called with type=%d\n",type);internal_error(txt);}
448 doc_id>>=JS_OBJ_MASK_SIZE;
449 foreach(struct session, ses, lses, sessions) if ((fd = jsint_find_recursive(ses->screen, doc_id))) return fd;
450 return NULL;
451 }
452
453 /* Document has just loaded. Scan for <SCRIPT> tags and execute each of them */
454
jsint_scan_script_tags(struct f_data_c * fd)455 void jsint_scan_script_tags(struct f_data_c *fd)
456 {
457 unsigned char *name, *attr;
458 int namelen;
459 unsigned char *val, *e, *ee;
460 unsigned char *s, *ss, *eof;
461 size_t len;
462 unsigned char *start, *end;
463 unsigned char *onload_code = NULL;
464 int uv;
465 int bs;
466
467 if (!js_enable) return;
468 if (!fd->rq || !fd->rq->ce || !fd->f_data) return;
469 if (!jsint_get_source(fd, &ss, &len)) {
470 if (get_file(fd->rq, &ss, &len)) return;
471 }
472 if (len > MAXINT) len = MAXINT;
473 eof = ss + len;
474
475 d_opt = &fd->f_data->opt;
476
477 s = ss;
478 se:
479 while (s < eof && *s != '<') sp:s++;
480 if (s >= eof || fd->script_t < 0)
481 {
482 if (onload_code && fd->script_t != -1)
483 {
484 jsint_execute_code(fd,onload_code,strlen(cast_const_char onload_code),-1,-1,-1, NULL);
485 }
486 fd->script_t = -1;
487 goto ret;
488 }
489 if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) {
490 s = skip_comment(s, eof);
491 goto se;
492 }
493 if (parse_element(s, eof, &name, &namelen, &attr, &s)) goto sp;
494 if (!onload_code&&namelen==4&&!casecmp(name,"BODY",4))
495 {
496 onload_code=get_attr_val(attr,"onload"); /* if the element doesn't have onload attribute get_attr_val returns NULL */
497 goto se;
498 }
499
500 if (!onload_code&&namelen==3&&!casecmp(name,"IMG",3))
501 {
502 onload_code=get_attr_val(attr,"onload"); /* if the element doesn't have onload attribute get_attr_val returns NULL */
503 goto se;
504 }
505
506 if (namelen != 6 || casecmp(name, "SCRIPT", 6) || s - ss < fd->script_t) goto se;
507 start = end = NULL;
508 if ((val = get_attr_val(attr, "src"))) {
509 unsigned char *url;
510 if (fd->f_data->script_href_base && ((url = join_urls(fd->f_data->script_href_base, val)))) {
511 size_t len;
512 int code, version;
513 struct additional_file *af = request_additional_file(fd->f_data, url);
514 mem_free(url);
515 mem_free(val);
516 if (!af || !af->rq) goto se;
517 if (af->rq->state >= 0) goto ret;
518 if (!af->rq->ce) goto se;
519 if (!get_http_code(af->rq->ce->head, &code, &version)) {
520 if (code < 200 || code >= 300) goto se;
521 }
522 if (get_file(af->rq, &start, &len)) goto se;
523 if (!len) goto se;
524 if (len > MAXINT) len = MAXINT;
525 end = start + len;
526 } else {
527 mem_free(val);
528 goto se;
529 }
530 }
531 e = s;
532 uv = 0;
533 bs = 0;
534 while (e < eof && *e != '<') {
535 es:
536 if (!uv && (*e == '"' || *e == '\'')) uv = *e, bs = 0;
537 else if (*e == '\\' && uv) bs = 1;
538 else if (*e == uv && !bs) uv = 0;
539 else bs = 0;
540 e++;
541 }
542 if (eof - e >= 8) {
543 if (/*uv ||*/ casecmp(e, "</SCRIPT", 8)) goto es;
544 } else e = eof;
545 ee = e;
546 while (ee < eof && *ee != '>') ee++;
547 if (ee < eof) ee++;
548 fd->script_t = ee - ss;
549 if (!start || !end) jsint_execute_code(fd, s, e - s, eof - ee,-1,-1, NULL);
550 else jsint_execute_code(fd, start, end - start, eof - ee,-1,-1, NULL);
551 ret:
552 if (onload_code)mem_free(onload_code);
553
554 d_opt = &dd_opt;
555 }
556
557
558 struct hopla_mladej
559 {
560 struct form_control *fc;
561 struct form_state *fs;
562 };
563
564
565 /* Returns pointer to the object with given ID in the document, or NULL when
566 * there's no such object. Document must be a valid pointer.
567 *
568 * Pointer type depends on type of object, caller must know the type and
569 * interpret the pointer in the right way.
570 */
571
jsint_find_object(struct f_data_c * document,long obj_id)572 static void *jsint_find_object(struct f_data_c *document, long obj_id)
573 {
574 int type=obj_id&JS_OBJ_MASK;
575 int orig_obj_id=obj_id;
576 obj_id>>=JS_OBJ_MASK_SIZE;
577
578 switch (type)
579 {
580 /* form element
581 * obj_id can be from 0 up to number of form fields
582 * (document->vs->form_info_len may be actually lower if the fields were never
583 * touched)
584 * returns allocated struct hopla_mladej, you must free it after use
585 */
586 case JS_OBJ_T_TEXT:
587 case JS_OBJ_T_PASSWORD:
588 case JS_OBJ_T_TEXTAREA:
589 case JS_OBJ_T_CHECKBOX:
590 case JS_OBJ_T_RADIO:
591 case JS_OBJ_T_SELECT:
592 case JS_OBJ_T_SUBMIT:
593 case JS_OBJ_T_RESET:
594 case JS_OBJ_T_HIDDEN:
595 case JS_OBJ_T_BUTTON:
596 {
597 struct hopla_mladej *hopla;
598
599 struct form_control *fc;
600 struct list_head *lfc;
601 int a=0;
602
603 if (obj_id<0/*||obj_id>=n*/)return NULL;
604 hopla=mem_alloc(sizeof(struct hopla_mladej));
605
606 if (!(document->f_data)){mem_free(hopla);return NULL;};
607
608 foreachback(struct form_control, fc, lfc, document->f_data->forms)
609 if (fc->g_ctrl_num==obj_id){a=1;break;}
610 if (!a){mem_free(hopla);return NULL;}
611
612 hopla->fs=find_form_state(document, fc);
613 hopla->fc=fc;
614 return hopla;
615 }
616
617 /* link
618 * obj_id can be from 0 to (nlinks-1)
619 */
620 case JS_OBJ_T_LINK:
621 {
622 struct link*l;
623 int n;
624
625 if (!(document->f_data))return NULL;
626
627 l=document->f_data->links;
628 n=document->f_data->nlinks;
629
630 if (obj_id<0||obj_id>=n)return NULL;
631 return l+obj_id;
632 }
633
634 /* form
635 * obj_id is form_num in struct form_control (f_data->forms)
636 */
637 case JS_OBJ_T_FORM:
638 {
639 struct form_control *f;
640 struct list_head *lf;
641
642 if (!(document->f_data))return NULL;
643 foreachback(struct form_control, f, lf, document->f_data->forms) if ((f->form_num)==obj_id)return f;
644 return NULL;
645 }
646
647 /* anchors
648 * obj_id is position in list of all tags
649 */
650 case JS_OBJ_T_ANCHOR:
651 {
652 struct tag *t;
653 struct list_head *lt;
654 int a=0;
655
656 if (!(document->f_data))return NULL;
657 foreach(struct tag, t, lt, document->f_data->tags)
658 {
659 if (obj_id==a)return t;
660 a++;
661 }
662 return NULL;
663 }
664 break;
665
666 /* this is document
667 * call jsint_find_document
668 * returned value is struct f_data_c
669 */
670 case JS_OBJ_T_FRAME:
671 case JS_OBJ_T_DOCUMENT:
672 return jsint_find_document(orig_obj_id);
673
674 /* image
675 * returned value is struct g_object_image *
676 */
677 case JS_OBJ_T_IMAGE:
678 #ifdef G
679 if (F) {
680 struct g_object_image *gi;
681 struct list_head *lgi;
682
683 if (!document->f_data) return NULL;
684 foreach(struct g_object_image, gi, lgi, document->f_data->images) {
685 if (gi->id == obj_id) return gi;
686 }
687 return NULL;
688 }else
689 #endif
690 return NULL;
691
692 default:
693 internal_error("jsint_find_object: unknown type %d.",type);
694 return NULL; /* never called, but GCC likes it ;-) */
695 }
696 }
697
698
add_id(long * field,int * len,long id)699 static long *add_id(long *field,int *len,long id)
700 {
701 long *p;
702 int a;
703 for (a=0;a<(*len);a++) /* this object is already on the list */
704 if (field[a]==id)return field;
705
706 (*len)++;
707 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
708 p=mem_realloc(field,(*len)*sizeof(long));
709
710 p[(*len)-1]=id;
711 return p;
712 }
713
add_fd_id(long * field,int * len,long fd,long id,unsigned char * name)714 long *add_fd_id(long *field,int *len,long fd,long id, unsigned char *name)
715 {
716 long *p;
717 int a;
718 for (a=0;a<(*len);a+=3) /* this object is already on the list */
719 if (field[a]==fd&&field[a+1]==id)return field;
720
721
722 (*len)+=3;
723 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
724 p=mem_realloc(field,(*len)*sizeof(long));
725
726 p[(*len)-3]=fd;
727 p[(*len)-2]=id;
728 p[(*len)-1]=(name&&(*name))?(long)stracpy(name):(long)NULL;
729 return p;
730 }
731
732 static long js_upcall_get_frame_id(void *data);
733
734 /* finds all objects with name takhle_tomu_u_nas_nadavame
735 * in fd and all it's subframes with rq==NULL
736 * js_ctx is f_data_c of the accessing script
737 */
find_in_subframes(struct f_data_c * js_ctx,struct f_data_c * fd,long * pole_vole,int * n_items,unsigned char * takhle_tomu_u_nas_nadavame)738 static long *find_in_subframes(struct f_data_c *js_ctx, struct f_data_c *fd, long *pole_vole, int *n_items, unsigned char *takhle_tomu_u_nas_nadavame)
739 {
740 struct f_data_c *ff;
741 struct list_head *lff;
742 struct form_control *f;
743 struct list_head *lf;
744
745 /* search frame */
746 foreach(struct f_data_c, ff, lff, fd->subframes)
747 if (ff->loc&&ff->loc->name&&!strcmp(cast_const_char ff->loc->name,cast_const_char takhle_tomu_u_nas_nadavame)&&jsint_can_access(js_ctx,ff)) /* to je on! */
748 if (!(pole_vole=add_id(pole_vole,n_items,js_upcall_get_frame_id(ff))))return NULL;
749
750 if (!(fd->f_data))goto a_je_po_ptakach;
751
752 #ifdef G
753 if (F) {
754 struct g_object_image *gi;
755 struct list_head *lgi;
756 /* search images */
757 foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
758 if (gi->name&&!strcmp(cast_const_char gi->name, cast_const_char takhle_tomu_u_nas_nadavame))
759 if (!(pole_vole=add_id(pole_vole,n_items,JS_OBJ_T_IMAGE+((gi->id)<<JS_OBJ_MASK_SIZE))))return NULL;
760 }
761 }
762 #endif
763 /* search forms */
764 foreachback(struct form_control, f, lf, fd->f_data->forms)
765 if (f->form_name&&!strcmp(cast_const_char f->form_name,cast_const_char takhle_tomu_u_nas_nadavame)) /* tak tohle JE Jim Beam */
766 if (!(pole_vole=add_id(pole_vole,n_items,((f->form_num)<<JS_OBJ_MASK_SIZE)+JS_OBJ_T_FORM)))return NULL;
767
768 /* search form elements */
769 foreachback(struct form_control, f, lf, fd->f_data->forms)
770 if (f->name&&!strcmp(cast_const_char f->name,cast_const_char takhle_tomu_u_nas_nadavame)) /* tak tohle JE Jim Beam */
771 {
772 long tak_mu_to_ukaz=0;
773 tak_mu_to_ukaz=(f->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
774 switch (f->type)
775 {
776 case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
777 case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
778 case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
779 case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
780 case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
781 case FC_IMAGE:
782 case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
783 case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
784 case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
785 case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
786 case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
787 default: /* internal_error("Invalid form element type.\n"); */
788 tak_mu_to_ukaz=0;break;
789 }
790 if (tak_mu_to_ukaz&&!(pole_vole=add_id(pole_vole,n_items,tak_mu_to_ukaz)))return NULL;
791 }
792
793 a_je_po_ptakach:
794 /* find in all rq==NULL */
795 foreach(struct f_data_c, ff, lff, fd->subframes)
796 if (!(ff->rq)) pole_vole=find_in_subframes(js_ctx,ff,pole_vole,n_items,takhle_tomu_u_nas_nadavame);
797
798
799 return pole_vole;
800 }
801
802 /* resolves name of an object, returns field of all ID's with the name
803 * obj_id is object in which we're searching
804 * takhle_tomu_u_nas_nadavame is the searched name
805 * context is identifier of the javascript context
806 * n_items is number of returned items
807 *
808 * on error returns NULL
809 */
jsint_resolve(void * context,long obj_id,char * takhle_tomu_u_nas_nadavame,int * n_items)810 long *jsint_resolve(void *context, long obj_id, char *takhle_tomu_u_nas_nadavame,int *n_items)
811 {
812 struct f_data_c *fd;
813 struct f_data_c *js_ctx=(struct f_data_c*)context;
814 long *pole_vole;
815 *n_items=0;
816
817 if (!takhle_tomu_u_nas_nadavame||!(*takhle_tomu_u_nas_nadavame))return NULL;
818 pole_vole=mem_alloc(sizeof(long));
819 switch(jsint_object_type(obj_id))
820 {
821 /* searched object can be a frame, image, form or a form element */
822 case JS_OBJ_T_DOCUMENT:
823 case JS_OBJ_T_FRAME:
824 fd=jsint_find_document(obj_id);
825 if (!fd||!(jsint_can_access(js_ctx,fd)))break;
826
827 pole_vole=find_in_subframes(js_ctx, fd, pole_vole, n_items, takhle_tomu_u_nas_nadavame);
828 break;
829
830 /* searched name can be a form element */
831 case JS_OBJ_T_FORM:
832 {
833 struct form_control *fc=jsint_find_object(js_ctx,obj_id);
834 struct form_control *f;
835 struct list_head *lf;
836 if (!fc){mem_free(pole_vole);return NULL;}
837
838 if (!(js_ctx->f_data)){mem_free(pole_vole);return NULL;}
839 foreachback(struct form_control, f, lf, js_ctx->f_data->forms)
840 {
841 if (f->form_num==fc->form_num) /* this form */
842 if (f->name&&!strcmp(cast_const_char f->name,cast_const_char takhle_tomu_u_nas_nadavame)) /* this IS Jim Beam */
843 {
844 long tak_mu_to_ukaz=0;
845 tak_mu_to_ukaz=(f->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
846 switch (f->type)
847 {
848 case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
849 case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
850 case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
851 case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
852 case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
853 case FC_IMAGE:
854 case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
855 case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
856 case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
857 case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
858 case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
859 default: tak_mu_to_ukaz=0;break;
860 /* internal_error("Invalid form element type.\n"); */
861 }
862 if ((tak_mu_to_ukaz&JS_OBJ_MASK)&&!(pole_vole=add_id(pole_vole,n_items,tak_mu_to_ukaz)))return NULL;
863 }
864 }
865 }
866 break;
867 }
868 if (!pole_vole)return NULL;
869 if (!(*n_items)){mem_free(pole_vole);pole_vole=NULL;}
870 return pole_vole;
871 }
872
873 /*------------------------>>>>>>>> UPCALLS <<<<<<<<-------------------------*/
874
875
876 /* tyhle upcally se volaji ze select smycky:
877
878 void js_upcall_confirm(void *data)
879 void js_upcall_alert(void * data)
880 void js_upcall_close_window(void *data)
881 void js_upcall_get_string(void *data)
882 void js_upcall_goto_url(void * data)
883 void js_upcall_goto_history(void * data)
884 void js_upcall_set_image_src(void* data)
885
886 V nich se musi volat js_spec_vykill_timer, aby se znicil timer, ktery upcall
887 zavolal.
888
889 Tyto upcally MUZOU dostavat f_data_c pointer primo, protoze kdyz ten f_data_c
890 umre a s nim i ten JS, tak se timery znicej --- tudiz se nic nestane.
891 */
892
893
redraw_document(struct f_data_c * f)894 static void redraw_document(struct f_data_c *f)
895 {
896 /*
897 if (F) {
898 f->xl = -1;
899 f->yl = -1;
900 draw_to_window(f->ses->win, draw_doc, f);
901 }
902 */
903 draw_fd(f);
904 }
905
906
907 /* returns ID of a document with the javascript */
js_upcall_get_document_id(void * data)908 long js_upcall_get_document_id(void *data)
909 {
910 struct f_data_c *fd;
911 if (!data)internal_error("js_upcall_get_document_id called with NULL pointer!");
912
913 fd=(struct f_data_c*)data;
914 return (((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT);
915 }
916
917
918 /* same as get_document_id, but returned type is FRAME */
js_upcall_get_frame_id(void * data)919 static long js_upcall_get_frame_id(void *data)
920 {
921 struct f_data_c *fd;
922 if (!data)internal_error("js_upcall_get_document_id called with NULL pointer!");
923
924 fd=(struct f_data_c*)data;
925 return (((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_FRAME);
926 }
927
928
929 /* writes "len" bytes starting at "str" to document */
js_upcall_document_write(void * p,unsigned char * str,int len)930 void js_upcall_document_write(void *p, unsigned char *str, int len)
931 {
932 int pos;
933 unsigned char *s;
934 struct f_data_c *fd = p;
935 struct js_state *js = fd->js;
936 if (!js)return;
937 if (!js->active) internal_error("js_upcall_document_write: no request active");
938 if (js->active->write_pos == -1) return;
939 if (js->active->write_pos < 0) internal_error("js_upcall_document_write: js->active trashed");
940 if (!js->src) {
941 size_t len;
942 unsigned char *s;
943 if (get_file(fd->rq, &s, &len)) return;
944 if (len > MAXINT) return;
945 js->src = memacpy(s, len);
946 js->srclen = len;
947 }
948 if ((unsigned)js->srclen + (unsigned)len > MAXINT) overalloc();
949 if ((unsigned)js->srclen + (unsigned)len < (unsigned)len) overalloc();
950 s = mem_realloc(js->src, js->srclen + len);
951 js->src = s;
952 if ((pos = js->srclen - js->active->write_pos) < 0) pos = 0;
953 memmove(s + pos + len, s + pos, js->srclen - pos);
954 memcpy(s + pos, str, len);
955 js->srclen += len;
956 js->newdata += len;
957 js_zaflaknuto_pameti += len;
958 js->active->wrote = 1;
959 }
960
961
962 /* returns title of actual document (=document in the script context) */
963 /* when an error occurs, returns NULL */
964 /* returned string should be deallocated after use */
js_upcall_get_title(void * data)965 unsigned char *js_upcall_get_title(void *data)
966 {
967 struct f_data_c *fd;
968 unsigned char *title, *t;
969
970 if (!data)internal_error("js_upcall_get_title called with NULL pointer!");
971 fd=(struct f_data_c *)data;
972
973 title=mem_alloc(MAX_STR_LEN);
974
975 if (!(get_current_title(fd,title,MAX_STR_LEN))){mem_free(title);return NULL;}
976 if (fd->f_data)
977 {
978 t = convert(fd->f_data->opt.cp, fd->f_data->cp, title, NULL);
979 mem_free(title);
980 title=t;
981 }
982 return title;
983 }
984
985
986 /* sets title of actual document (=document in the script context) */
987 /* string title will be deallocated after use */
js_upcall_set_title(void * data,unsigned char * title)988 void js_upcall_set_title(void *data, unsigned char *title)
989 {
990 unsigned char *t;
991 struct f_data_c *fd;
992 int l=0;
993
994 if (!data)internal_error("js_upcall_get_title called with NULL pointer!");
995 fd=(struct f_data_c *)data;
996
997 if (!title)return;
998
999 if (!(fd->f_data)){mem_free(title);return;}
1000 if (fd->f_data->title)mem_free(fd->f_data->title);
1001 fd->f_data->title=init_str();
1002 fd->f_data->uncacheable=1;
1003 t = convert(fd->f_data->cp, fd->f_data->opt.cp, title, NULL);
1004 add_to_str(&(fd->f_data->title),&l,t);
1005 mem_free(t);
1006
1007 mem_free(title);
1008 redraw_document(fd);
1009 }
1010
1011
1012 /* returns URL of actual document (=document in the script context) */
1013 /* when an error occurs, returns NULL */
1014 /* returned string should be deallocated after use */
js_upcall_get_location(void * data)1015 unsigned char *js_upcall_get_location(void *data)
1016 {
1017 struct f_data_c *fd;
1018 unsigned char *loc;
1019
1020 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1021 fd=(struct f_data_c *)data;
1022
1023 loc=mem_alloc(MAX_STR_LEN);
1024
1025 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1026 return loc;
1027 }
1028
1029
1030 /* returns string containing last modification date */
1031 /* or NULL when the date is not known or when an error occurs */
js_upcall_document_last_modified(void * data,long document_id)1032 unsigned char *js_upcall_document_last_modified(void *data, long document_id)
1033 {
1034 struct f_data_c *fd;
1035 struct f_data_c *document;
1036 unsigned char *retval;
1037
1038 document=jsint_find_document(document_id);
1039 if (!data)internal_error("js_upcall_document_last_modified called with NULL pointer!");
1040 fd=(struct f_data_c *)data;
1041
1042 if (!document)return NULL; /* document not found */
1043 if (!jsint_can_access(fd, document))return NULL; /* you have no permissions to look at the document */
1044
1045 if (!fd->rq||!fd->rq->ce)return NULL;
1046 retval=stracpy(fd->rq->ce->last_modified);
1047
1048 return retval;
1049 }
1050
1051
1052 /* returns allocated string with user-agent */
js_upcall_get_useragent(void * data)1053 unsigned char *js_upcall_get_useragent(void *data)
1054 {
1055 /*struct f_data_c *fd;*/
1056 unsigned char *retval=init_str();
1057 int l=0;
1058
1059 if (!data)internal_error("js_upcall_get_useragent called with NULL pointer!");
1060 /*fd=(struct f_data_c *)data;*/
1061
1062 if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent)) {
1063 add_to_str(&retval, &l, "Links (" VERSION_STRING "; ");
1064 add_to_str(&retval, &l, system_name);
1065 add_to_str(&retval, &l, ")");
1066 }
1067 else {
1068 add_to_str(&retval, &l, http_options.header.fake_useragent);
1069 }
1070
1071 return retval;
1072 }
1073
1074
1075 /* returns allocated string with browser name */
js_upcall_get_appname(void)1076 unsigned char *js_upcall_get_appname(void)
1077 {
1078 if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent))
1079 return stracpy("Links");
1080 else
1081 return stracpy(http_options.header.fake_useragent);
1082 }
1083
1084
1085 /* returns allocated string with browser name */
js_upcall_get_appcodename(void)1086 unsigned char *js_upcall_get_appcodename(void)
1087 {
1088 if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent))
1089 return stracpy("Links");
1090 else
1091 return stracpy(http_options.header.fake_useragent);
1092 }
1093
1094
1095 /* returns allocated string with browser version: "version_number (system_name)" */
js_upcall_get_appversion(void)1096 unsigned char *js_upcall_get_appversion(void)
1097 {
1098 unsigned char *str;
1099 int l=0;
1100
1101 if (http_options.header.fake_useragent&&(*http_options.header.fake_useragent))return stracpy(http_options.header.fake_useragent);
1102 str=init_str();
1103 add_to_str(&str,&l,VERSION_STRING);
1104 add_to_str(&str,&l," (");
1105 add_to_str(&str,&l,system_name);
1106 add_to_str(&str,&l,")");
1107 return str;
1108 }
1109
1110
1111 /* returns allocated string with referrer */
js_upcall_get_referrer(void * data)1112 unsigned char *js_upcall_get_referrer(void *data)
1113 {
1114 struct f_data_c *fd;
1115 unsigned char *retval=init_str();
1116 unsigned char *loc;
1117 int l=0;
1118
1119 if (!data)internal_error("js_upcall_get_referrer called with NULL pointer!");
1120 fd=(struct f_data_c *)data;
1121
1122 switch (http_options.header.referer)
1123 {
1124 case REFERER_FAKE:
1125 add_to_str(&retval, &l, http_options.header.fake_referer);
1126 break;
1127
1128 case REFERER_SAME_URL:
1129 loc=mem_alloc(MAX_STR_LEN);
1130 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);break;}
1131 add_to_str(&retval, &l, loc);
1132 mem_free(loc);
1133 break;
1134
1135 case REFERER_REAL:
1136 {
1137 unsigned char *post;
1138
1139 if (!fd->rq||!(fd->rq->prev_url))break; /* no referrer */
1140 post=strchr(fd->rq->prev_url, POST_CHAR);
1141 if (!post)add_to_str(&retval, &l, fd->rq->prev_url);
1142 else add_bytes_to_str(&retval, &l, fd->rq->prev_url, post - fd->rq->prev_url);
1143 }
1144 break;
1145 }
1146
1147 return retval;
1148 }
1149
1150 struct gimme_js_id
1151 {
1152 long id; /* id of f_data_c */
1153 long js_id; /* unique id of javascript */
1154 };
1155
1156 /* tady se netestuje js_id, protoze BFU to chce killnout, tak to proste killne */
1157 /* aux function for all dialog upcalls */
js_kill_script_pressed(void * data)1158 static void js_kill_script_pressed(void *data)
1159 {
1160 struct f_data_c *fd;
1161 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1162
1163 fd=jsint_find_document(jsid->id);
1164 if (!fd)return; /* context no longer exists */
1165
1166 if (!(fd->js))return;
1167 js_downcall_game_over(fd->js->ctx); /* call downcall */
1168 }
1169
1170
1171
1172 /* aux function for js_upcall_confirm */
js_upcall_confirm_ok_pressed(void * data)1173 static void js_upcall_confirm_ok_pressed(void *data)
1174 {
1175 struct f_data_c *fd;
1176 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1177
1178 fd=jsint_find_document(jsid->id);
1179 if (!fd)return; /* context no longer exists */
1180
1181 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
1182 js_downcall_vezmi_true(fd->js->ctx); /* call downcall */
1183 }
1184
1185
1186 /* aux function for js_upcall_confirm */
js_upcall_confirm_cancel_pressed(void * data)1187 static void js_upcall_confirm_cancel_pressed(void *data)
1188 {
1189 struct f_data_c *fd;
1190 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1191
1192 fd=jsint_find_document(jsid->id);
1193 if (!fd)return; /* context no longer exists */
1194
1195 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
1196 js_downcall_vezmi_false(fd->js->ctx); /* call downcall */
1197 }
1198
1199
1200 /* creates dialog with text s->string and buttons OK/Cancel */
1201 /* s->string will be dealocated */
1202 /* s will be dealocated too */
1203 /* must be called from select loop */
js_upcall_confirm(void * data)1204 void js_upcall_confirm(void *data)
1205 {
1206 struct fax_me_tender_string *s=(struct fax_me_tender_string*)data;
1207 struct gimme_js_id* jsid;
1208 struct f_data_c *fd;
1209 struct terminal *term;
1210 unsigned char *txt;
1211
1212 if (!s)internal_error("js_upcall_confirm called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
1213
1214 /* context must be a valid pointer ! */
1215 fd=(struct f_data_c*)(s->ident);
1216 term=fd->ses->term;
1217
1218 if (!fd->js)return;
1219 jsid=mem_alloc(sizeof(struct gimme_js_id));
1220
1221 /* kill timer, that called me */
1222 js_spec_vykill_timer(fd->js->ctx,0);
1223
1224 /* fill in jsid */
1225 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
1226 jsid->js_id=fd->js->ctx->js_id;
1227
1228 skip_nonprintable(s->string);
1229 if (fd->f_data)
1230 {
1231 txt=convert(fd->f_data->cp, fd->f_data->opt.cp, s->string, NULL);
1232 }
1233 else
1234 txt=stracpy(s->string);
1235 js_mem_free(s->string);
1236 msg_box(
1237 term, /* terminal */
1238 getml(txt,jsid,NULL), /* memory blocks to free */
1239 TEXT_(T_QUESTION), /* title */
1240 AL_CENTER, /* alignment */
1241 txt,MSG_BOX_END, /* message */
1242 (void *)jsid, /* data for button functions */
1243 3, /* # of buttons */
1244 TEXT_(T_OK),js_upcall_confirm_ok_pressed,B_ENTER, /* first button */
1245 TEXT_(T_CANCEL),js_upcall_confirm_cancel_pressed,B_ESC, /* second button */
1246 TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
1247 );
1248
1249 js_mem_free(s);
1250 }
1251
1252
1253 /* aux function for js_upcall_alert */
js_upcall_alert_ok_pressed(void * data)1254 static void js_upcall_alert_ok_pressed(void *data)
1255 {
1256 struct f_data_c *fd;
1257 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1258
1259 fd=jsint_find_document(jsid->id);
1260 if (!fd)return; /* context no longer exists */
1261
1262 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
1263 js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
1264 }
1265
1266
1267 /* gets struct fax_me_tender_string* */
1268 /* creates dialog with title "Alert" and message got from struct fax_me_tender_string */
1269 /* structure and the text are both deallocated */
1270 /* must be called from select loop */
js_upcall_alert(void * data)1271 void js_upcall_alert(void * data)
1272 {
1273 struct fax_me_tender_string *s=(struct fax_me_tender_string*)data;
1274 struct gimme_js_id* jsid;
1275 struct f_data_c *fd;
1276 struct terminal *term;
1277 unsigned char *txt;
1278
1279 if (!s)internal_error("Alert called with NULL pointer.\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
1280
1281 /* context must be a valid pointer ! */
1282 fd=(struct f_data_c*)(s->ident);
1283 term=fd->ses->term;
1284
1285 if (!fd->js) return;
1286 jsid=mem_alloc(sizeof(struct gimme_js_id));
1287
1288 /* kill timer, that called me */
1289 js_spec_vykill_timer(fd->js->ctx,0);
1290
1291 /* fill in jsid */
1292 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
1293 jsid->js_id=fd->js->ctx->js_id;
1294
1295 skip_nonprintable(s->string);
1296 if (fd->f_data)
1297 {
1298 txt=convert(fd->f_data->cp, fd->f_data->opt.cp, s->string, NULL);
1299 }
1300 else
1301 txt=stracpy(s->string);
1302 js_mem_free(s->string);
1303 msg_box(
1304 term, /* terminal */
1305 getml(txt,jsid,NULL), /* memory blocks to free */
1306 TEXT_(T_ALERT), /* title */
1307 AL_CENTER, /* alignment */
1308 txt,MSG_BOX_END, /* message */
1309 (void *)jsid, /* data for button functions */
1310 2, /* # of buttons */
1311 TEXT_(T_OK),js_upcall_alert_ok_pressed,B_ENTER|B_ESC,
1312 TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
1313 );
1314
1315 js_mem_free(s);
1316 }
1317
1318
1319 /* aux function for js_upcall_close_window */
1320 /* tady se netestuje js_id, protoze BFU zmacklo, ze chce zavrit okno a v
1321 * nekterych pripadech by ho to nezavrelo (kdyby se testovalo) a to by vypadalo
1322 * blbe */
js_upcall_close_window_yes_pressed(void * data)1323 static void js_upcall_close_window_yes_pressed(void *data)
1324 {
1325 struct f_data_c *fd;
1326 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1327
1328 fd=jsint_find_document(jsid->id);
1329 if (!fd)return; /* context no longer exists */
1330
1331 really_exit_prog(fd->ses);
1332 }
1333
1334
1335 /* asks user if he really wants to close the window and calls really_exit_prog */
1336 /* argument is struct fax_me_tender_nothing* */
1337 /* must be called from select loop */
js_upcall_close_window(void * data)1338 void js_upcall_close_window(void *data)
1339 {
1340 struct fax_me_tender_nothing *s=(struct fax_me_tender_nothing*)data;
1341 struct f_data_c *fd;
1342 struct terminal *term;
1343
1344 if (!s)internal_error("js_upcall_close_window called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
1345
1346 /* context must be a valid pointer ! */
1347 fd=(struct f_data_c*)(s->ident);
1348 if (!fd->js) return;
1349 term=fd->ses->term;
1350
1351 /* kill timer, that called me */
1352 js_spec_vykill_timer(fd->js->ctx,0);
1353
1354 if (js_manual_confirmation)
1355 {
1356 struct gimme_js_id* jsid;
1357
1358 jsid=mem_alloc(sizeof(struct gimme_js_id));
1359
1360 /* fill in jsid */
1361 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
1362 jsid->js_id=fd->js->ctx->js_id;
1363
1364 msg_box(
1365 term, /* terminal */
1366 getml(jsid,NULL), /* memory blocks to free */
1367 TEXT_(T_EXIT_LINKS), /* title */
1368 AL_CENTER, /* alignment */
1369 TEXT_(T_SCRIPT_TRYING_TO_CLOSE_WINDOW),MSG_BOX_END, /* message */
1370 (void *)jsid, /* data for button functions */
1371 2, /* # of buttons */
1372 TEXT_(T_YES),js_upcall_close_window_yes_pressed,NULL,
1373 TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
1374 );
1375 js_mem_free(s);
1376 }
1377 else
1378 {
1379 js_mem_free(s);
1380 if (term->list_entry.next == term->list_entry.prev && are_there_downloads())
1381 query_exit(fd->ses);
1382 else
1383 really_exit_prog(fd->ses);
1384 }
1385 }
1386
1387
1388 /* returns parent window ID of the script */
js_upcall_get_window_id(void * data)1389 long js_upcall_get_window_id(void *data)
1390 {
1391 struct f_data_c *fd;
1392 if (!data)internal_error("js_upcall_get_window_id called with NULL pointer!");
1393
1394 fd=(struct f_data_c*)data;
1395 return ((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_FRAME;
1396 }
1397
1398
1399
1400 /* aux function for js_upcall_get_string */
js_upcall_get_string_ok_pressed(void * data,unsigned char * str)1401 static void js_upcall_get_string_ok_pressed(void *data, unsigned char *str)
1402 {
1403 struct f_data_c *fd;
1404 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
1405
1406 fd=jsint_find_document(jsid->id);
1407 if (!fd)return; /* context no longer exists */
1408
1409 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
1410 js_downcall_vezmi_string(fd->js->ctx, stracpy(str)); /* call downcall */
1411 }
1412
js_upcall_get_string_kill_script_pressed(void * data,unsigned char * str)1413 static void js_upcall_get_string_kill_script_pressed(void *data, unsigned char *str)
1414 {
1415 js_kill_script_pressed(data);
1416 }
1417
1418 struct history js_get_string_history={0, {&js_get_string_history.items, &js_get_string_history.items}};
1419
1420
1421 /* creates input field for string, with text s->string1, default response
1422 * s->string2 and buttons OK/Kill Script
1423 * s->string1 and s->string2 will be dealocated
1424 * s will be dealocated too
1425 * must be called from select loop */
1426
js_upcall_get_string(void * data)1427 void js_upcall_get_string(void *data)
1428 {
1429 struct fax_me_tender_2_stringy *s=(struct fax_me_tender_2_stringy*)data;
1430 struct gimme_js_id* jsid;
1431 struct f_data_c *fd;
1432 struct terminal *term;
1433 unsigned char *str1,*str2;
1434
1435 if (!s)internal_error("js_upcall_get_string called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
1436
1437 /* context must be a valid pointer ! */
1438 fd=(struct f_data_c*)(s->ident);
1439 term=fd->ses->term;
1440
1441 if (!fd->js) return;
1442 jsid=mem_alloc(sizeof(struct gimme_js_id));
1443
1444 /* kill timer, that called me */
1445 js_spec_vykill_timer(fd->js->ctx,0);
1446
1447 /* fill in jsid */
1448 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
1449 jsid->js_id=fd->js->ctx->js_id;
1450
1451 str1=stracpy(s->string1);
1452 str2=stracpy(s->string2);
1453 js_mem_free(s->string1);
1454 js_mem_free(s->string2);
1455
1456 input_field(
1457 term, /* terminal */
1458 getml(str1, str2,jsid,NULL), /* mem to free */
1459 TEXT_(T_ENTER_STRING), /* title */
1460 str1, /* question */
1461 jsid, /* data for functions */
1462 &js_get_string_history, /* history */
1463 MAX_INPUT_URL_LEN, /* string len */
1464 str2, /* string to fill the dialog with */
1465 0, /* min value */
1466 0, /* max value */
1467 NULL, /* check fn */
1468 2, /* the number of buttons */
1469 TEXT_(T_OK), /* ok button */
1470 js_upcall_get_string_ok_pressed,
1471 TEXT_(T_KILL_SCRIPT), /* cancel button */
1472 js_upcall_get_string_kill_script_pressed
1473 );
1474 js_mem_free(s);
1475 }
1476
1477
1478 /* clears window with javascript */
1479 /* must be called from select loop */
1480 /* javascript must halt before calling this upcall */
js_upcall_clear_window(void * data)1481 void js_upcall_clear_window(void *data)
1482 {
1483 /* context must be a valid pointer ! */
1484 /*struct f_data_c *fd=(struct f_data_c*)data;*/
1485 /* no jsint_destroy context or so here, it's called automatically from reinit_f_data_c */
1486 /*
1487 zatim jsem to zrusil ... tahle funkce musi byt volana pres timer, takhle je to uplne blbe a spadne to pri kazdem volani -- Mikulas
1488
1489 to je <|>vina, v komentari je jasne napsano, ze tahle fce musi byt volana ze select loop, takze to nema co padat -- Brain
1490
1491 no prave!! ze select smycky == z timeru. Z javascriptu to volat nemuzes, protoze to pod sebou ten kontext javascriptu smaze, a ten interpret spadne, protoze jeho kontext uz nebude existovat. -- Mikulas
1492
1493 reinit_f_data_c(fd);
1494 */
1495 }
1496
1497
1498 /* returns allocated string with window name */
js_upcall_get_window_name(void * data)1499 unsigned char *js_upcall_get_window_name(void *data)
1500 {
1501 /* context must be a valid pointer ! */
1502 struct f_data_c *fd=(struct f_data_c*)data;
1503
1504 return fd->loc?stracpy(fd->loc->name):NULL;
1505 }
1506
1507
1508 /* returns allocated field of ID's of links in JS document
1509 * number of links is stored in len
1510 * if number of links is 0, returns NULL
1511 * on error returns NULL too
1512 */
js_upcall_get_links(void * data,long document_id,int * len)1513 long *js_upcall_get_links(void *data, long document_id, int *len)
1514 {
1515 struct f_data_c *js_ctx=(struct f_data_c*)data;
1516 struct f_data_c *fd;
1517 /*struct link *l;*/
1518 int a;
1519 long *to_je_Ono;
1520
1521 fd=jsint_find_document(document_id);
1522 if (!js_ctx)internal_error("js_upcall_get_links called with NULL context pointer\n");
1523 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1524 if (!(fd->f_data))return NULL;
1525 *len=fd->f_data->nlinks;
1526 if (!(*len))return NULL;
1527 /*l=fd->f_data->links;*/
1528 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
1529 to_je_Ono=mem_alloc((*len)*sizeof(long));
1530
1531 for (a=0;a<(*len);a++)
1532 /*to_je_Ono[a]=JS_OBJ_T_LINK+(((l+a)->num)<<JS_OBJ_MASK_SIZE);*/
1533 to_je_Ono[a]=JS_OBJ_T_LINK+(a<<JS_OBJ_MASK_SIZE);
1534
1535 return to_je_Ono;
1536 }
1537
1538
1539 /* returns allocated string with TARGET of the link
1540 * if the link doesn't exist in the document, returns NULL
1541 */
js_upcall_get_link_target(void * data,long document_id,long link_id)1542 unsigned char *js_upcall_get_link_target(void *data, long document_id, long link_id)
1543 {
1544 struct f_data_c *js_ctx=(struct f_data_c*)data;
1545 struct f_data_c *fd;
1546 struct link *l;
1547
1548 if (!js_ctx)internal_error("js_upcall_get_link_target called with NULL context pointer\n");
1549 if ((link_id&JS_OBJ_MASK)!=JS_OBJ_T_LINK)return NULL; /* this isn't link */
1550
1551 fd=jsint_find_document(document_id);
1552 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1553
1554 l=jsint_find_object(fd,link_id);
1555 if (!l)return NULL;
1556
1557 return stracpy((l->target)?(l->target):(unsigned char *)(""));
1558 }
1559
1560
1561 /* returns allocated field of ID's of forms in JS document
1562 * number of forms is stored in len
1563 * if number of forms is 0, returns NULL
1564 * on error returns NULL too
1565 */
js_upcall_get_forms(void * data,long document_id,int * len)1566 long *js_upcall_get_forms(void *data, long document_id, int *len)
1567 {
1568 struct f_data_c *js_ctx=(struct f_data_c *)data;
1569 struct f_data_c *fd;
1570 struct form_control *fc;
1571 struct list_head *lfc;
1572 long *to_je_Ono;
1573 long last=0;
1574
1575 if (!js_ctx)internal_error("js_upcall_get_forms called with NULL context pointer\n");
1576 fd=jsint_find_document(document_id);
1577 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1578
1579 if (!(fd->f_data))return NULL;
1580
1581 to_je_Ono=mem_alloc(sizeof(long));
1582
1583 *len=0;
1584
1585 foreachback(struct form_control, fc, lfc, fd->f_data->forms) {
1586 long *p;
1587 int a;
1588
1589 if ((*len)&&(fc->form_num)==last)continue;
1590 for (a=0;a<(*len);a++)
1591 if ((to_je_Ono[a]>>JS_OBJ_MASK_SIZE)==(fc->form_num))goto already_have; /* we already have this number */
1592
1593 (*len)++;
1594 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
1595 p=mem_realloc(to_je_Ono,(*len)*sizeof(long));
1596 to_je_Ono=p;
1597 to_je_Ono[(*len)-1]=JS_OBJ_T_FORM|((fc->form_num)<<JS_OBJ_MASK_SIZE);
1598 last=fc->form_num;
1599 already_have:;
1600 }
1601
1602 if (!(*len)){mem_free(to_je_Ono);to_je_Ono=NULL;}
1603
1604 return to_je_Ono;
1605 }
1606
1607
1608 /* returns allocated string with the form action
1609 * when an error occurs, returns NULL
1610 */
js_upcall_get_form_action(void * data,long document_id,long form_id)1611 unsigned char *js_upcall_get_form_action(void *data, long document_id, long form_id)
1612 {
1613 struct f_data_c *js_ctx=(struct f_data_c *)data;
1614 struct f_data_c *fd;
1615 struct form_control *fc;
1616
1617 if (!js_ctx)internal_error("js_upcall_get_form_action called with NULL context pointer\n");
1618 fd=jsint_find_document(document_id);
1619 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1620
1621 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
1622
1623 fc=jsint_find_object(fd,form_id);
1624 if (!fc)return NULL;
1625
1626 return stracpy(fc->action);
1627 }
1628
1629
1630
1631 /* sets form action
1632 */
js_upcall_set_form_action(void * context,long document_id,long form_id,unsigned char * action)1633 void js_upcall_set_form_action(void *context, long document_id, long form_id, unsigned char *action)
1634 {
1635 struct f_data_c *js_ctx=(struct f_data_c *)context;
1636 struct f_data_c *fd;
1637 struct form_control *fc;
1638
1639 if (!js_ctx) {
1640 internal_error("js_upcall_set_form_action called with NULL context pointer\n");
1641 }
1642
1643 fd=jsint_find_document(document_id);
1644 if (!fd || !jsint_can_access(js_ctx,fd)) {
1645 if (action) mem_free(action);
1646 return;
1647 }
1648
1649 if ( (form_id&JS_OBJ_MASK) != JS_OBJ_T_FORM ) {
1650 if (action) mem_free(action);
1651 return;
1652 }
1653
1654 fc=jsint_find_object(fd,form_id);
1655 if (!fc) {
1656 if (action) mem_free(action);
1657 return;
1658 }
1659
1660 if (fc->action) {
1661 mem_free (fc->action);
1662 if ( fd->loc && fd->loc->url )
1663 fc->action=join_urls(fd->loc->url,action);
1664 else
1665 fc->action=stracpy(action);
1666 fd->f_data->uncacheable=1;
1667 }
1668
1669 if (action) {
1670 mem_free(action);
1671 }
1672 }
1673
1674
1675 /* returns allocated string with the form target
1676 * when an error occurs, returns NULL
1677 */
js_upcall_get_form_target(void * data,long document_id,long form_id)1678 unsigned char *js_upcall_get_form_target(void *data, long document_id, long form_id)
1679 {
1680 struct f_data_c *js_ctx=(struct f_data_c *)data;
1681 struct f_data_c *fd;
1682 struct form_control *fc;
1683
1684 if (!js_ctx)internal_error("js_upcall_get_form_target called with NULL context pointer\n");
1685 fd=jsint_find_document(document_id);
1686 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1687
1688 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
1689
1690 fc=jsint_find_object(fd,form_id);
1691 if (!fc)return NULL;
1692
1693 return stracpy(fc->target);
1694 }
1695
1696
1697
1698 /* returns allocated string with the form method
1699 * when an error occurs, returns NULL
1700 */
js_upcall_get_form_method(void * data,long document_id,long form_id)1701 unsigned char *js_upcall_get_form_method(void *data, long document_id, long form_id)
1702 {
1703 struct f_data_c *js_ctx=(struct f_data_c *)data;
1704 struct f_data_c *fd;
1705 struct form_control *fc;
1706
1707 if (!js_ctx)internal_error("js_upcall_get_form_method called with NULL context pointer\n");
1708 fd=jsint_find_document(document_id);
1709 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1710
1711 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
1712
1713 fc=jsint_find_object(fd,form_id);
1714 if (!fc)return NULL;
1715
1716 switch (fc->method)
1717 {
1718 case FM_GET:
1719 return stracpy("GET");
1720
1721 case FM_POST:
1722 case FM_POST_MP:
1723 return stracpy("POST");
1724
1725 default:
1726 internal_error("Invalid form method!\n");
1727 return NULL; /* never called, but GCC likes it */
1728 }
1729 }
1730
1731
1732
1733 /* returns allocated string with the form encoding (value of attribute enctype)
1734 * when an error occurs, returns NULL
1735 */
js_upcall_get_form_encoding(void * data,long document_id,long form_id)1736 unsigned char *js_upcall_get_form_encoding(void *data, long document_id, long form_id)
1737 {
1738 struct f_data_c *js_ctx=(struct f_data_c *)data;
1739 struct f_data_c *fd;
1740 struct form_control *fc;
1741
1742 if (!js_ctx)internal_error("js_upcall_get_form_encoding called with NULL context pointer\n");
1743 fd=jsint_find_document(document_id);
1744 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
1745
1746 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
1747
1748 fc=jsint_find_object(fd,form_id);
1749 if (!fc)return NULL;
1750
1751 switch (fc->method)
1752 {
1753 case FM_GET:
1754 case FM_POST:
1755 return stracpy("application/x-www-form-urlencoded");
1756
1757 case FM_POST_MP:
1758 return stracpy("multipart/form-data");
1759
1760 default:
1761 internal_error("Invalid form method!\n");
1762 return NULL; /* never called, but GCC likes it */
1763 }
1764 }
1765
1766
1767 /* returns allocated string containing protocol from current URL in the script context
1768 * on error (or there's no protocol) NULL is returned
1769 */
js_upcall_get_location_protocol(void * data)1770 unsigned char *js_upcall_get_location_protocol(void *data)
1771 {
1772 struct f_data_c *fd;
1773 unsigned char *loc;
1774 unsigned char *p;
1775 int l;
1776
1777 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1778 fd=(struct f_data_c *)data;
1779
1780 loc=mem_alloc(MAX_STR_LEN);
1781
1782 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1783
1784 if (parse_url(loc, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)){mem_free(loc);return NULL;}
1785 p=memacpy(loc,l+1); /* l is pointing to the colon, but we want protocol with colon */
1786 mem_free(loc);
1787 return p;
1788 }
1789
1790
1791 /* returns allocated string containing port of current URL in the script context
1792 * on error (or there's no protocol) NULL is returned
1793 */
js_upcall_get_location_port(void * data)1794 unsigned char *js_upcall_get_location_port(void *data)
1795 {
1796 struct f_data_c *fd;
1797 unsigned char *loc;
1798 unsigned char *p;
1799
1800 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1801 fd=(struct f_data_c *)data;
1802
1803 loc=mem_alloc(MAX_STR_LEN);
1804
1805 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1806
1807 p=get_port_str(loc);
1808 mem_free(loc);
1809 return p;
1810 }
1811
1812
1813 /* returns allocated string containing hostname of current URL in the script context
1814 * on error (or there's no protocol) NULL is returned
1815 */
js_upcall_get_location_hostname(void * data)1816 unsigned char *js_upcall_get_location_hostname(void *data)
1817 {
1818 struct f_data_c *fd;
1819 unsigned char *loc;
1820 unsigned char *p;
1821
1822 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1823 fd=(struct f_data_c *)data;
1824
1825 loc=mem_alloc(MAX_STR_LEN);
1826
1827 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1828
1829 p=get_host_name(loc);
1830 mem_free(loc);
1831 return p;
1832 }
1833
1834
1835 /* returns allocated string containing hostname and port of current URL in the script context
1836 * on error (or there's no protocol) NULL is returned
1837 */
js_upcall_get_location_host(void * data)1838 unsigned char *js_upcall_get_location_host(void *data)
1839 {
1840 struct f_data_c *fd;
1841 unsigned char *loc;
1842 unsigned char *p, *h;
1843 int l1,l2;
1844
1845 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1846 fd=(struct f_data_c *)data;
1847
1848 loc=mem_alloc(MAX_STR_LEN);
1849
1850 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1851
1852 if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, &h, &l1, NULL, &l2, NULL, NULL, NULL)){mem_free(loc);return NULL;}
1853 p=memacpy(h,l1+l2);
1854 mem_free(loc);
1855 return p;
1856 }
1857
1858
1859 /* returns allocated string containing pathname of current URL in the script context
1860 * on error (or there's no protocol) NULL is returned
1861 */
js_upcall_get_location_pathname(void * data)1862 unsigned char *js_upcall_get_location_pathname(void *data)
1863 {
1864 struct f_data_c *fd;
1865 unsigned char *loc;
1866 unsigned char *d, *p;
1867
1868 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1869 fd=(struct f_data_c *)data;
1870
1871 loc=mem_alloc(MAX_STR_LEN);
1872
1873 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1874
1875 if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
1876 if (!d){mem_free(loc);return NULL;}
1877 p=memacpy(d,strcspn(d,"?"));
1878 mem_free(loc);
1879 return p;
1880 }
1881
1882
1883 /* returns allocated string containing everything after ? in current URL in the script context
1884 * on error (or there's no protocol) NULL is returned
1885 */
js_upcall_get_location_search(void * data)1886 unsigned char *js_upcall_get_location_search(void *data)
1887 {
1888 struct f_data_c *fd;
1889 unsigned char *loc;
1890 unsigned char *d, *p;
1891
1892 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1893 fd=(struct f_data_c *)data;
1894
1895 loc=mem_alloc(MAX_STR_LEN);
1896
1897 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1898
1899 if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
1900 if (!d){mem_free(loc);return NULL;}
1901 p=stracpy(strchr(d,'?'));
1902 mem_free(loc);
1903 return p;
1904 }
1905
1906
1907 /* returns allocated string containing everything between # and ? in current URL in the script context
1908 * on error (or there's no protocol) NULL is returned
1909 */
js_upcall_get_location_hash(void * data)1910 unsigned char *js_upcall_get_location_hash(void *data)
1911 {
1912 struct f_data_c *fd;
1913 unsigned char *loc;
1914 unsigned char *d, *p;
1915
1916 if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
1917 fd=(struct f_data_c *)data;
1918
1919 loc=mem_alloc(MAX_STR_LEN);
1920
1921 if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
1922
1923 if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
1924 if (!d){mem_free(loc);return NULL;}
1925 d=strchr(d,'#');
1926 if (!d){mem_free(loc);return NULL;}
1927 d++;
1928 p=memacpy(d,strcspn(d,"?"));
1929 mem_free(loc);
1930 return p;
1931 }
1932
1933
1934 /* returns allocated field of all form elements
1935 * size of the field will be stored in len
1936 * when an error occurs, returns NULL
1937 */
js_upcall_get_form_elements(void * data,long document_id,long form_id,int * len)1938 long *js_upcall_get_form_elements(void *data, long document_id, long form_id, int *len)
1939 {
1940 struct f_data_c *js_ctx=(struct f_data_c *)data;
1941 struct f_data_c *fd;
1942 struct form_control *fc, *fc2;
1943 struct list_head *lfc2;
1944 long *pole_Premysla_Zavorace;
1945 int b;
1946
1947 if (!js_ctx)internal_error("js_upcall_get_form_elements called with NULL context pointer\n");
1948 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
1949 fd=jsint_find_document(document_id);
1950 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
1951
1952 fc=jsint_find_object(fd,form_id);
1953 if (!fc)return NULL;
1954
1955 *len=0;
1956
1957 foreach(struct form_control, fc2, lfc2, fd->f_data->forms)
1958 if (fc2->form_num==fc->form_num)(*len)++;
1959
1960 if (!(*len))return NULL;
1961
1962 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
1963 pole_Premysla_Zavorace=mem_alloc((*len)*sizeof(long));
1964
1965 b=0;
1966 foreachback(struct form_control, fc2, lfc2, fd->f_data->forms)
1967 if (fc2->form_num==fc->form_num)
1968 {
1969 switch (fc2->type)
1970 {
1971 case FC_TEXT: pole_Premysla_Zavorace[b]=JS_OBJ_T_TEXT; break;
1972 case FC_PASSWORD: pole_Premysla_Zavorace[b]=JS_OBJ_T_PASSWORD; break;
1973 case FC_TEXTAREA: pole_Premysla_Zavorace[b]=JS_OBJ_T_TEXTAREA; break;
1974 case FC_CHECKBOX: pole_Premysla_Zavorace[b]=JS_OBJ_T_CHECKBOX; break;
1975 case FC_RADIO: pole_Premysla_Zavorace[b]=JS_OBJ_T_RADIO; break;
1976 case FC_IMAGE:
1977 case FC_SELECT: pole_Premysla_Zavorace[b]=JS_OBJ_T_SELECT; break;
1978 case FC_SUBMIT: pole_Premysla_Zavorace[b]=JS_OBJ_T_SUBMIT ; break;
1979 case FC_RESET: pole_Premysla_Zavorace[b]=JS_OBJ_T_RESET ; break;
1980 case FC_HIDDEN: pole_Premysla_Zavorace[b]=JS_OBJ_T_HIDDEN ; break;
1981 case FC_BUTTON: pole_Premysla_Zavorace[b]=JS_OBJ_T_BUTTON ; break;
1982 default: /* internal_error("Invalid form element type.\n"); */
1983 (*len)--;
1984 continue;
1985 }
1986 pole_Premysla_Zavorace[b]|=((fc2->g_ctrl_num)<<JS_OBJ_MASK_SIZE);
1987 b++;
1988 }
1989 return pole_Premysla_Zavorace;
1990 }
1991
1992
1993 /* returns allocated field with anchors
1994 * size of the field is stored in len
1995 * when there're no anchors, *len is 0 and NULL is returned
1996 * on error NULL is returned
1997 */
js_upcall_get_anchors(void * hej_Hombre,long document_id,int * len)1998 long *js_upcall_get_anchors(void *hej_Hombre, long document_id, int *len)
1999 {
2000 struct f_data_c *js_ctx=(struct f_data_c*)hej_Hombre;
2001 struct f_data_c *fd;
2002 int a;
2003 long *to_je_Ono;
2004 *len=0;
2005
2006 if (!js_ctx)internal_error("js_upcall_get_anchors called with NULL context pointer\n");
2007 fd=jsint_find_document(document_id);
2008 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
2009
2010 if (!(fd->f_data))return NULL;
2011 *len = (int)list_size(&fd->f_data->tags);
2012 if (!*len) return NULL;
2013 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
2014 to_je_Ono = mem_alloc((*len)*sizeof(long));
2015
2016 for (a = 0; a < *len; a++)
2017 to_je_Ono[a] = JS_OBJ_T_ANCHOR + (a << JS_OBJ_MASK_SIZE);
2018 return to_je_Ono;
2019
2020 }
2021
2022
2023 /* returns whether radio or checkbox is checked
2024 * return value: 0=not checked
2025 * 1=checked
2026 * -1=error
2027 */
js_upcall_get_checkbox_radio_checked(void * smirak,long document_id,long radio_tv_id)2028 int js_upcall_get_checkbox_radio_checked(void *smirak, long document_id, long radio_tv_id)
2029 {
2030 struct f_data_c *js_ctx=(struct f_data_c*)smirak;
2031 struct f_data_c *fd;
2032 struct hopla_mladej *hopla;
2033 int state;
2034
2035 if (!js_ctx)internal_error("js_upcall_get_checkbox_radio_checked called with NULL context pointer\n");
2036 fd=jsint_find_document(document_id);
2037 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
2038
2039 if ((radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO&&(radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_CHECKBOX)return -1; /* this isn't radio nor TV */
2040
2041 hopla=jsint_find_object(fd,radio_tv_id);
2042 if (!hopla)return -1;
2043
2044 state=hopla->fs->state;
2045 mem_free(hopla);
2046 return state;
2047 }
2048
2049
2050 /* checks/unchecks radio or checkbox
2051 */
js_upcall_set_checkbox_radio_checked(void * smirak,long document_id,long radio_tv_id,int value)2052 void js_upcall_set_checkbox_radio_checked(void *smirak, long document_id, long radio_tv_id, int value)
2053 {
2054 struct f_data_c *js_ctx=(struct f_data_c*)smirak;
2055 struct f_data_c *fd;
2056 struct hopla_mladej *hopla;
2057
2058 if (!js_ctx)internal_error("js_upcall_set_checkbox_radio_checked called with NULL context pointer\n");
2059 if ((radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO&&(radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_CHECKBOX)return; /* this isn't radio nor TV */
2060 fd=jsint_find_document(document_id);
2061 if (!fd||!jsint_can_access(js_ctx,fd))return;
2062
2063 hopla=jsint_find_object(fd,radio_tv_id);
2064 if (!hopla)return;
2065
2066 hopla->fs->state=!!value;
2067 mem_free(hopla);
2068 redraw_document(fd);
2069 }
2070
2071
2072 /* returns whether radio or checkbox is checked
2073 * return value: 0=default not checked
2074 * 1=default checked
2075 * -1=error
2076 */
js_upcall_get_checkbox_radio_default_checked(void * bidak_smirak,long document_id,long radio_tv_id)2077 int js_upcall_get_checkbox_radio_default_checked(void *bidak_smirak, long document_id, long radio_tv_id)
2078 {
2079 struct f_data_c *js_ctx=(struct f_data_c*)bidak_smirak;
2080 struct f_data_c *fd;
2081 struct hopla_mladej *hopla;
2082 int default_checked;
2083
2084 if (!js_ctx)internal_error("js_upcall_get_checkbox_radio_default_checked called with NULL context pointer\n");
2085 if ((radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO&&(radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_CHECKBOX)return -1; /* this isn't radio nor TV */
2086 fd=jsint_find_document(document_id);
2087 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
2088
2089 hopla=jsint_find_object(fd,radio_tv_id);
2090 if (!hopla)return -1;
2091
2092 default_checked=hopla->fc->default_state;
2093 mem_free(hopla);
2094 return default_checked;
2095 }
2096
2097
2098 /* sets radio/checkbox default_checked in the form
2099 */
js_upcall_set_checkbox_radio_default_checked(void * bidak_smirak,long document_id,long radio_tv_id,int value)2100 void js_upcall_set_checkbox_radio_default_checked(void *bidak_smirak, long document_id, long radio_tv_id, int value)
2101 {
2102 struct f_data_c *js_ctx=(struct f_data_c*)bidak_smirak;
2103 struct f_data_c *fd;
2104 struct hopla_mladej *hopla;
2105 int something_changed;
2106 value=!!value;
2107
2108 if (!js_ctx)internal_error("js_upcall_set_checkbox_radio_default_checked called with NULL context pointer\n");
2109 if ((radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO&&(radio_tv_id&JS_OBJ_MASK)!=JS_OBJ_T_CHECKBOX)return; /* this isn't radio nor TV */
2110 fd=jsint_find_document(document_id);
2111 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return;
2112
2113 hopla=jsint_find_object(fd,radio_tv_id);
2114 if (!hopla)return;
2115
2116 something_changed=(hopla->fc->default_state)^value;
2117 hopla->fc->default_state=value;
2118 fd->f_data->uncacheable|=something_changed;
2119 mem_free(hopla);
2120 }
2121
2122
2123 /* returns allocated string with name of the form element
2124 * don't forget to free the string after use
2125 * on error returns NULL
2126 */
js_upcall_get_form_element_name(void * bidak,long document_id,long ksunt_id)2127 unsigned char *js_upcall_get_form_element_name(void *bidak, long document_id, long ksunt_id)
2128 {
2129 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2130 struct f_data_c *fd;
2131 struct hopla_mladej *hopla;
2132 unsigned char *hele_ho_bidaka;
2133
2134 if (!js_ctx)internal_error("js_upcall_get_form_element_name called with NULL context pointer\n");
2135 fd=jsint_find_document(document_id);
2136 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
2137
2138 switch (ksunt_id&JS_OBJ_MASK)
2139 {
2140 case JS_OBJ_T_RADIO:
2141 case JS_OBJ_T_TEXT:
2142 case JS_OBJ_T_PASSWORD:
2143 case JS_OBJ_T_TEXTAREA:
2144 case JS_OBJ_T_CHECKBOX:
2145 case JS_OBJ_T_SELECT:
2146 case JS_OBJ_T_SUBMIT:
2147 case JS_OBJ_T_RESET:
2148 case JS_OBJ_T_HIDDEN:
2149 case JS_OBJ_T_BUTTON:
2150 break;
2151
2152 default:
2153 return NULL; /* To neni Jim Beam! */
2154 }
2155
2156 hopla=jsint_find_object(fd,ksunt_id);
2157 if (!hopla)return NULL;
2158
2159 hele_ho_bidaka=stracpy(hopla->fc->name);
2160 mem_free(hopla);
2161 return hele_ho_bidaka;
2162 }
2163
2164
2165 /* sets name of the form element
2166 * name is allocated string, this function deallocates it
2167 */
js_upcall_set_form_element_name(void * bidak,long document_id,long ksunt_id,unsigned char * name)2168 void js_upcall_set_form_element_name(void *bidak, long document_id, long ksunt_id, unsigned char *name)
2169 {
2170 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2171 struct f_data_c *fd;
2172 struct hopla_mladej *hopla;
2173
2174 if (!js_ctx)internal_error("js_upcall_set_form_element_name called with NULL context pointer\n");
2175 fd=jsint_find_document(document_id);
2176 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
2177
2178 switch (ksunt_id&JS_OBJ_MASK)
2179 {
2180 case JS_OBJ_T_RADIO:
2181 case JS_OBJ_T_TEXT:
2182 case JS_OBJ_T_PASSWORD:
2183 case JS_OBJ_T_TEXTAREA:
2184 case JS_OBJ_T_CHECKBOX:
2185 case JS_OBJ_T_SELECT:
2186 case JS_OBJ_T_SUBMIT:
2187 case JS_OBJ_T_RESET:
2188 case JS_OBJ_T_HIDDEN:
2189 case JS_OBJ_T_BUTTON:
2190 break;
2191
2192 default:
2193 if(name) mem_free(name);
2194 return; /* To neni Jim Beam! */
2195 }
2196
2197 hopla=jsint_find_object(fd,ksunt_id);
2198 if (!hopla){if (name)mem_free(name);return;}
2199
2200 if ((name||(hopla->fc->name))&&strcmp(cast_const_char name,cast_const_char hopla->fc->name))
2201 {
2202 mem_free(hopla->fc->name);
2203 hopla->fc->name=stracpy(name);
2204 fd->f_data->uncacheable=1;
2205 }
2206 mem_free(hopla);
2207 if(name) mem_free(name);
2208 }
2209
2210
2211 /* returns allocated string with value of VALUE attribute of the form element
2212 * on error returns NULL
2213 * don't forget to free the string after use
2214 */
js_upcall_get_form_element_default_value(void * bidak,long document_id,long ksunt_id)2215 unsigned char *js_upcall_get_form_element_default_value(void *bidak, long document_id, long ksunt_id)
2216 {
2217 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2218 struct f_data_c *fd;
2219 struct hopla_mladej *hopla;
2220 unsigned char *hele_ho_bidaka;
2221
2222 if (!js_ctx)internal_error("js_upcall_get_form_element_default_value called with NULL context pointer\n");
2223 fd=jsint_find_document(document_id);
2224 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
2225
2226 switch (ksunt_id&JS_OBJ_MASK)
2227 {
2228 case JS_OBJ_T_RADIO:
2229 case JS_OBJ_T_TEXT:
2230 case JS_OBJ_T_PASSWORD:
2231 case JS_OBJ_T_TEXTAREA:
2232 case JS_OBJ_T_CHECKBOX:
2233 case JS_OBJ_T_SELECT:
2234 case JS_OBJ_T_SUBMIT:
2235 case JS_OBJ_T_RESET:
2236 case JS_OBJ_T_HIDDEN:
2237 break;
2238
2239 default:
2240 return NULL; /* To neni Jim Beam! */
2241 }
2242
2243 hopla=jsint_find_object(fd,ksunt_id);
2244 if (!hopla)return NULL;
2245
2246 hele_ho_bidaka=convert(fd->f_data->opt.cp, fd->f_data->cp, hopla->fc->default_value, NULL);
2247
2248 mem_free(hopla);
2249 return hele_ho_bidaka;
2250 }
2251
2252
2253 /* sets attribute VALUE of the form element
2254 * name is allocated string that, this function frees it
2255 * when name is NULL default value will be empty
2256 */
js_upcall_set_form_element_default_value(void * bidak,long document_id,long ksunt_id,unsigned char * name)2257 void js_upcall_set_form_element_default_value(void *bidak, long document_id, long ksunt_id, unsigned char *name)
2258 {
2259 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2260 struct f_data_c *fd;
2261 struct hopla_mladej *hopla;
2262
2263 if (!js_ctx)internal_error("js_upcall_set_form_element_default_value called with NULL context pointer\n");
2264 fd=jsint_find_document(document_id);
2265 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
2266
2267 switch (ksunt_id&JS_OBJ_MASK)
2268 {
2269 case JS_OBJ_T_RADIO:
2270 case JS_OBJ_T_TEXT:
2271 case JS_OBJ_T_PASSWORD:
2272 case JS_OBJ_T_TEXTAREA:
2273 case JS_OBJ_T_CHECKBOX:
2274 case JS_OBJ_T_SELECT:
2275 case JS_OBJ_T_SUBMIT:
2276 case JS_OBJ_T_RESET:
2277 case JS_OBJ_T_HIDDEN:
2278 break;
2279
2280 default:
2281 if (name)mem_free(name);
2282 return; /* To neni Jim Beam! */
2283 }
2284
2285 hopla=jsint_find_object(fd,ksunt_id);
2286 if (!hopla){if (name)mem_free(name);return;}
2287
2288 if ((name||(hopla->fc->default_value))&&strcmp(cast_const_char name,cast_const_char hopla->fc->default_value))
2289 {
2290 mem_free(hopla->fc->default_value);
2291 hopla->fc->default_value=convert(fd->f_data->cp, fd->f_data->opt.cp, name, NULL);
2292 fd->f_data->uncacheable=1;
2293 }
2294 mem_free(hopla);
2295 if (name)mem_free(name);
2296 }
2297
get_js_event_ptr(struct js_event_spec ** j,long type)2298 static unsigned char **get_js_event_ptr(struct js_event_spec **j, long type)
2299 {
2300 create_js_event_spec(j);
2301 if (type == Conkeydown) return &(*j)->keydown_code;
2302 else if (type == Conkeypress) return &(*j)->keypress_code;
2303 else if (type == Conkeyup) return &(*j)->keyup_code;
2304 else return NULL;
2305 }
2306
js_upcall_set_form_element_event_handler(void * bidak,long document_id,long ksunt_id,long type,unsigned char * name)2307 void js_upcall_set_form_element_event_handler(void *bidak, long document_id, long ksunt_id, long type, unsigned char *name)
2308 {
2309 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2310 struct f_data_c *fd;
2311 struct hopla_mladej *hopla;
2312 int i;
2313
2314 if (!js_ctx)internal_error("js_upcall_set_form_element_event_handler called with NULL context pointer\n");
2315 fd=jsint_find_document(document_id);
2316 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
2317 if ((ksunt_id&JS_OBJ_MASK) == JS_OBJ_T_FRAME || (ksunt_id&JS_OBJ_MASK) == JS_OBJ_T_DOCUMENT) {
2318 unsigned char **p = get_js_event_ptr(&fd->f_data->js_event, type);
2319 if (!p) {
2320 mem_free(name);
2321 return;
2322 }
2323 if (*p) mem_free(*p);
2324 *p = name;
2325 fd->f_data->uncacheable=1;
2326 return;
2327 }
2328 hopla=jsint_find_object(fd,ksunt_id);
2329 if (!hopla){if (name)mem_free(name);return;}
2330 for (i = 0; i < fd->f_data->nlinks; i++) {
2331 struct link *l = &fd->f_data->links[i];
2332 if (l->form == hopla->fc) {
2333 unsigned char **p = get_js_event_ptr(&l->js_event, type);
2334 mem_free(hopla);
2335 if (!p) {
2336 mem_free(name);
2337 return;
2338 }
2339 if (*p) mem_free(*p);
2340 *p = name;
2341 fd->f_data->uncacheable=1;
2342 return;
2343 }
2344 }
2345 mem_free(hopla);
2346 mem_free(name);
2347 }
2348
2349
2350 /* returns allocated string with actual value of password, text or textarea element
2351 * on error returns NULL
2352 * don't forget to free the string after use
2353 */
js_upcall_get_form_element_value(void * bidak,long document_id,long ksunt_id)2354 unsigned char *js_upcall_get_form_element_value(void *bidak, long document_id, long ksunt_id)
2355 {
2356 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2357 struct f_data_c *fd;
2358 struct hopla_mladej *hopla;
2359 unsigned char *hele_ho_bidaka;
2360
2361 if (!js_ctx)internal_error("js_upcall_get_form_element_value called with NULL context pointer\n");
2362 fd=jsint_find_document(document_id);
2363 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
2364
2365 switch (ksunt_id&JS_OBJ_MASK)
2366 {
2367 case JS_OBJ_T_TEXT:
2368 case JS_OBJ_T_PASSWORD:
2369 case JS_OBJ_T_TEXTAREA:
2370 break;
2371
2372 default:
2373 return NULL; /* To neni Jim Beam! */
2374 }
2375
2376 hopla=jsint_find_object(fd,ksunt_id);
2377 if (!hopla)return NULL;
2378
2379 hele_ho_bidaka=convert(fd->f_data->opt.cp, fd->f_data->cp, hopla->fs->string, NULL);
2380
2381 mem_free(hopla);
2382 return hele_ho_bidaka;
2383 }
2384
2385
2386 /* sets actual value of password, text or textarea element
2387 * name is allocated string that, this function frees it
2388 * when name is NULL default value will be empty
2389 */
js_upcall_set_form_element_value(void * bidak,long document_id,long ksunt_id,unsigned char * name)2390 void js_upcall_set_form_element_value(void *bidak, long document_id, long ksunt_id, unsigned char *name)
2391 {
2392 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2393 struct f_data_c *fd;
2394 struct hopla_mladej *hopla;
2395
2396 if (!js_ctx)internal_error("js_upcall_set_form_element_value called with NULL context pointer\n");
2397 fd=jsint_find_document(document_id);
2398 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
2399
2400 fd=jsint_find_document(document_id);
2401
2402 switch (ksunt_id&JS_OBJ_MASK)
2403 {
2404 case JS_OBJ_T_TEXT:
2405 case JS_OBJ_T_PASSWORD:
2406 case JS_OBJ_T_TEXTAREA:
2407 break;
2408
2409 default:
2410 if (name)mem_free(name);
2411 return; /* To neni Jim Beam! */
2412 }
2413
2414 hopla=jsint_find_object(fd,ksunt_id);
2415 if (!hopla){if (name)mem_free(name);return;}
2416
2417 free_format_text_cache_entry(hopla->fs);
2418 mem_free(hopla->fs->string);
2419 hopla->fs->string=convert(fd->f_data->cp, fd->f_data->opt.cp, name, NULL);
2420
2421 if ((size_t)hopla->fs->state > strlen(cast_const_char hopla->fs->string))
2422 hopla->fs->state = strlen(cast_const_char hopla->fs->string);
2423 if ((ksunt_id&JS_OBJ_MASK) != JS_OBJ_T_TEXTAREA) {
2424 if ((size_t)hopla->fs->vpos > strlen(cast_const_char hopla->fs->string))
2425 hopla->fs->vpos = strlen(cast_const_char hopla->fs->string);
2426 }
2427 mem_free(hopla);
2428 if (name)mem_free(name);
2429 redraw_document(fd);
2430 }
2431
2432
2433 /* emulates click on everything */
js_upcall_click(void * bidak,long document_id,long elem_id)2434 void js_upcall_click(void *bidak, long document_id, long elem_id)
2435 {
2436 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2437 struct f_data_c *fd;
2438
2439 if (!js_ctx)internal_error("js_upcall_click called with NULL context pointer\n");
2440 fd=jsint_find_document(document_id);
2441 if (!fd||!jsint_can_access(js_ctx,fd))return;
2442
2443 switch (elem_id&JS_OBJ_MASK)
2444 {
2445 case JS_OBJ_T_CHECKBOX:
2446 case JS_OBJ_T_RADIO:
2447 case JS_OBJ_T_SUBMIT:
2448 case JS_OBJ_T_RESET:
2449 case JS_OBJ_T_BUTTON:
2450 {
2451 struct hopla_mladej *hopla;
2452 int a;
2453 struct link *l;
2454
2455 if (!fd->f_data)return;
2456 hopla=jsint_find_object(fd,elem_id);
2457 if (!hopla)return;
2458
2459 for (a=0;a<fd->f_data->nlinks;a++)
2460 {
2461 l=&(fd->f_data->links[a]);
2462 if (l->form&&l->form==hopla->fc) /* to je on! */
2463 {
2464 int old_link=fd->vs->current_link;
2465 int old_orig_link=fd->vs->orig_link;
2466 fd->vs->current_link=a;
2467 fd->vs->orig_link=a;
2468 enter(fd->ses,fd,0);
2469 draw_fd(fd);
2470 fd->vs->current_link=old_link;
2471 fd->vs->orig_link=old_orig_link;
2472 change_screen_status(fd->ses);
2473 print_screen_status(fd->ses);
2474 break;
2475 }
2476 }
2477 mem_free(hopla);
2478 }
2479 break;
2480 }
2481 }
2482
2483 #ifdef G
2484 static int find_go_link_num;
2485 static struct g_object *to_je_on_bidak;
find_go(struct g_object * p,struct g_object * c)2486 static void find_go(struct g_object *p, struct g_object *c)
2487 {
2488 if (c->draw == g_text_draw) {
2489 struct g_object_text *t = get_struct(c, struct g_object_text, goti.go);
2490 if (t->goti.link_num==find_go_link_num){to_je_on_bidak=c;return;}
2491 }
2492 if (c->get_list) c->get_list(c, find_go);
2493 }
2494 #endif
2495
2496 /* emulates focus on password, text and textarea */
js_upcall_focus(void * bidak,long document_id,long elem_id)2497 void js_upcall_focus(void *bidak, long document_id, long elem_id)
2498 {
2499 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2500 struct f_data_c *fd;
2501
2502 if (!js_ctx)internal_error("js_upcall_focus called with NULL context pointer\n");
2503 fd=jsint_find_document(document_id);
2504 if (!fd||!jsint_can_access(js_ctx,fd))return;
2505
2506 switch (elem_id&JS_OBJ_MASK)
2507 {
2508 case JS_OBJ_T_TEXT:
2509 case JS_OBJ_T_PASSWORD:
2510 case JS_OBJ_T_TEXTAREA:
2511 {
2512 struct hopla_mladej *hopla;
2513 int a;
2514 struct link *l;
2515
2516 if (!fd->f_data)return;
2517 hopla=jsint_find_object(fd,elem_id);
2518 if (!hopla)return;
2519
2520 for (a=0;a<fd->f_data->nlinks;a++)
2521 {
2522 l=&(fd->f_data->links[a]);
2523 if (l->form&&l->form==hopla->fc) /* to je on! */
2524 {
2525 struct session *ses = fd->ses;
2526 /*int x = 0;*/
2527 while (fd != current_frame(ses)) next_frame(ses, 1)/*, x = 1*/;
2528 fd->vs->current_link=a;
2529 fd->vs->orig_link=a;
2530 if (fd->ses->term->spec->braille) {
2531 if (fd->f_data->links[a].n) {
2532 fd->vs->brl_x = fd->vs->orig_brl_x = fd->f_data->links[a].pos[0].x;
2533 fd->vs->brl_y = fd->vs->orig_brl_y = fd->f_data->links[a].pos[0].y;
2534 }
2535 }
2536 #ifdef G
2537 if (F)
2538 {
2539 fd->ses->locked_link=1;
2540 to_je_on_bidak=NULL;
2541 find_go_link_num=a;
2542
2543 /* tak tedka tu budu carovat g_object_text, kterej patri k tomuhle linku */
2544 if (fd->f_data->root->get_list)fd->f_data->root->get_list(fd->f_data->root,find_go);
2545 fd->f_data->locked_on=to_je_on_bidak;
2546 }
2547 #endif
2548 if (l->js_event&&l->js_event->focus_code)
2549 jsint_execute_code(fd,l->js_event->focus_code,strlen(cast_const_char l->js_event->focus_code),-1,-1,-1, NULL);
2550
2551 /*draw_fd(fd);*/
2552 draw_formatted(ses);
2553 change_screen_status(fd->ses);
2554 print_screen_status(fd->ses);
2555 break;
2556 }
2557 }
2558 mem_free(hopla);
2559 }
2560 break;
2561 }
2562 }
2563
2564 /* emulates focus on password, text and textarea */
js_upcall_blur(void * bidak,long document_id,long elem_id)2565 void js_upcall_blur(void *bidak, long document_id, long elem_id)
2566 {
2567 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2568 struct f_data_c *fd;
2569
2570 if (!js_ctx)internal_error("js_upcall_blur called with NULL context pointer\n");
2571 fd=jsint_find_document(document_id);
2572 if (!fd||!jsint_can_access(js_ctx,fd))return;
2573
2574 /* in text mode do nothing, because we don't know where to go with cursor */
2575 #ifdef G
2576 if (F)
2577 switch (elem_id&JS_OBJ_MASK)
2578 {
2579 case JS_OBJ_T_TEXT:
2580 case JS_OBJ_T_PASSWORD:
2581 case JS_OBJ_T_TEXTAREA:
2582 {
2583 struct hopla_mladej *hopla;
2584 int a;
2585 struct link *l;
2586
2587 if (!fd->f_data)return;
2588 hopla=jsint_find_object(fd,elem_id);
2589 if (!hopla)return;
2590
2591 for (a=0;a<fd->f_data->nlinks;a++)
2592 {
2593 l=&(fd->f_data->links[a]);
2594 if (l->form&&l->form==hopla->fc) /* to je on! */
2595 {
2596 fd->ses->locked_link=0;
2597 if (l->js_event&&l->js_event->blur_code)
2598 jsint_execute_code(fd,l->js_event->blur_code,strlen(cast_const_char l->js_event->blur_code),-1,-1,-1, NULL);
2599
2600 /* pro jistotu */
2601 draw_fd(fd);
2602 change_screen_status(fd->ses);
2603 print_screen_status(fd->ses);
2604 break;
2605 }
2606 }
2607 mem_free(hopla);
2608 }
2609 break;
2610 }
2611 #endif
2612 }
2613
2614 /* emulates submit of a form */
js_upcall_submit(void * bidak,long document_id,long form_id)2615 void js_upcall_submit(void *bidak, long document_id, long form_id)
2616 {
2617 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2618 struct f_data_c *fd;
2619 struct form_control *form;
2620 int has_onsubmit;
2621 unsigned char *u;
2622
2623 if (!js_ctx)internal_error("js_upcall_submit called with NULL context pointer\n");
2624 fd=jsint_find_document(document_id);
2625 if (!fd||!jsint_can_access(js_ctx,fd))return;
2626
2627 if (fd->ses->rq && fd->ses->defered_url) return;
2628
2629 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return;
2630 form=jsint_find_object(fd,form_id);
2631 if (!form)return;
2632
2633 u=get_form_url(fd->ses,fd,form,&has_onsubmit);
2634 if (u) {
2635 goto_url_f(fd->ses,NULL,u,NULL,fd,form->form_num, has_onsubmit,0,0);
2636 mem_free(u);
2637 }
2638 draw_fd(fd);
2639 change_screen_status(fd->ses);
2640 print_screen_status(fd->ses);
2641 }
2642
2643
2644 /* emulates reset of a form */
js_upcall_reset(void * bidak,long document_id,long form_id)2645 void js_upcall_reset(void *bidak, long document_id, long form_id)
2646 {
2647 struct f_data_c *js_ctx=(struct f_data_c*)bidak;
2648 struct f_data_c *fd;
2649
2650 if (!js_ctx)internal_error("js_upcall_reset called with NULL context pointer\n");
2651 fd=jsint_find_document(document_id);
2652 if (!fd||!jsint_can_access(js_ctx,fd))return;
2653 if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return;
2654 if (!fd->f_data)return;
2655
2656 reset_form(fd,form_id>>JS_OBJ_MASK_SIZE);
2657 draw_fd(fd);
2658 change_screen_status(fd->ses);
2659 print_screen_status(fd->ses);
2660 }
2661
2662 /* returns length (number of radio buttons) of a radio
2663 * on error returns -1
2664 */
js_upcall_get_radio_length(void * p,long document_id,long radio_id)2665 int js_upcall_get_radio_length(void *p, long document_id, long radio_id)
2666 {
2667 struct f_data_c *js_ctx=(struct f_data_c*)p;
2668 struct f_data_c *fd;
2669 struct form_control *f;
2670 struct list_head *lf;
2671 struct hopla_mladej *hopla;
2672 struct form_control *radio;
2673 int count=0;
2674
2675 if (!js_ctx)internal_error("js_upcall_get_radio_length called with NULL context pointer\n");
2676 if ((radio_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO) return -1;
2677 fd=jsint_find_document(document_id);
2678 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return -1;
2679
2680 hopla=jsint_find_object(fd,radio_id);
2681 if (!hopla)return -1;
2682 radio=hopla->fc;
2683
2684 /* find form elements with the same type, form_num (belonging to the same form) and name */
2685 foreachback(struct form_control, f, lf, fd->f_data->forms)
2686 if (f->type==radio->type&&f->form_num==radio->form_num&&!strcmp(cast_const_char radio->name,cast_const_char f->name))count++;
2687 mem_free(hopla);
2688 return count;
2689 }
2690
2691 /* returns number of items in a select form element
2692 * on error returns -1
2693 */
js_upcall_get_select_length(void * p,long document_id,long select_id)2694 int js_upcall_get_select_length(void *p, long document_id, long select_id)
2695 {
2696 int l;
2697 struct f_data_c *js_ctx=(struct f_data_c*)p;
2698 struct f_data_c *fd;
2699 struct hopla_mladej *hopla;
2700
2701 if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
2702 if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return -1;
2703 fd=jsint_find_document(document_id);
2704 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
2705
2706 hopla=jsint_find_object(fd,select_id);
2707 if (!hopla)return -1;
2708
2709 l = hopla->fc->nvalues;
2710 mem_free(hopla);
2711 return l;
2712 }
2713
2714
2715 /* returns allocated field of select items
2716 * don't forget to free: text and value of each item and the field
2717 * on error returns NULL
2718 * n is number of items in the field
2719 */
js_upcall_get_select_options(void * p,long document_id,long select_id,int * n)2720 struct js_select_item* js_upcall_get_select_options(void *p, long document_id, long select_id, int *n)
2721 {
2722 struct f_data_c *js_ctx=(struct f_data_c*)p;
2723 struct f_data_c *fd;
2724 struct hopla_mladej *hopla;
2725 struct js_select_item* elektricke_pole;
2726 int ukazme_si_na_nej;
2727
2728 *n=0;
2729 if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
2730 if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return NULL;
2731 fd=jsint_find_document(document_id);
2732 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
2733
2734 hopla=jsint_find_object(fd,select_id);
2735 if (!hopla)return NULL;
2736
2737 *n=hopla->fc->nvalues;
2738 if ((unsigned)*n > MAXINT / sizeof(struct js_select_item)) overalloc();
2739 elektricke_pole=mem_alloc((*n)*sizeof(struct js_select_item));
2740
2741 for (ukazme_si_na_nej=0;ukazme_si_na_nej<(*n);ukazme_si_na_nej++)
2742 {
2743 elektricke_pole[ukazme_si_na_nej].text=stracpy((hopla->fc->labels)[ukazme_si_na_nej]);
2744 elektricke_pole[ukazme_si_na_nej].value=stracpy((hopla->fc->values)[ukazme_si_na_nej]);
2745 elektricke_pole[ukazme_si_na_nej].selected=(ukazme_si_na_nej==(hopla->fs->state));
2746 elektricke_pole[ukazme_si_na_nej].default_selected=(ukazme_si_na_nej==(hopla->fc->default_state));
2747 }
2748 mem_free(hopla);
2749 return elektricke_pole;
2750 }
2751
2752 /* returns index of just selected item in a select form element
2753 * on error returns -1
2754 */
js_upcall_get_select_index(void * p,long document_id,long select_id)2755 int js_upcall_get_select_index(void *p, long document_id, long select_id)
2756 {
2757 struct f_data_c *js_ctx=(struct f_data_c*)p;
2758 struct f_data_c *fd;
2759 struct hopla_mladej *hopla;
2760 int l;
2761
2762 if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
2763 if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return -1;
2764 fd=jsint_find_document(document_id);
2765 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
2766
2767 hopla=jsint_find_object(fd,select_id);
2768 if (!hopla)return -1;
2769
2770 l = hopla->fs->state;
2771 mem_free(hopla);
2772 return l;
2773 }
2774
2775
2776 struct gimme_js_id_string
2777 {
2778 long id;
2779 long js_id;
2780 unsigned char *string;
2781 int n;
2782 };
2783
2784 /* open a link in a new xterm */
send_vodevri_v_novym_vokne(struct terminal * term,void * open_window_,void * ses_)2785 static void send_vodevri_v_novym_vokne(struct terminal *term, void *open_window_, void *ses_)
2786 {
2787 int (*open_window)(struct terminal *, unsigned char *, unsigned char *) = *(int (* const *)(struct terminal *, unsigned char *, unsigned char *))open_window_;
2788 struct session *ses = (struct session *)ses_;
2789 if (ses->dn_url) {
2790 unsigned char *enc_url = encode_url(ses->dn_url);
2791 open_window(term, path_to_exe, enc_url);
2792 mem_free(enc_url);
2793 }
2794 }
2795
2796 static void (* const send_vodevri_v_novym_vokne_ptr)(struct terminal *term, void *open_window_, void *ses_) = send_vodevri_v_novym_vokne;
2797
2798 /* aux function for js_upcall_goto_url */
js_upcall_goto_url_ok_pressed(void * data)2799 static void js_upcall_goto_url_ok_pressed(void *data)
2800 {
2801 struct f_data_c *fd;
2802 struct gimme_js_id_string *jsid=(struct gimme_js_id_string*)data;
2803
2804 fd=jsint_find_document(jsid->id);
2805 if (!fd)return; /* context no longer exists */
2806
2807 /* it doesn't matter, that fd->js is NULL */
2808 if (jsid->n&&can_open_in_new(fd->ses->term)) /* open in new window */
2809 {
2810 if (fd->ses->dn_url) mem_free(fd->ses->dn_url);
2811 fd->ses->dn_url=stracpy(jsid->string);
2812 open_in_new_window(fd->ses->term, (void *)&send_vodevri_v_novym_vokne_ptr, fd->ses);
2813 }
2814 else
2815 goto_url(fd->ses,jsid->string);
2816
2817 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
2818 js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
2819 }
2820
2821
2822 /* aux function for js_upcall_goto_url */
js_upcall_goto_url_cancel_pressed(void * data)2823 static void js_upcall_goto_url_cancel_pressed(void *data)
2824 {
2825 struct f_data_c *fd;
2826 struct gimme_js_id *jsid=(struct gimme_js_id*)data;
2827
2828 fd=jsint_find_document(jsid->id);
2829 if (!fd)return; /* context no longer exists */
2830
2831 if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
2832 js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
2833 }
2834
2835
2836 /* gets struct fax_me_tender_int_string */
2837 /* asks user whether to go to the url or not */
2838 /* structure and the text are both deallocated */
2839 /* must be called from select loop */
2840 /* if num in fax_me_tender_int_string is not null, open in a new window */
js_upcall_goto_url(void * data)2841 void js_upcall_goto_url(void * data)
2842 {
2843 struct fax_me_tender_int_string *s=(struct fax_me_tender_int_string*)data;
2844 struct f_data_c *fd;
2845 struct terminal *term;
2846 unsigned char *dest_url;
2847 int in_new_win;
2848
2849 fd=(struct f_data_c*)(s->ident);
2850 term=fd->ses->term;
2851
2852 if (!fd->js) return;
2853
2854 /* kill timer, that called me */
2855 js_spec_vykill_timer(fd->js->ctx,0);
2856
2857 if (!s)internal_error("js_upcall_goto_url called with NULL pointer\n");
2858
2859 if (!s->string){js_mem_free(data);goto goto_url_failed;}
2860 if (fd->loc&&fd->loc->url) dest_url=join_urls(fd->loc->url,s->string);
2861 else dest_url=stracpy(s->string);
2862 if (!(dest_url)){js_mem_free(s->string);js_mem_free(data);goto goto_url_failed;}
2863 js_mem_free(s->string);
2864 in_new_win=s->num;
2865
2866 if (js_manual_confirmation)
2867 {
2868 struct gimme_js_id_string* jsid;
2869
2870 /* goto the same url */
2871 {
2872 unsigned char txt[MAX_STR_LEN];
2873 void *p;
2874
2875 p=get_current_url(fd->ses,txt,MAX_STR_LEN);
2876 if (p&&fd->loc&&fd->loc->url&&!strcmp(cast_const_char txt,cast_const_char dest_url))
2877 {
2878 mem_free(dest_url);
2879 js_mem_free(data);
2880 goto goto_url_failed;
2881 }
2882 }
2883
2884 jsid=mem_alloc(sizeof(struct gimme_js_id_string));
2885
2886 /* context must be a valid pointer ! */
2887 /* fill in jsid */
2888 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
2889 jsid->js_id=fd->js->ctx->js_id;
2890 jsid->string=dest_url;
2891 jsid->n=s->num;
2892
2893 msg_box(
2894 term, /* terminal */
2895 getml(jsid->string,jsid,NULL), /* memory blocks to free */
2896 TEXT_(T_GOTO_URL), /* title */
2897 AL_CENTER, /* alignment */
2898 jsid->n?TEXT_(T_JS_IS_ATTEMPTING_TO_OPEN_NEW_WINDOW_WITH_URL):TEXT_(T_JS_IS_ATTEMPTING_TO_GO_TO_URL), " \"",jsid->string,"\".",MSG_BOX_END, /* message */
2899 (void *)jsid, /* data for button functions */
2900 3, /* # of buttons */
2901 TEXT_(T_ALLOW),js_upcall_goto_url_ok_pressed,B_ENTER,
2902 TEXT_(T_REJECT),js_upcall_goto_url_cancel_pressed,B_ESC,
2903 TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL /* dirty trick: gimme_js_id_string and gimme_js_id begins with the same long */
2904 );
2905 js_mem_free(s);
2906 }
2907 else
2908 {
2909 js_mem_free(s);
2910 if (in_new_win&&can_open_in_new(fd->ses->term)) /* open in new window */
2911 {
2912 if (fd->ses->dn_url) mem_free(fd->ses->dn_url);
2913 fd->ses->dn_url=stracpy(dest_url);
2914 open_in_new_window(fd->ses->term, (void *)&send_vodevri_v_novym_vokne_ptr, fd->ses);
2915 }
2916 else
2917 goto_url(fd->ses,dest_url);
2918 js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
2919 mem_free(dest_url);
2920 }
2921 return;
2922
2923 goto_url_failed:
2924 js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
2925 return;
2926 }
2927
2928
2929 /* returns number of items in history */
js_upcall_get_history_length(void * context)2930 int js_upcall_get_history_length(void *context)
2931 {
2932 struct f_data_c *fd=(struct f_data_c*)context;
2933
2934 if (!fd)internal_error("PerMe, PerMe, ja si te podam!\n");
2935
2936 return (int)list_size(&fd->ses->history);
2937 }
2938
2939
2940 /* aux function for js_upcall_goto_history */
js_upcall_goto_history_ok_pressed(void * data)2941 static void js_upcall_goto_history_ok_pressed(void *data)
2942 {
2943 struct f_data_c *fd;
2944 struct gimme_js_id_string *jsid=(struct gimme_js_id_string*)data;
2945 int a;
2946
2947 fd=jsint_find_document(jsid->id);
2948 if (!fd)return; /* context no longer exists */
2949
2950 a = (int)list_size(&fd->ses->history);
2951
2952 if (a<jsid->n&&(fd->js)&&jsid->js_id==fd->js->ctx->js_id){js_downcall_vezmi_null(fd->js->ctx);return;} /* call downcall */
2953
2954 go_backwards(fd->ses->term,(void*)(my_intptr_t)(jsid->n),fd->ses);
2955 }
2956
2957
2958 /* gets struct fax_me_tender_int_string
2959 * either num or string is set, but not both, the other must be NULL
2960 * asks user whether to go to the url or not
2961 * structure and the text are both deallocated
2962 * must be called from select loop
2963 * number can be:
2964 * >0 go forward in history (not supported)
2965 * 0 do nothing (means use string)
2966 * <0 go backward in history (supported :) )
2967 * if string is defined - find appropriate history item and go to the url, when
2968 * the URL doesn't exist do nothing
2969 *
2970 * JAK TO FUNGUJE:
2971 * string se prekonvertuje na cislo (projde se historie)
2972 * po zmacknuti OK se spocita delka historie a pokud je dostatecna, n-krat
2973 * zavola go_back. Pokud neni, tak se chovame jako pri cancelu.
2974 */
2975
js_upcall_goto_history(void * data)2976 void js_upcall_goto_history(void * data)
2977 {
2978 struct fax_me_tender_int_string *s=(struct fax_me_tender_int_string*)data;
2979 struct f_data_c *fd;
2980 struct terminal *term;
2981 unsigned char *url=NULL;
2982 unsigned char txt[16];
2983 long history_num=0;
2984
2985 /* context must be a valid pointer ! */
2986 fd=(struct f_data_c*)(s->ident);
2987
2988 if (!fd->js) return;
2989
2990 /* kill timer, that called me */
2991 js_spec_vykill_timer(fd->js->ctx,0);
2992
2993 if (!s)internal_error("Hele, tyhle prasarny si zkousej na nekoho jinyho, jo?!\n");
2994 if (!(s->num)&&!(s->string))internal_error("Tak tohle na mne nezkousej, bidaku!\n");
2995 if ((s->num)&&(s->string))internal_error("Ta sedla!\n");
2996
2997 /* find the history item */
2998 if (s->num) /* goto n-th item */
2999 {
3000 struct location *loc;
3001 struct list_head *lloc;
3002 int a=0;
3003
3004 if ((s->num)>0){if (s->string)js_mem_free(s->string);js_mem_free(data);goto goto_history_failed;} /* forward not supported */
3005 s->num=-s->num;
3006 history_num=s->num;
3007
3008 foreach(struct location, loc, lloc, fd->ses->history) {
3009 if (a==s->num){url=stracpy(loc->url);break;}
3010 a++;
3011 }
3012 }
3013 else /* goto given url */
3014 {
3015 struct location *loc;
3016 struct list_head *lloc;
3017 int a=0;
3018
3019 foreach(struct location, loc, lloc, fd->ses->history) {
3020 if (!strcmp(cast_const_char s->string,cast_const_char loc->url)){url=stracpy(s->string);history_num=a;break;}
3021 a++;
3022 }
3023 }
3024
3025 if (s->string)js_mem_free(s->string);
3026 if (!url){js_mem_free(data);goto goto_history_failed;}
3027
3028 term=fd->ses->term;
3029
3030 if (js_manual_confirmation)
3031 {
3032 struct gimme_js_id_string* jsid;
3033
3034 jsid=mem_alloc(sizeof(struct gimme_js_id_string));
3035
3036 /* fill in jsid */
3037 jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
3038 jsid->js_id=fd->js->ctx->js_id;
3039 jsid->string=url;
3040 jsid->n=history_num;
3041
3042 snprintf(txt,16," (-%d) ",jsid->n);
3043 msg_box(
3044 term, /* terminal */
3045 getml(url,jsid,NULL), /* memory blocks to free */
3046 TEXT_(T_GOTO_HISTORY), /* title */
3047 AL_CENTER, /* alignment */
3048 TEXT_(T_JS_IS_ATTEMPTING_TO_GO_INTO_HISTORY), txt, TEXT_(T_TO_URL), " \"",url,"\".",MSG_BOX_END, /* message */
3049 (void *)jsid, /* data for button functions */
3050 3, /* # of buttons */
3051 TEXT_(T_ALLOW),js_upcall_goto_history_ok_pressed,B_ENTER,
3052 TEXT_(T_REJECT),js_upcall_goto_url_cancel_pressed,B_ESC,
3053 TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL /* dirty trick: gimme_js_id_string and gimme_js_id begins with the same long */
3054 );
3055 js_mem_free(s);
3056 }
3057 else
3058 {
3059 js_mem_free(s);
3060 mem_free(url);
3061 go_backwards(term,(void*)(history_num),fd->ses);
3062 }
3063 return;
3064 goto_history_failed:
3065 js_downcall_vezmi_null(fd->js->ctx);
3066 return;
3067 }
3068
3069
3070 /* set default status-line text
3071 * tak_se_ukaz_Kolbene is allocated string or NULL
3072 */
js_upcall_set_default_status(void * context,unsigned char * tak_se_ukaz_Kolbene)3073 void js_upcall_set_default_status(void *context, unsigned char *tak_se_ukaz_Kolbene)
3074 {
3075 struct f_data_c *fd=(struct f_data_c*)context;
3076 unsigned char *trouba;
3077
3078 if (!fd)internal_error("Tak tohle teda ne, bobanku!\n");
3079
3080 if (!(*tak_se_ukaz_Kolbene)){mem_free(tak_se_ukaz_Kolbene);tak_se_ukaz_Kolbene=NULL;} /* Ale to hlavni jsme se nedozvedeli - s tim chrapanim jste mi neporadil... */
3081
3082 if (fd->ses->default_status)mem_free(fd->ses->default_status);
3083 skip_nonprintable(tak_se_ukaz_Kolbene);
3084 if (fd->f_data&&tak_se_ukaz_Kolbene)
3085 {
3086 /* ... a ted ty pochybne reci o majetku ... */
3087 trouba=convert(fd->f_data->cp, fd->f_data->opt.cp, tak_se_ukaz_Kolbene, NULL); /* Taky to mate levnejsi - jinak by to stalo deset! */
3088 mem_free(tak_se_ukaz_Kolbene);
3089 /* a je to v troube... */
3090 }
3091 else
3092 {
3093 trouba=tak_se_ukaz_Kolbene;
3094 }
3095
3096 fd->ses->default_status=trouba;
3097 change_screen_status(fd->ses);
3098 print_screen_status(fd->ses);
3099 }
3100
3101
3102 /* returns allocated string with default status-line value or NULL when default value is empty
3103 */
js_upcall_get_default_status(void * context)3104 unsigned char* js_upcall_get_default_status(void *context)
3105 {
3106 struct f_data_c *fd=(struct f_data_c *)context;
3107 unsigned char *tak_se_ukaz_Danku=NULL;
3108 unsigned char *trouba;
3109
3110 if (!fd)internal_error("Ale hovno!\n");
3111
3112 if (fd->ses->default_status&&(*fd->ses->default_status))tak_se_ukaz_Danku=stracpy(fd->ses->default_status);
3113 skip_nonprintable(tak_se_ukaz_Danku);
3114 if (fd->f_data&&tak_se_ukaz_Danku)
3115 {
3116 trouba=convert(fd->f_data->opt.cp, fd->f_data->cp, tak_se_ukaz_Danku, NULL);
3117 mem_free(tak_se_ukaz_Danku);
3118 }
3119 else
3120 {
3121 trouba=tak_se_ukaz_Danku;
3122 }
3123
3124 /* Tak to mame Kolben a Danek po peti korunach... */
3125
3126 return trouba; /* No jo, je to v troube! */
3127 }
3128
3129
3130 /* set status-line text
3131 * tak_se_ukaz_Kolbene is allocated string or NULL
3132 */
js_upcall_set_status(void * context,unsigned char * tak_se_ukaz_Kolbene)3133 void js_upcall_set_status(void *context, unsigned char *tak_se_ukaz_Kolbene)
3134 {
3135 struct f_data_c *fd=(struct f_data_c*)context;
3136 unsigned char *trouba;
3137
3138 if (!fd)internal_error("To leda tak -PRd!\n");
3139
3140 if (!(*tak_se_ukaz_Kolbene)){mem_free(tak_se_ukaz_Kolbene);tak_se_ukaz_Kolbene=NULL;}
3141
3142 if (fd->ses->st)mem_free(fd->ses->st);
3143 skip_nonprintable(tak_se_ukaz_Kolbene);
3144 if (fd->f_data&&tak_se_ukaz_Kolbene)
3145 {
3146 trouba=convert(fd->f_data->cp, fd->f_data->opt.cp, tak_se_ukaz_Kolbene, NULL);
3147 mem_free(tak_se_ukaz_Kolbene);
3148 /* a je to v troube... */
3149 }
3150 else
3151 {
3152 trouba=tak_se_ukaz_Kolbene;
3153 }
3154
3155 fd->ses->st=trouba;
3156 print_screen_status(fd->ses);
3157 }
3158
3159
3160 /* returns allocated string with default status-line value or NULL when default value is empty
3161 */
js_upcall_get_status(void * context)3162 unsigned char* js_upcall_get_status(void *context)
3163 {
3164 struct f_data_c *fd=(struct f_data_c *)context;
3165 unsigned char *tak_se_ukaz_Danku=NULL;
3166 unsigned char *trouba;
3167
3168 if (!fd)internal_error("To leda tak hovno!\n");
3169
3170 if (fd->ses->st&&(*fd->ses->st))tak_se_ukaz_Danku=stracpy(fd->ses->st);
3171 skip_nonprintable(tak_se_ukaz_Danku);
3172 if (fd->f_data&&tak_se_ukaz_Danku)
3173 {
3174 trouba=convert(fd->f_data->opt.cp, fd->f_data->cp, tak_se_ukaz_Danku, NULL);
3175 mem_free(tak_se_ukaz_Danku);
3176 }
3177 else
3178 {
3179 trouba=tak_se_ukaz_Danku;
3180 }
3181
3182 /* Kolben a Danek, to mame po peti korunach... */
3183
3184 return trouba;
3185 }
3186
3187 /* returns allocated string with cookies, or NULL on error */
js_upcall_get_cookies(void * context)3188 unsigned char * js_upcall_get_cookies(void *context)
3189 {
3190 struct f_data_c *fd=(struct f_data_c *)context;
3191 unsigned char *s=init_str();
3192 int l=0;
3193 int nc=0;
3194 time_t now;
3195 struct cookie *c;
3196 struct list_head *lc;
3197 unsigned char *server, *data;
3198 struct c_domain *cd;
3199 struct list_head *lcd;
3200
3201 if (!fd)internal_error("Tak tomu rikam selhani komunikace...\n");
3202
3203 /* zavolame set_cookies, ten zparsuje fd->js->ctx->cookies a necha tam nezparsovatelnej zbytek */
3204
3205 if (!fd->js||!fd->js->ctx) {mem_free(s);return NULL;}
3206 if (!fd->rq) goto ty_uz_se_nevratis;
3207
3208 jsint_set_cookies(fd,0);
3209
3210 server = get_host_name(fd->rq->url);
3211 data = get_url_data(fd->rq->url);
3212
3213 if (data > fd->rq->url) data--;
3214 foreach(struct c_domain, cd, lcd, c_domains) if (is_in_domain(cd->domain, server)) goto ok;
3215 mem_free(server);
3216 ty_uz_se_nevratis:
3217 if (fd->js->ctx->cookies)add_to_str(&s,&l,fd->js->ctx->cookies);
3218 else {mem_free(s);s=NULL;}
3219 return s;
3220 ok:
3221 now = get_absolute_seconds();
3222 foreach(struct cookie, c, lc, all_cookies) if (is_in_domain(c->domain, server)) if (is_path_prefix(c->path, data)) {
3223 if (cookie_expired(c, now)) {
3224 lc = lc->prev;
3225 del_from_list(c);
3226 free_cookie(c);
3227 continue;
3228 }
3229 if (c->secure) continue;
3230 if (!nc) nc = 1;
3231 else add_to_str(&s, &l, "; ");
3232 add_to_str(&s, &l, c->name);
3233 if (c->value) {
3234 add_to_str(&s, &l, "=");
3235 add_to_str(&s, &l, c->value);
3236 }
3237 }
3238
3239 if (!nc) {mem_free(s);s=NULL;}
3240 mem_free(server);
3241
3242 /* za strinzik sestaveny z vnitrni reprezentace susenek jeste prilepime nezparsovatelnej zbytek */
3243 if (fd->js->ctx->cookies)
3244 {
3245 if (!s)s=stracpy(fd->js->ctx->cookies);
3246 else {add_to_str(&s,&l,"; ");add_to_str(&s,&l,fd->js->ctx->cookies);}
3247 }
3248 /*debug("get_cookies: \"%s\"", s);*/
3249 return s;
3250 }
3251
3252 /* FIXME: document.all nechodi, musi se prepsat, aby vracel dvojice frame:idcko */
3253
3254
3255 /* adds all in given f_data_c, the f_data_c must be accessible by the javascript */
add_all_recursive_in_fd(long ** field,int * len,struct f_data_c * fd,struct f_data_c * js_ctx)3256 static void add_all_recursive_in_fd(long **field, int *len, struct f_data_c *fd, struct f_data_c *js_ctx)
3257 {
3258 struct f_data_c *ff;
3259 struct list_head *lff;
3260 struct form_control *fc;
3261 struct list_head *lfc;
3262
3263 /* add all accessible frames */
3264 foreach(struct f_data_c, ff, lff, fd->subframes)
3265 if (jsint_can_access(js_ctx,ff))
3266 if (!((*field)=add_fd_id(*field,len,js_upcall_get_frame_id(fd),js_upcall_get_frame_id(ff),ff->f_data?ff->f_data->opt.framename:NULL)))return;
3267
3268 if (!(fd->f_data))goto tady_uz_nic_peknyho_nebude;
3269
3270 #ifdef G
3271 /* add all images */
3272 if (F) {
3273 struct g_object_image *gi;
3274 struct list_head *lgi;
3275
3276 foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
3277 if (!((*field)=add_fd_id(*field,len,js_upcall_get_frame_id(fd),JS_OBJ_T_IMAGE+((gi->id)<<JS_OBJ_MASK_SIZE),gi->name)))return;
3278 }
3279 }
3280 #endif
3281 /* add all forms */
3282 foreachback(struct form_control, fc, lfc, fd->f_data->forms)
3283 if (!((*field)=add_fd_id(*field,len,js_upcall_get_frame_id(fd),((fc->form_num)<<JS_OBJ_MASK_SIZE)+JS_OBJ_T_FORM,fc->form_name)))return;
3284
3285 /* add all form elements */
3286 foreachback(struct form_control, fc, lfc, fd->f_data->forms)
3287 {
3288 long tak_mu_to_ukaz=0;
3289 tak_mu_to_ukaz=(fc->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
3290 switch (fc->type)
3291 {
3292 case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
3293 case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
3294 case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
3295 case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
3296 case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
3297 case FC_IMAGE:
3298 case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
3299 case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
3300 case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
3301 case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
3302 case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
3303 default:/* internal_error("Invalid form element type.\n"); */
3304 tak_mu_to_ukaz=0;break;
3305 }
3306 if (tak_mu_to_ukaz&&!((*field)=add_fd_id(*field,len,js_upcall_get_frame_id(fd),tak_mu_to_ukaz,fc->name)))return;
3307 }
3308
3309 tady_uz_nic_peknyho_nebude:
3310
3311 foreach(struct f_data_c, ff, lff, fd->subframes)
3312 if (jsint_can_access(js_ctx,ff)) add_all_recursive_in_fd(field,len,ff,js_ctx);
3313 }
3314
3315 /* returns allocated field of all objects in the document (document.all)
3316 * size of the field will be stored in len
3317 * the field has 3x more items than the number of objects
3318 * field[x+0]==id of frame
3319 * field[x+1]==id of the object
3320 * field[x+2]==allocated unsigned char* with name of the object or NULL (when there's no name)
3321 *
3322 * when an error occurs, returns NULL
3323 */
js_upcall_get_all(void * chuligane,long document_id,int * len)3324 long * js_upcall_get_all(void *chuligane, long document_id, int *len)
3325 {
3326 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3327 long *pole_neorane; /* Premysle Zavoraci, kde se flakas? Zase forbesis, co? */
3328 struct f_data_c *fd;
3329
3330 if (!js_ctx)internal_error("js_upcall_get_all called with NULL context pointer\n");
3331 fd=jsint_find_document(document_id);
3332 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
3333
3334 *len=0;
3335
3336 pole_neorane=mem_alloc(sizeof(long));
3337
3338 add_all_recursive_in_fd(&pole_neorane,len,fd,js_ctx);
3339
3340 /* nothing was found */
3341 if (!pole_neorane)return NULL;
3342 if (!(*len))mem_free(pole_neorane),pole_neorane=NULL;
3343
3344 return pole_neorane;
3345 }
3346
3347
3348 /* returns allocated field of all images
3349 * size of the field will be stored in len
3350 * when an error occurs, returns NULL
3351 */
3352
js_upcall_get_images(void * chuligane,long document_id,int * len)3353 long *js_upcall_get_images(void *chuligane, long document_id, int *len)
3354 {
3355 #ifdef G
3356 struct f_data_c *fd;
3357 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3358 long *pole_Premysla_Zavorace;
3359 int a;
3360
3361 if (F) {
3362 struct g_object_image *gi;
3363 struct list_head *lgi;
3364
3365 if (!js_ctx)internal_error("js_upcall_get_images called with NULL context pointer\n");
3366 fd=jsint_find_document(document_id);
3367 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
3368
3369 *len = list_size(&fd->f_data->images);
3370
3371 if (!(*len))return NULL;
3372
3373 if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
3374 pole_Premysla_Zavorace=mem_alloc((*len)*sizeof(long));
3375
3376 a=0;
3377 foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
3378 unsigned id = gi->id;;
3379 pole_Premysla_Zavorace[a]=JS_OBJ_T_IMAGE+(id<<JS_OBJ_MASK_SIZE);
3380 a++;
3381 }
3382 return pole_Premysla_Zavorace;
3383 } else
3384 #endif
3385 {
3386 document_id=document_id;
3387 *len=0;
3388 return NULL;
3389 }
3390 }
3391
3392 /* returns width of given image or -1 on error */
js_upcall_get_image_width(void * chuligane,long document_id,long image_id)3393 int js_upcall_get_image_width(void *chuligane, long document_id, long image_id)
3394 {
3395 #ifdef G
3396 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3397 struct f_data_c *fd;
3398 struct g_object_image *gi;
3399
3400 if (F)
3401 {
3402 if (!js_ctx)internal_error("js_upcall_get_image_width called with NULL context pointer\n");
3403 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3404 fd=jsint_find_document(document_id);
3405 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3406
3407 gi=jsint_find_object(fd,image_id);
3408
3409 if (!gi)return -1;
3410
3411 return gi->goti.go.xw;
3412 }else
3413 #endif
3414 {
3415 document_id=document_id;
3416 image_id=image_id;
3417 return -1;
3418 }
3419 }
3420
3421
3422 /* returns height of given image or -1 on error */
js_upcall_get_image_height(void * chuligane,long document_id,long image_id)3423 int js_upcall_get_image_height(void *chuligane, long document_id, long image_id)
3424 {
3425 #ifdef G
3426 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3427 struct f_data_c *fd;
3428 struct g_object_image *gi;
3429
3430 if (F)
3431 {
3432 if (!js_ctx)internal_error("js_upcall_get_image_height called with NULL context pointer\n");
3433 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3434 fd=jsint_find_document(document_id);
3435 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3436
3437 gi=jsint_find_object(fd,image_id);
3438
3439 if (!gi)return -1;
3440
3441 return gi->goti.go.yw;
3442 }else
3443 #endif
3444 {
3445 document_id=document_id;
3446 image_id=image_id;
3447 return -1;
3448 }
3449 }
3450
3451
3452 /* returns border of given image or -1 on error */
js_upcall_get_image_border(void * chuligane,long document_id,long image_id)3453 int js_upcall_get_image_border(void *chuligane, long document_id, long image_id)
3454 {
3455 #ifdef G
3456 struct f_data_c *fd;
3457 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3458 struct g_object_image *gi;
3459
3460 if (F)
3461 {
3462 if (!js_ctx)internal_error("js_upcall_get_image_border called with NULL context pointer\n");
3463 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3464 fd=jsint_find_document(document_id);
3465 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3466
3467 gi=jsint_find_object(fd,image_id);
3468
3469 if (!gi)return -1;
3470
3471 return gi->border;
3472 }else
3473 #endif
3474 {
3475 document_id=document_id;
3476 image_id=image_id;
3477 return -1;
3478 }
3479 }
3480
3481
3482 /* returns vspace of given image or -1 on error */
js_upcall_get_image_vspace(void * chuligane,long document_id,long image_id)3483 int js_upcall_get_image_vspace(void *chuligane, long document_id, long image_id)
3484 {
3485 #ifdef G
3486 struct f_data_c *fd;
3487 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3488 struct g_object_image *gi;
3489
3490 if (F)
3491 {
3492 if (!js_ctx)internal_error("js_upcall_get_image_vspace called with NULL context pointer\n");
3493 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3494 fd=jsint_find_document(document_id);
3495 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3496
3497 gi=jsint_find_object(fd,image_id);
3498
3499 if (!gi)return -1;
3500
3501 return gi->vspace;
3502 }else
3503 #endif
3504 {
3505 document_id=document_id;
3506 image_id=image_id;
3507 return -1;
3508 }
3509 }
3510
3511
3512 /* returns hspace of given image or -1 on error */
js_upcall_get_image_hspace(void * chuligane,long document_id,long image_id)3513 int js_upcall_get_image_hspace(void *chuligane, long document_id, long image_id)
3514 {
3515 #ifdef G
3516 struct f_data_c *fd;
3517 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3518 struct g_object_image *gi;
3519
3520 if (F)
3521 {
3522 if (!js_ctx)internal_error("js_upcall_get_image_hspace called with NULL context pointer\n");
3523 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3524 fd=jsint_find_document(document_id);
3525 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3526
3527 gi=jsint_find_object(fd,image_id);
3528
3529 if (!gi)return -1;
3530
3531 return gi->hspace;
3532 }else
3533 #endif
3534 {
3535 document_id=document_id;
3536 image_id=image_id;
3537 return -1;
3538 }
3539 }
3540
3541
3542 /* returns allocated string with name of given image or NULL on error */
js_upcall_get_image_name(void * chuligane,long document_id,long image_id)3543 unsigned char * js_upcall_get_image_name(void *chuligane, long document_id, long image_id)
3544 {
3545 #ifdef G
3546 struct f_data_c *fd;
3547 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3548 struct g_object_image *gi;
3549
3550 if (F)
3551 {
3552 if (!js_ctx)internal_error("js_upcall_get_image_name called with NULL context pointer\n");
3553 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
3554 fd=jsint_find_document(document_id);
3555 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
3556
3557 gi=jsint_find_object(fd,image_id);
3558
3559 if (!gi)return NULL;
3560
3561 return stracpy(gi->name);
3562 }else
3563 #endif
3564 {
3565 document_id=document_id;
3566 image_id=image_id;
3567 return NULL;
3568 }
3569 }
3570
3571
3572 /* returns allocated string with name of given image or NULL on error */
js_upcall_get_image_alt(void * chuligane,long document_id,long image_id)3573 unsigned char * js_upcall_get_image_alt(void *chuligane, long document_id, long image_id)
3574 {
3575 #ifdef G
3576 struct f_data_c *fd;
3577 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3578 struct g_object_image *gi;
3579
3580 if (F)
3581 {
3582 if (!js_ctx)internal_error("js_upcall_get_image_alt called with NULL context pointer\n");
3583 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
3584 fd=jsint_find_document(document_id);
3585 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
3586
3587 gi=jsint_find_object(fd,image_id);
3588
3589 if (!gi)return NULL;
3590
3591 return stracpy(gi->alt);
3592 }else
3593 #endif
3594 {
3595 chuligane=chuligane;
3596 document_id=document_id;
3597 image_id=image_id;
3598 return NULL;
3599 }
3600 }
3601
3602
3603 /* sets image name to given value */
3604 /* name is deallocated after use with mem_free */
js_upcall_set_image_name(void * chuligane,long document_id,long image_id,unsigned char * name)3605 void js_upcall_set_image_name(void *chuligane, long document_id, long image_id, unsigned char *name)
3606 {
3607 #ifdef G
3608 struct f_data_c *fd;
3609 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3610 struct g_object_image *gi;
3611
3612 if (F)
3613 {
3614 if (!js_ctx)internal_error("js_upcall_set_image_name called with NULL context pointer\n");
3615 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return;
3616 fd=jsint_find_document(document_id);
3617 if (!fd||!jsint_can_access(js_ctx,fd))return;
3618
3619 gi=jsint_find_object(fd,image_id);
3620
3621 if (!gi)return;
3622
3623 if (gi->name)mem_free(gi->name);
3624 gi->name=stracpy(name); /* radeji takhle, protoze to je bezpecnejsi: az PerM zase do neceho slapne, tak se to pozna hned tady a ne buhvikde */
3625 if (name)mem_free(name);
3626 return;
3627 }else
3628 #endif
3629 {
3630 chuligane=chuligane;
3631 document_id=document_id;
3632 image_id=image_id;
3633 if (name)mem_free(name);
3634 return;
3635 }
3636 }
3637
3638
3639 /* sets image alt to given value */
3640 /* alt is deallocated after use with mem_free */
js_upcall_set_image_alt(void * chuligane,long document_id,long image_id,unsigned char * alt)3641 void js_upcall_set_image_alt(void *chuligane, long document_id, long image_id, unsigned char *alt)
3642 {
3643 #ifdef G
3644 struct f_data_c *fd;
3645 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3646 struct g_object_image *gi;
3647
3648 if (F)
3649 {
3650 if (!js_ctx)internal_error("js_upcall_set_image_alt called with NULL context pointer\n");
3651 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return;
3652 fd=jsint_find_document(document_id);
3653 if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return;
3654
3655 gi=jsint_find_object(fd,image_id);
3656
3657 if (!gi)return;
3658
3659 if (gi->alt)mem_free(gi->alt);
3660 gi->alt=stracpy(alt); /* radeji takhle, protoze to je bezpecnejsi: az PerM zase do neceho slapne, tak se to pozna hned tady a ne buhvikde */
3661 if (fd->f_data&&gi->goti.link_num>=0&&gi->goti.link_num<fd->f_data->nlinks)
3662 {
3663 struct link *l=&fd->f_data->links[gi->goti.link_num];
3664
3665 if (l->img_alt)mem_free(l->img_alt);
3666 l->img_alt=stracpy(alt);
3667 }
3668 if (alt)mem_free(alt);
3669 change_screen_status(fd->ses);
3670 print_screen_status(fd->ses);
3671 return;
3672 }else
3673 #endif
3674 {
3675 chuligane=chuligane;
3676 document_id=document_id;
3677 image_id=image_id;
3678 if (alt)mem_free(alt);
3679 return;
3680 }
3681 }
3682
3683
3684 /* returns allocated string with source URL of given image or NULL on error */
js_upcall_get_image_src(void * chuligane,long document_id,long image_id)3685 unsigned char * js_upcall_get_image_src(void *chuligane, long document_id, long image_id)
3686 {
3687 #ifdef G
3688 struct f_data_c *fd;
3689 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3690 struct g_object_image *gi;
3691
3692 if (F)
3693 {
3694 if (!js_ctx)internal_error("js_upcall_get_image_src called with NULL context pointer\n");
3695 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
3696 fd=jsint_find_document(document_id);
3697 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
3698
3699 gi=jsint_find_object(fd,image_id);
3700
3701 if (!gi)return NULL;
3702
3703 return stracpy(gi->orig_src);
3704 }else
3705 #endif
3706 {
3707 document_id=document_id;
3708 image_id=image_id;
3709 return NULL;
3710 }
3711 }
3712
3713
3714 /* changes image URL
3715 * gets struct fax_me_tender_string_2_longy
3716 * num1 = document_id, num2 = image_id, string = url
3717 *
3718 * frees the string and the fax_me_tender struct with js_mem_free function
3719 */
js_upcall_set_image_src(void * chuligane)3720 void js_upcall_set_image_src(void *chuligane)
3721 {
3722 unsigned char *zvrat;
3723 struct fax_me_tender_string_2_longy *fax=(struct fax_me_tender_string_2_longy*)chuligane;
3724 struct f_data_c *js_ctx;
3725 #ifdef G
3726 struct f_data_c *fd;
3727 struct g_object_image *gi;
3728 long image_id,document_id;
3729 unsigned char *vecirek;
3730 if (F)
3731 {
3732 js_ctx=(struct f_data_c*)fax->ident;
3733 js_spec_vykill_timer(js_ctx->js->ctx,0);
3734 if (!chuligane)internal_error("js_upcall_set_image_src called with NULL argument\n");
3735 if (!js_ctx)internal_error("js_upcall_set_image_src called with NULL context pointer\n");
3736 image_id=fax->obj_id;
3737 document_id=fax->doc_id;
3738 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)goto abych_tu_nepovecerel;
3739 fd=jsint_find_document(document_id);
3740 if (!fd||!jsint_can_access(js_ctx,fd))goto abych_tu_nepovecerel;
3741
3742 gi=jsint_find_object(fd,image_id);
3743
3744 if (!gi||!fd->f_data)goto abych_tu_nepovecerel;
3745
3746 /* string joinnem s url */
3747 if (fd->f_data&&fd->f_data->script_href_base) vecirek=join_urls(fd->f_data->script_href_base,fax->string);
3748 else if (fd->loc&&fd->loc->url) vecirek=join_urls(fd->loc->url,fax->string);
3749 else vecirek=stracpy(fax->string);
3750 /* a mame to kompatidebilni s verzi pred jointem */
3751
3752 change_image(gi,vecirek,fax->string,fd->f_data);
3753 if (vecirek) mem_free(vecirek);
3754 fd->f_data->uncacheable = 1;
3755 abych_tu_nepovecerel:;
3756 }else
3757 #endif
3758 {
3759 js_ctx=(struct f_data_c*)fax->ident;
3760 if (!js_ctx)internal_error("js_upcall_set_image_src called with NULL context pointer\n");
3761 js_spec_vykill_timer(js_ctx->js->ctx,0);
3762 if (!chuligane)internal_error("js_upcall_set_image_src called with NULL argument\n");
3763 }
3764 zvrat=stracpy(fax->string);
3765 js_mem_free(fax->string);
3766 js_mem_free(fax);
3767 js_downcall_vezmi_string(js_ctx->js->ctx,zvrat);
3768 }
3769
3770
3771 /* returns 1 if image has completed loading, 0 when not, -1 on error */
js_upcall_image_complete(void * chuligane,long document_id,long image_id)3772 int js_upcall_image_complete(void *chuligane, long document_id, long image_id)
3773 {
3774 #ifdef G
3775 struct f_data_c *fd;
3776 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3777 struct g_object_image *gi;
3778
3779 if (F)
3780 {
3781 if (!js_ctx)internal_error("js_upcall_image_complete called with NULL context pointer\n");
3782 if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
3783 fd=jsint_find_document(document_id);
3784 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3785
3786 gi=jsint_find_object(fd,image_id);
3787
3788 if (!gi)return -1;
3789
3790 if (!gi->af||!gi->af->rq||!gi->af->rq->state)return -1;
3791 return gi->af->rq->state==O_OK;
3792 }else
3793 #endif
3794 {
3795 document_id=document_id;
3796 image_id=image_id;
3797 return -1;
3798 }
3799 }
3800
3801
3802 /* returns parent of given frame (or document), or -1 on error or no permissions */
3803 /* if frame_id is already top frame returns the same frame */
js_upcall_get_parent(void * chuligane,long frame_id)3804 long js_upcall_get_parent(void *chuligane, long frame_id)
3805 {
3806 struct f_data_c *fd, *ff;
3807 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3808
3809 if (!js_ctx)internal_error("js_upcall_get_parent called with NULL context pointer\n");
3810 if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return -1;
3811 fd=jsint_find_document(frame_id);
3812 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3813
3814 for (ff=fd->parent;ff&&!ff->rq;ff=ff->parent);
3815
3816 if (!ff)ff=fd->ses->screen;
3817 return jsint_can_access(fd,ff)?js_upcall_get_frame_id(ff):-1;
3818 }
3819
3820
3821 /* returns top of given frame (or document), or -1 on error */
3822 /* returns highest grandparent accessible from given frame */
js_upcall_get_frame_top(void * chuligane,long frame_id)3823 long js_upcall_get_frame_top(void *chuligane, long frame_id)
3824 {
3825 struct f_data_c *fd, *ff;
3826 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3827
3828 if (!js_ctx)internal_error("js_upcall_get_frame_top called with NULL context pointer\n");
3829 if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return -1;
3830 fd=jsint_find_document(frame_id);
3831 if (!fd||!jsint_can_access(js_ctx,fd))return -1;
3832 for (ff=fd->parent;ff;ff=ff->parent)
3833 {
3834 if (ff->rq)
3835 {
3836 if (!jsint_can_access(fd,ff))break;
3837 fd=ff;
3838 }
3839 }
3840 return js_upcall_get_frame_id(fd);
3841 }
3842
3843
3844 /* returns allocated field of subframes or NULL on error */
3845 /* count cointains length of the field */
3846 /* don't forget to free the field after use */
js_upcall_get_subframes(void * chuligane,long frame_id,int * count)3847 long * js_upcall_get_subframes(void *chuligane, long frame_id, int *count)
3848 {
3849 struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
3850 struct f_data_c *fd;
3851 struct f_data_c *f;
3852 struct list_head *lf;
3853 int a;
3854 long *pole;
3855 *count=0;
3856
3857 if (!js_ctx)internal_error("js_upcall_get_subframes called with NULL context pointer\n");
3858 if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return NULL;
3859 fd=jsint_find_document(frame_id);
3860 if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
3861
3862 foreach(struct f_data_c, f, lf, fd->subframes)
3863 if (jsint_can_access(fd,f)) (*count)++;
3864
3865 if (!*count)return NULL;
3866 if ((unsigned)*count > MAXINT / sizeof(long)) overalloc();
3867 pole=mem_alloc((*count)*sizeof(long));
3868
3869 a=0;
3870 foreach(struct f_data_c, f, lf, fd->subframes)
3871 if (jsint_can_access(fd,f))
3872 {pole[a]=js_upcall_get_frame_id(f);a++;}
3873 return pole;
3874 }
3875
3876
3877 /*--------------------- DOWNCALLS ---------------------------*/
3878
js_downcall_game_over(void * context)3879 void js_downcall_game_over(void *context)
3880 {
3881 struct f_data_c *fd=(struct f_data_c*)(((js_context*)(context))->ptr);
3882
3883 /* js_error(get_text_translation(TEXT_(T_SCRIPT_KILLED_BY_USER),fd->ses->term),context);
3884 * Tato hlaska me srala. Na to bych neprisel, ze jsem prave zabil
3885 * rucne javascript. */
3886 if (fd->ses->default_status)mem_free(fd->ses->default_status),fd->ses->default_status=NULL; /* pekne uklidime bordylek, ktery nam BFU nacintalo do status lajny */
3887 jsint_destroy(fd);
3888 #if 0
3889 js_durchfall=0;
3890 if(((js_context*)context)->running)
3891 js_volej_kolbena(context);
3892 /* Kolben - ale nespi mi - co s tim budeme delat? */
3893 ((js_context*)context)->running=0;
3894 #endif
3895 }
3896
3897
js_downcall_vezmi_int(void * context,int i)3898 void js_downcall_vezmi_int(void *context, int i)
3899 {
3900 }
3901
3902
js_downcall_vezmi_float(void * context,float f)3903 void js_downcall_vezmi_float(void *context, float f)
3904 {
3905 }
3906
3907 #else
3908
jsint_execute_code(struct f_data_c * fd,unsigned char * code,int len,int write_pos,int onclick_submit,int onsubmit,struct links_event * ev)3909 void jsint_execute_code(struct f_data_c *fd, unsigned char *code, int len, int write_pos, int onclick_submit, int onsubmit, struct links_event *ev)
3910 {
3911 }
3912
jsint_destroy(struct f_data_c * fd)3913 void jsint_destroy(struct f_data_c *fd)
3914 {
3915 }
3916
jsint_scan_script_tags(struct f_data_c * fd)3917 void jsint_scan_script_tags(struct f_data_c *fd)
3918 {
3919 }
3920
jsint_get_source(struct f_data_c * fd,unsigned char ** start,size_t * len)3921 int jsint_get_source(struct f_data_c *fd, unsigned char **start, size_t *len)
3922 {
3923 return 0;
3924 }
3925
3926 #endif
3927