links/jsint.c
2021-08-28 18:37:32 +03:00

3926 lines
109 KiB
C

/* jsint.c
* (c) 2002 Mikulas Patocka (Vrxni Ideolog), Petr 'Brain' Kulhavy
* This file is a part of the Links program, relased under GPL.
*/
/*
* Ve vsech upcallech plati, ze pokud dostanu ID nejakeho objektu, tak
* javascript ma k tomu objektu pristupova prava. Jinymi slovy pristupova prava
* se testuji v upcallech jen, aby se neco neproneslo vratnici ven. Dovnitr se
* muze donaset vsechno, co si javascript donese, na to ma prava.
*
* Navic vsechny upcally dostanou pointer na f_data_c, kde bezi javascript,
* takze se bude moci testovat, zda javascript nesaha na f_data_c, ke kteremu
* nema pristupova prava.
*
* Brain
*/
/* Uctovani pameti:
* js_mem_alloc/js_mem_free se bude pouzivat na struktury fax_me_tender
* dale se bude pouzivat take ve funkcich pro praci s cookies, protoze string
* cookies v javascript_context se tez alokuje pomoci js_mem_alloc/js_mem_free.
*/
/*
Retezce:
vsechny retezce v ramci javascriptu jsou predavany v kodovani f_data->cp
(tedy tak, jak prisly v dokumentu ze site)
*/
#include "links.h"
#ifdef JS
tcount jsint_execute_seq = 0;
#include "struct.h"
#include "ipret.h"
#include "builtin_keys.h"
/*
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
#define TRACE_EXECUTE
*/
struct js_request {
list_entry_1st
int onclick_submit; /* >=0 (znamena cislo formulare) pokud tohle je request onclick handleru u submit tlacitka nebo onsubmit handleru */
int onsubmit; /* dtto pro submit handler */
struct links_event ev; /* event, ktery se ma poslat pri uspechu */
int write_pos; /* document.write position from END of document. -1 if document.write cannot be used */
int wrote; /* this request called document.write */
int len;
tcount seq;
list_entry_last
unsigned char code[1];
};
/* set_cookies bude parsovat takhle:
* +....=............;...............................+ <- tohle je strinzik
* ^ ^
* najdu 1. rovnase a za nim 1. strednik, najdu nasledujici rovnase a
* nasledujici strednik, pokud to bude platne (&'='<&';') a 2. jmeno bude
* "expires", tak to je furt jedna cookie -> poslu Mikulasovi.
*
* kdyz ne, tak je to jina susenka a poslu to 1. Mikulasovi
*
* pokud najdu ';' a za nim whitespace, za kterym neni rovnase, tak od toho
* stredniku je to garbaz, kterou vratim do strinziku (fd->js->ctx->cookies)
*/
/* sets all cookies in fd>js->ctx->cookies */
/* final_flush means, that set_cookies was called from jsint_done_execution */
/* JESTLI V TYHLE FUNKCI BUDE NEJAKA BUGA, tak za to muze PerM, Clock a pan GNU,
* ktery tady kolem rusili, ze jsem se nemohl soustredit. Takze se s
* pripadnejma reklamacema obratte na ne!
*
* Brain
*/
/* prototypes */
static void jsint_send_event(struct f_data_c *fd, struct links_event *ev);
static int jsint_create(struct f_data_c *);
static void jsint_done_execution(void *);
static int jsint_can_access(struct f_data_c *, struct f_data_c *);
static struct f_data_c *jsint_find_recursive(struct f_data_c *, long); /* line 89 */
static void *jsint_find_object(struct f_data_c *, long);
static long *add_id(long *, int *, long );
static long *add_fd_id(long *, int *, long, long, unsigned char *);
static void add_all_recursive_in_fd(long **, int *, struct f_data_c *, struct f_data_c *);
void jsint_set_cookies(struct f_data_c *fd, int final_flush)
{
unsigned char *str;
unsigned char *next;
unsigned char *eq1, *semic1, *eq2, *semic2;
if(!(fd->js)||!(fd->js->ctx))internal_error("jsint_set_cookies called with NULL context.\n");
if (!(fd->js->ctx->cookies)||!(fd->rq))return; /* cookies string is empty, nothing to set */
str=fd->js->ctx->cookies;
a_znova:
eq1=strchr(str,'=');
semic1=strchr(str,';');
if (!*str||(!final_flush&&!semic1)) /* na konci neni strednik a skript jeste bezi, takze to musime vratit do stringu a vypadnout */
{
unsigned char *bla=NULL;
if (*str)bla=stracpy1(str);
js_mem_free(fd->js->ctx->cookies);
fd->js->ctx->cookies=bla;
return;
}
/* ted se v str bud vyskytuje strednik, nebo skript uz skoncil */
if (semic1&&eq1>semic1) /* '=' je za ';' takze to pred strednikem a strednik skipnem */
{
str=semic1+1;
goto a_znova;
}
next=semic1?semic1+1:str+strlen(cast_const_char str);
if (!eq1) /* neni tam '=', takze to preskocime */
{
str=next;
goto a_znova;
}
/* ted by to mela bejt regulerni susenka */
next_par:
eq2=NULL,semic2=NULL;
if (semic1!=NULL)
{
eq2=strchr(semic1+1,'=');
semic2=strchr(semic1+1,';');
}
if (eq2&&semic1&&(final_flush||semic2))
{
unsigned char *p=strstr(semic1+1,"expires");
if (!p)p=strstr(semic1+1,"Expires");
if (!p)p=strstr(semic1+1,"EXPIRES");
if (!p)p=strstr(semic1+1,"domain");
if (!p)p=strstr(semic1+1,"Domain");
if (!p)p=strstr(semic1+1,"DOMAIN");
if (!p)p=strstr(semic1+1,"path");
if (!p)p=strstr(semic1+1,"Path");
if (!p)p=strstr(semic1+1,"PATH");
if (!p)p=strstr(semic1+1,"comment");
if (!p)p=strstr(semic1+1,"Comment");
if (!p)p=strstr(semic1+1,"COMMENT");
if (!p)p=strstr(semic1+1,"max-age");
if (!p)p=strstr(semic1+1,"Max-age");
if (!p)p=strstr(semic1+1,"Max-Age");
if (!p)p=strstr(semic1+1,"MAX-AGE");
if (!p)p=strstr(semic1+1,"version");
if (!p)p=strstr(semic1+1,"Version");
if (!p)p=strstr(semic1+1,"VERSION");
if (p&&p>semic1&&p<eq2) /* za 1. prirazenim nasleduje "expires=", takze to je porad jedna susenka */
{
next=semic2?semic2+1:str+strlen(cast_const_char str);
semic1=semic2;
goto next_par;
}
}
if (*next)next[-1]=0;
for (;*str&&WHITECHAR(*str);str++); /* skip whitechars */
/*debug("set_cookie: \"%s\"", str);*/
set_cookie(fd->rq->url, str);
str=next;
goto a_znova;
}
int jsint_object_type(long to_je_on_Padre)
{
return to_je_on_Padre&JS_OBJ_MASK;
}
static int jsint_create(struct f_data_c *fd)
{
struct js_state *js;
if (fd->js) internal_error("javascript state present");
js = mem_calloc(sizeof(struct js_state));
if (!(js->ctx = js_create_context(fd, ((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT))) {
mem_free(js);
return 1;
}
init_list(js->queue);
fd->js = js;
return 0;
}
void jsint_destroy(struct f_data_c *fd)
{
struct js_state *js = fd->js;
fd->script_t = 0;
if (!js) return;
fd->js = NULL;
pr(js_destroy_context(js->ctx)) return;
if (js->src) mem_free(js->src);
if (js->active) mem_free(js->active);
js_zaflaknuto_pameti -= js->newdata;
free_list(struct js_request, js->queue);
mem_free(js);
}
/* for <a href="javascript:..."> */
void javascript_func(struct session *ses, unsigned char *hlavne_ze_je_vecirek)
{
unsigned char *code=get_url_data(hlavne_ze_je_vecirek);
jsint_execute_code(current_frame(ses),code,strlen(cast_const_char code),-1,-1,-1, NULL);
}
static void jsint_send_event(struct f_data_c *fd, struct links_event *ev)
{
if (!ev || !ev->b) return;
send_event(fd->ses, ev);
}
/* executes or queues javascript code in frame:
write_pos is number of bytes from the position where document.write should write to the end of document
write_pos == -1 if it is not from <SCRIPT> statement and cannot use document.write
*/
/* data je cislo formulare pro onclick submit handler, jinak se nepouziva */
/* ev je udalost, ktera se ma znovu poslat, pokud bylo vraceno true */
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)
{
struct js_request *r, *q;
struct list_head *lq;
for (;code&&len&&*code&&((*code)==' '||(*code)==9||(*code)==13||(*code)==10);code++,len--);
/*
FUJ !!!!
if (!casecmp(code, cast_uchar "javascript:",strlen(cast_const_char "javascript:")))code+=strlen(cast_const_char "javascript:");
*/
if (len >= 11 && !casecmp(code, "javascript:", 11)) code += 11, len -= 11;
if (!js_enable) {
jsint_send_event(fd, ev);
return;
}
#ifdef TRACE_EXECUTE
fprintf(stderr, "Submitted: ^^%.*s^^\n", len, code);
#endif
if (!fd->js && jsint_create(fd)) {
jsint_send_event(fd, ev);
return;
}
if ((unsigned)len > MAXINT - sizeof(struct js_request)) overalloc();
r = mem_calloc(sizeof(struct js_request) + len);
r->seq = jsint_execute_seq++;
r->write_pos = write_pos;
r->len = len;
r->onclick_submit = onclick_submit;
r->onsubmit = onsubmit;
memcpy(r->code, code, len);
if (ev) memcpy(&r->ev, ev, sizeof(struct links_event));
if (write_pos == -1) {
add_to_list_end(fd->js->queue, r);
} else {
/* add it beyond all <SCRIPT> requests but before non-<SCRIPT> ones */
foreach(struct js_request, q, lq, fd->js->queue) if (q->write_pos == -1) break;
add_before_list_entry(lq, &r->list_entry);
}
jsint_run_queue(fd);
}
static void jsint_done_execution(void *fd_)
{
struct f_data_c *fd = (struct f_data_c *)fd_;
struct js_request *r, *to_exec;
struct list_head *lr;
struct js_state *js = fd->js;
struct links_event ev = { 0, 0, 0, 0 };
if (!js) {
internal_error("no js in frame");
return;
}
if (!js->active) {
internal_error("jsint_done_execution: completion function called on inactive js");
return;
}
#ifdef TRACE_EXECUTE
fprintf(stderr, "Done: ^^%.*s^^\n", js->active->len, js->active->code);
#endif
/* accept all cookies set by the script */
jsint_set_cookies(fd,1);
/* js->active obsahuje request prave dobehnuteho skriptu */
/* dobehl onclick_handler a nezaplatil (vratil false), budou se dit veci */
if (js->active->ev.b && js->ctx->zaplatim)
memcpy(&ev, &js->active->ev, sizeof(struct links_event));
if (js->active->onclick_submit >=0 && !js->ctx->zaplatim)
{
/* pokud je handler od stejneho formulare, jako je defered, tak odlozeny skok znicime a zlikvidujem prislusny onsubmit handler z fronty */
if (js->active->onclick_submit == fd->ses->defered_data)
{
foreach(struct js_request, r, lr,js->queue)
/* to je onsubmit od naseho formulare, tak ho smazem */
if (r->onsubmit == js->active->onclick_submit)
{
del_from_list(r);
mem_free(r);
break; /* zadny dalsi onsubmit tohoto formulare uz nebude */
}
ses_destroy_defered_jump(fd->ses);
}
}
if (js->active->write_pos == -1) mem_free(js->active), js->active = NULL;
else {
r = js->active; js->active = NULL;
if (r->wrote) js->wrote = 1;
jsint_scan_script_tags(fd);
if (!f_is_finished(fd->f_data)) {
fd->done = 0;
fd->parsed_done = 0;
}
if (js->wrote && fd->script_t == -1) {
fd->done = 0;
fd->parsed_done = 0;
fd_loaded(NULL, fd);
js->wrote = 0;
}
mem_free(r);
}
to_exec = js->active;
if (!to_exec && !list_empty(fd->js->queue)) to_exec = list_struct(fd->js->queue.next, struct js_request);
if (fd->ses->defered_url && (!to_exec || (to_exec->seq > fd->ses->defered_seq && to_exec->write_pos == -1)))
{
unsigned char *url, *target;
url=stracpy(fd->ses->defered_url);
target=stracpy(fd->ses->defered_url);
goto_url_f(fd->ses,NULL,url,target,fd->ses->defered_target_base,fd->ses->defered_data,0,0,0);
mem_free(url);
mem_free(target);
}
else
jsint_run_queue(fd);
jsint_send_event(fd, &ev);
}
void jsint_run_queue(struct f_data_c *fd)
{
struct js_request *r;
struct js_state *js = fd->js;
if ((!fd->done && fd->f_data) || !js || js->active || list_empty(js->queue)) return;
r = list_struct(js->queue.next, struct js_request);
del_from_list(r);
js->active = r;
#ifdef TRACE_EXECUTE
fprintf(stderr, "Executing: ^^%.*s^^\n", r->len, r->code);
#endif
pr(js_execute_code(js->ctx, r->code, r->len, jsint_done_execution)) {};
}
/* returns: 1 - source is modified by document.write
0 - original source
*/
int jsint_get_source(struct f_data_c *fd, unsigned char **start, size_t *len)
{
struct js_state *js = fd->js;
if (!js || !js->src) return 0;
if (start) *start = js->src;
if (len) *len = (size_t)js->srclen;
return 1;
}
/*
* tests if script running in frame "running" can access document in frame "accessed"
* 0=no permission, 1=permission OK
*/
static int jsint_can_access(struct f_data_c *running, struct f_data_c *accessed)
{
int a;
unsigned char *h1, *h2;
if (!running || !accessed || !running->rq || !accessed->rq) return 0;
h1 = get_host_name(running->rq->url);
h2 = get_host_name(accessed->rq->url);
a = !casestrcmp(h1, h2);
mem_free(h1);
mem_free(h2);
return a;
}
/* doc_id is real document id, whithout any type */
/* fd must be a valid pointer */
static struct f_data_c *jsint_find_recursive(struct f_data_c *fd, long doc_id)
{
struct f_data_c *sub, *fdd;
struct list_head *lsub;
if (fd->id == doc_id) return fd;
foreach(struct f_data_c, sub, lsub, fd->subframes) {
if ((fdd = jsint_find_recursive(sub, doc_id))) return fdd;
}
return NULL;
}
/*
* This function finds document that has given ID
*/
struct f_data_c *jsint_find_document(long doc_id)
{
struct f_data_c *fd;
struct session *ses;
struct list_head *lses;
int type=jsint_object_type(doc_id);
if (type!=JS_OBJ_T_DOCUMENT&&type!=JS_OBJ_T_FRAME)
{unsigned char txt[256]; snprintf(txt,256,"jsint_find_document called with type=%d\n",type);internal_error(txt);}
doc_id>>=JS_OBJ_MASK_SIZE;
foreach(struct session, ses, lses, sessions) if ((fd = jsint_find_recursive(ses->screen, doc_id))) return fd;
return NULL;
}
/* Document has just loaded. Scan for <SCRIPT> tags and execute each of them */
void jsint_scan_script_tags(struct f_data_c *fd)
{
unsigned char *name, *attr;
int namelen;
unsigned char *val, *e, *ee;
unsigned char *s, *ss, *eof;
size_t len;
unsigned char *start, *end;
unsigned char *onload_code = NULL;
int uv;
int bs;
if (!js_enable) return;
if (!fd->rq || !fd->rq->ce || !fd->f_data) return;
if (!jsint_get_source(fd, &ss, &len)) {
if (get_file(fd->rq, &ss, &len)) return;
}
if (len > MAXINT) len = MAXINT;
eof = ss + len;
d_opt = &fd->f_data->opt;
s = ss;
se:
while (s < eof && *s != '<') sp:s++;
if (s >= eof || fd->script_t < 0)
{
if (onload_code && fd->script_t != -1)
{
jsint_execute_code(fd,onload_code,strlen(cast_const_char onload_code),-1,-1,-1, NULL);
}
fd->script_t = -1;
goto ret;
}
if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) {
s = skip_comment(s, eof);
goto se;
}
if (parse_element(s, eof, &name, &namelen, &attr, &s)) goto sp;
if (!onload_code&&namelen==4&&!casecmp(name,"BODY",4))
{
onload_code=get_attr_val(attr,"onload"); /* if the element doesn't have onload attribute get_attr_val returns NULL */
goto se;
}
if (!onload_code&&namelen==3&&!casecmp(name,"IMG",3))
{
onload_code=get_attr_val(attr,"onload"); /* if the element doesn't have onload attribute get_attr_val returns NULL */
goto se;
}
if (namelen != 6 || casecmp(name, "SCRIPT", 6) || s - ss < fd->script_t) goto se;
start = end = NULL;
if ((val = get_attr_val(attr, "src"))) {
unsigned char *url;
if (fd->f_data->script_href_base && ((url = join_urls(fd->f_data->script_href_base, val)))) {
size_t len;
int code, version;
struct additional_file *af = request_additional_file(fd->f_data, url);
mem_free(url);
mem_free(val);
if (!af || !af->rq) goto se;
if (af->rq->state >= 0) goto ret;
if (!af->rq->ce) goto se;
if (!get_http_code(af->rq->ce->head, &code, &version)) {
if (code < 200 || code >= 300) goto se;
}
if (get_file(af->rq, &start, &len)) goto se;
if (!len) goto se;
if (len > MAXINT) len = MAXINT;
end = start + len;
} else {
mem_free(val);
goto se;
}
}
e = s;
uv = 0;
bs = 0;
while (e < eof && *e != '<') {
es:
if (!uv && (*e == '"' || *e == '\'')) uv = *e, bs = 0;
else if (*e == '\\' && uv) bs = 1;
else if (*e == uv && !bs) uv = 0;
else bs = 0;
e++;
}
if (eof - e >= 8) {
if (/*uv ||*/ casecmp(e, "</SCRIPT", 8)) goto es;
} else e = eof;
ee = e;
while (ee < eof && *ee != '>') ee++;
if (ee < eof) ee++;
fd->script_t = ee - ss;
if (!start || !end) jsint_execute_code(fd, s, e - s, eof - ee,-1,-1, NULL);
else jsint_execute_code(fd, start, end - start, eof - ee,-1,-1, NULL);
ret:
if (onload_code)mem_free(onload_code);
d_opt = &dd_opt;
}
struct hopla_mladej
{
struct form_control *fc;
struct form_state *fs;
};
/* Returns pointer to the object with given ID in the document, or NULL when
* there's no such object. Document must be a valid pointer.
*
* Pointer type depends on type of object, caller must know the type and
* interpret the pointer in the right way.
*/
static void *jsint_find_object(struct f_data_c *document, long obj_id)
{
int type=obj_id&JS_OBJ_MASK;
int orig_obj_id=obj_id;
obj_id>>=JS_OBJ_MASK_SIZE;
switch (type)
{
/* form element
* obj_id can be from 0 up to number of form fields
* (document->vs->form_info_len may be actually lower if the fields were never
* touched)
* returns allocated struct hopla_mladej, you must free it after use
*/
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_RADIO:
case JS_OBJ_T_SELECT:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_HIDDEN:
case JS_OBJ_T_BUTTON:
{
struct hopla_mladej *hopla;
struct form_control *fc;
struct list_head *lfc;
int a=0;
if (obj_id<0/*||obj_id>=n*/)return NULL;
hopla=mem_alloc(sizeof(struct hopla_mladej));
if (!(document->f_data)){mem_free(hopla);return NULL;};
foreachback(struct form_control, fc, lfc, document->f_data->forms)
if (fc->g_ctrl_num==obj_id){a=1;break;}
if (!a){mem_free(hopla);return NULL;}
hopla->fs=find_form_state(document, fc);
hopla->fc=fc;
return hopla;
}
/* link
* obj_id can be from 0 to (nlinks-1)
*/
case JS_OBJ_T_LINK:
{
struct link*l;
int n;
if (!(document->f_data))return NULL;
l=document->f_data->links;
n=document->f_data->nlinks;
if (obj_id<0||obj_id>=n)return NULL;
return l+obj_id;
}
/* form
* obj_id is form_num in struct form_control (f_data->forms)
*/
case JS_OBJ_T_FORM:
{
struct form_control *f;
struct list_head *lf;
if (!(document->f_data))return NULL;
foreachback(struct form_control, f, lf, document->f_data->forms) if ((f->form_num)==obj_id)return f;
return NULL;
}
/* anchors
* obj_id is position in list of all tags
*/
case JS_OBJ_T_ANCHOR:
{
struct tag *t;
struct list_head *lt;
int a=0;
if (!(document->f_data))return NULL;
foreach(struct tag, t, lt, document->f_data->tags)
{
if (obj_id==a)return t;
a++;
}
return NULL;
}
break;
/* this is document
* call jsint_find_document
* returned value is struct f_data_c
*/
case JS_OBJ_T_FRAME:
case JS_OBJ_T_DOCUMENT:
return jsint_find_document(orig_obj_id);
/* image
* returned value is struct g_object_image *
*/
case JS_OBJ_T_IMAGE:
#ifdef G
if (F) {
struct g_object_image *gi;
struct list_head *lgi;
if (!document->f_data) return NULL;
foreach(struct g_object_image, gi, lgi, document->f_data->images) {
if (gi->id == obj_id) return gi;
}
return NULL;
}else
#endif
return NULL;
default:
internal_error("jsint_find_object: unknown type %d.",type);
return NULL; /* never called, but GCC likes it ;-) */
}
}
static long *add_id(long *field,int *len,long id)
{
long *p;
int a;
for (a=0;a<(*len);a++) /* this object is already on the list */
if (field[a]==id)return field;
(*len)++;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
p=mem_realloc(field,(*len)*sizeof(long));
p[(*len)-1]=id;
return p;
}
long *add_fd_id(long *field,int *len,long fd,long id, unsigned char *name)
{
long *p;
int a;
for (a=0;a<(*len);a+=3) /* this object is already on the list */
if (field[a]==fd&&field[a+1]==id)return field;
(*len)+=3;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
p=mem_realloc(field,(*len)*sizeof(long));
p[(*len)-3]=fd;
p[(*len)-2]=id;
p[(*len)-1]=(name&&(*name))?(long)stracpy(name):(long)NULL;
return p;
}
static long js_upcall_get_frame_id(void *data);
/* finds all objects with name takhle_tomu_u_nas_nadavame
* in fd and all it's subframes with rq==NULL
* js_ctx is f_data_c of the accessing script
*/
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)
{
struct f_data_c *ff;
struct list_head *lff;
struct form_control *f;
struct list_head *lf;
/* search frame */
foreach(struct f_data_c, ff, lff, fd->subframes)
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! */
if (!(pole_vole=add_id(pole_vole,n_items,js_upcall_get_frame_id(ff))))return NULL;
if (!(fd->f_data))goto a_je_po_ptakach;
#ifdef G
if (F) {
struct g_object_image *gi;
struct list_head *lgi;
/* search images */
foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
if (gi->name&&!strcmp(cast_const_char gi->name, cast_const_char takhle_tomu_u_nas_nadavame))
if (!(pole_vole=add_id(pole_vole,n_items,JS_OBJ_T_IMAGE+((gi->id)<<JS_OBJ_MASK_SIZE))))return NULL;
}
}
#endif
/* search forms */
foreachback(struct form_control, f, lf, fd->f_data->forms)
if (f->form_name&&!strcmp(cast_const_char f->form_name,cast_const_char takhle_tomu_u_nas_nadavame)) /* tak tohle JE Jim Beam */
if (!(pole_vole=add_id(pole_vole,n_items,((f->form_num)<<JS_OBJ_MASK_SIZE)+JS_OBJ_T_FORM)))return NULL;
/* search form elements */
foreachback(struct form_control, f, lf, fd->f_data->forms)
if (f->name&&!strcmp(cast_const_char f->name,cast_const_char takhle_tomu_u_nas_nadavame)) /* tak tohle JE Jim Beam */
{
long tak_mu_to_ukaz=0;
tak_mu_to_ukaz=(f->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
switch (f->type)
{
case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
case FC_IMAGE:
case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
default: /* internal_error("Invalid form element type.\n"); */
tak_mu_to_ukaz=0;break;
}
if (tak_mu_to_ukaz&&!(pole_vole=add_id(pole_vole,n_items,tak_mu_to_ukaz)))return NULL;
}
a_je_po_ptakach:
/* find in all rq==NULL */
foreach(struct f_data_c, ff, lff, fd->subframes)
if (!(ff->rq)) pole_vole=find_in_subframes(js_ctx,ff,pole_vole,n_items,takhle_tomu_u_nas_nadavame);
return pole_vole;
}
/* resolves name of an object, returns field of all ID's with the name
* obj_id is object in which we're searching
* takhle_tomu_u_nas_nadavame is the searched name
* context is identifier of the javascript context
* n_items is number of returned items
*
* on error returns NULL
*/
long *jsint_resolve(void *context, long obj_id, char *takhle_tomu_u_nas_nadavame,int *n_items)
{
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)context;
long *pole_vole;
*n_items=0;
if (!takhle_tomu_u_nas_nadavame||!(*takhle_tomu_u_nas_nadavame))return NULL;
pole_vole=mem_alloc(sizeof(long));
switch(jsint_object_type(obj_id))
{
/* searched object can be a frame, image, form or a form element */
case JS_OBJ_T_DOCUMENT:
case JS_OBJ_T_FRAME:
fd=jsint_find_document(obj_id);
if (!fd||!(jsint_can_access(js_ctx,fd)))break;
pole_vole=find_in_subframes(js_ctx, fd, pole_vole, n_items, takhle_tomu_u_nas_nadavame);
break;
/* searched name can be a form element */
case JS_OBJ_T_FORM:
{
struct form_control *fc=jsint_find_object(js_ctx,obj_id);
struct form_control *f;
struct list_head *lf;
if (!fc){mem_free(pole_vole);return NULL;}
if (!(js_ctx->f_data)){mem_free(pole_vole);return NULL;}
foreachback(struct form_control, f, lf, js_ctx->f_data->forms)
{
if (f->form_num==fc->form_num) /* this form */
if (f->name&&!strcmp(cast_const_char f->name,cast_const_char takhle_tomu_u_nas_nadavame)) /* this IS Jim Beam */
{
long tak_mu_to_ukaz=0;
tak_mu_to_ukaz=(f->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
switch (f->type)
{
case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
case FC_IMAGE:
case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
default: tak_mu_to_ukaz=0;break;
/* internal_error("Invalid form element type.\n"); */
}
if ((tak_mu_to_ukaz&JS_OBJ_MASK)&&!(pole_vole=add_id(pole_vole,n_items,tak_mu_to_ukaz)))return NULL;
}
}
}
break;
}
if (!pole_vole)return NULL;
if (!(*n_items)){mem_free(pole_vole);pole_vole=NULL;}
return pole_vole;
}
/*------------------------>>>>>>>> UPCALLS <<<<<<<<-------------------------*/
/* tyhle upcally se volaji ze select smycky:
void js_upcall_confirm(void *data)
void js_upcall_alert(void * data)
void js_upcall_close_window(void *data)
void js_upcall_get_string(void *data)
void js_upcall_goto_url(void * data)
void js_upcall_goto_history(void * data)
void js_upcall_set_image_src(void* data)
V nich se musi volat js_spec_vykill_timer, aby se znicil timer, ktery upcall
zavolal.
Tyto upcally MUZOU dostavat f_data_c pointer primo, protoze kdyz ten f_data_c
umre a s nim i ten JS, tak se timery znicej --- tudiz se nic nestane.
*/
static void redraw_document(struct f_data_c *f)
{
/*
if (F) {
f->xl = -1;
f->yl = -1;
draw_to_window(f->ses->win, draw_doc, f);
}
*/
draw_fd(f);
}
/* returns ID of a document with the javascript */
long js_upcall_get_document_id(void *data)
{
struct f_data_c *fd;
if (!data)internal_error("js_upcall_get_document_id called with NULL pointer!");
fd=(struct f_data_c*)data;
return (((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT);
}
/* same as get_document_id, but returned type is FRAME */
static long js_upcall_get_frame_id(void *data)
{
struct f_data_c *fd;
if (!data)internal_error("js_upcall_get_document_id called with NULL pointer!");
fd=(struct f_data_c*)data;
return (((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_FRAME);
}
/* writes "len" bytes starting at "str" to document */
void js_upcall_document_write(void *p, unsigned char *str, int len)
{
int pos;
unsigned char *s;
struct f_data_c *fd = p;
struct js_state *js = fd->js;
if (!js)return;
if (!js->active) internal_error("js_upcall_document_write: no request active");
if (js->active->write_pos == -1) return;
if (js->active->write_pos < 0) internal_error("js_upcall_document_write: js->active trashed");
if (!js->src) {
size_t len;
unsigned char *s;
if (get_file(fd->rq, &s, &len)) return;
if (len > MAXINT) return;
js->src = memacpy(s, len);
js->srclen = len;
}
if ((unsigned)js->srclen + (unsigned)len > MAXINT) overalloc();
if ((unsigned)js->srclen + (unsigned)len < (unsigned)len) overalloc();
s = mem_realloc(js->src, js->srclen + len);
js->src = s;
if ((pos = js->srclen - js->active->write_pos) < 0) pos = 0;
memmove(s + pos + len, s + pos, js->srclen - pos);
memcpy(s + pos, str, len);
js->srclen += len;
js->newdata += len;
js_zaflaknuto_pameti += len;
js->active->wrote = 1;
}
/* returns title of actual document (=document in the script context) */
/* when an error occurs, returns NULL */
/* returned string should be deallocated after use */
unsigned char *js_upcall_get_title(void *data)
{
struct f_data_c *fd;
unsigned char *title, *t;
if (!data)internal_error("js_upcall_get_title called with NULL pointer!");
fd=(struct f_data_c *)data;
title=mem_alloc(MAX_STR_LEN);
if (!(get_current_title(fd,title,MAX_STR_LEN))){mem_free(title);return NULL;}
if (fd->f_data)
{
t = convert(fd->f_data->opt.cp, fd->f_data->cp, title, NULL);
mem_free(title);
title=t;
}
return title;
}
/* sets title of actual document (=document in the script context) */
/* string title will be deallocated after use */
void js_upcall_set_title(void *data, unsigned char *title)
{
unsigned char *t;
struct f_data_c *fd;
int l=0;
if (!data)internal_error("js_upcall_get_title called with NULL pointer!");
fd=(struct f_data_c *)data;
if (!title)return;
if (!(fd->f_data)){mem_free(title);return;}
if (fd->f_data->title)mem_free(fd->f_data->title);
fd->f_data->title=init_str();
fd->f_data->uncacheable=1;
t = convert(fd->f_data->cp, fd->f_data->opt.cp, title, NULL);
add_to_str(&(fd->f_data->title),&l,t);
mem_free(t);
mem_free(title);
redraw_document(fd);
}
/* returns URL of actual document (=document in the script context) */
/* when an error occurs, returns NULL */
/* returned string should be deallocated after use */
unsigned char *js_upcall_get_location(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
return loc;
}
/* returns string containing last modification date */
/* or NULL when the date is not known or when an error occurs */
unsigned char *js_upcall_document_last_modified(void *data, long document_id)
{
struct f_data_c *fd;
struct f_data_c *document;
unsigned char *retval;
document=jsint_find_document(document_id);
if (!data)internal_error("js_upcall_document_last_modified called with NULL pointer!");
fd=(struct f_data_c *)data;
if (!document)return NULL; /* document not found */
if (!jsint_can_access(fd, document))return NULL; /* you have no permissions to look at the document */
if (!fd->rq||!fd->rq->ce)return NULL;
retval=stracpy(fd->rq->ce->last_modified);
return retval;
}
/* returns allocated string with user-agent */
unsigned char *js_upcall_get_useragent(void *data)
{
/*struct f_data_c *fd;*/
unsigned char *retval=init_str();
int l=0;
if (!data)internal_error("js_upcall_get_useragent called with NULL pointer!");
/*fd=(struct f_data_c *)data;*/
if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent)) {
add_to_str(&retval, &l, "Links (" VERSION_STRING "; ");
add_to_str(&retval, &l, system_name);
add_to_str(&retval, &l, ")");
}
else {
add_to_str(&retval, &l, http_options.header.fake_useragent);
}
return retval;
}
/* returns allocated string with browser name */
unsigned char *js_upcall_get_appname(void)
{
if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent))
return stracpy("Links");
else
return stracpy(http_options.header.fake_useragent);
}
/* returns allocated string with browser name */
unsigned char *js_upcall_get_appcodename(void)
{
if (!http_options.header.fake_useragent||!(*http_options.header.fake_useragent))
return stracpy("Links");
else
return stracpy(http_options.header.fake_useragent);
}
/* returns allocated string with browser version: "version_number (system_name)" */
unsigned char *js_upcall_get_appversion(void)
{
unsigned char *str;
int l=0;
if (http_options.header.fake_useragent&&(*http_options.header.fake_useragent))return stracpy(http_options.header.fake_useragent);
str=init_str();
add_to_str(&str,&l,VERSION_STRING);
add_to_str(&str,&l," (");
add_to_str(&str,&l,system_name);
add_to_str(&str,&l,")");
return str;
}
/* returns allocated string with referrer */
unsigned char *js_upcall_get_referrer(void *data)
{
struct f_data_c *fd;
unsigned char *retval=init_str();
unsigned char *loc;
int l=0;
if (!data)internal_error("js_upcall_get_referrer called with NULL pointer!");
fd=(struct f_data_c *)data;
switch (http_options.header.referer)
{
case REFERER_FAKE:
add_to_str(&retval, &l, http_options.header.fake_referer);
break;
case REFERER_SAME_URL:
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);break;}
add_to_str(&retval, &l, loc);
mem_free(loc);
break;
case REFERER_REAL:
{
unsigned char *post;
if (!fd->rq||!(fd->rq->prev_url))break; /* no referrer */
post=strchr(fd->rq->prev_url, POST_CHAR);
if (!post)add_to_str(&retval, &l, fd->rq->prev_url);
else add_bytes_to_str(&retval, &l, fd->rq->prev_url, post - fd->rq->prev_url);
}
break;
}
return retval;
}
struct gimme_js_id
{
long id; /* id of f_data_c */
long js_id; /* unique id of javascript */
};
/* tady se netestuje js_id, protoze BFU to chce killnout, tak to proste killne */
/* aux function for all dialog upcalls */
static void js_kill_script_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js))return;
js_downcall_game_over(fd->js->ctx); /* call downcall */
}
/* aux function for js_upcall_confirm */
static void js_upcall_confirm_ok_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_true(fd->js->ctx); /* call downcall */
}
/* aux function for js_upcall_confirm */
static void js_upcall_confirm_cancel_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_false(fd->js->ctx); /* call downcall */
}
/* creates dialog with text s->string and buttons OK/Cancel */
/* s->string will be dealocated */
/* s will be dealocated too */
/* must be called from select loop */
void js_upcall_confirm(void *data)
{
struct fax_me_tender_string *s=(struct fax_me_tender_string*)data;
struct gimme_js_id* jsid;
struct f_data_c *fd;
struct terminal *term;
unsigned char *txt;
if (!s)internal_error("js_upcall_confirm called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
/* context must be a valid pointer ! */
fd=(struct f_data_c*)(s->ident);
term=fd->ses->term;
if (!fd->js)return;
jsid=mem_alloc(sizeof(struct gimme_js_id));
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
skip_nonprintable(s->string);
if (fd->f_data)
{
txt=convert(fd->f_data->cp, fd->f_data->opt.cp, s->string, NULL);
}
else
txt=stracpy(s->string);
js_mem_free(s->string);
msg_box(
term, /* terminal */
getml(txt,jsid,NULL), /* memory blocks to free */
TEXT_(T_QUESTION), /* title */
AL_CENTER, /* alignment */
txt,MSG_BOX_END, /* message */
(void *)jsid, /* data for button functions */
3, /* # of buttons */
TEXT_(T_OK),js_upcall_confirm_ok_pressed,B_ENTER, /* first button */
TEXT_(T_CANCEL),js_upcall_confirm_cancel_pressed,B_ESC, /* second button */
TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
);
js_mem_free(s);
}
/* aux function for js_upcall_alert */
static void js_upcall_alert_ok_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
}
/* gets struct fax_me_tender_string* */
/* creates dialog with title "Alert" and message got from struct fax_me_tender_string */
/* structure and the text are both deallocated */
/* must be called from select loop */
void js_upcall_alert(void * data)
{
struct fax_me_tender_string *s=(struct fax_me_tender_string*)data;
struct gimme_js_id* jsid;
struct f_data_c *fd;
struct terminal *term;
unsigned char *txt;
if (!s)internal_error("Alert called with NULL pointer.\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
/* context must be a valid pointer ! */
fd=(struct f_data_c*)(s->ident);
term=fd->ses->term;
if (!fd->js) return;
jsid=mem_alloc(sizeof(struct gimme_js_id));
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
skip_nonprintable(s->string);
if (fd->f_data)
{
txt=convert(fd->f_data->cp, fd->f_data->opt.cp, s->string, NULL);
}
else
txt=stracpy(s->string);
js_mem_free(s->string);
msg_box(
term, /* terminal */
getml(txt,jsid,NULL), /* memory blocks to free */
TEXT_(T_ALERT), /* title */
AL_CENTER, /* alignment */
txt,MSG_BOX_END, /* message */
(void *)jsid, /* data for button functions */
2, /* # of buttons */
TEXT_(T_OK),js_upcall_alert_ok_pressed,B_ENTER|B_ESC,
TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
);
js_mem_free(s);
}
/* aux function for js_upcall_close_window */
/* tady se netestuje js_id, protoze BFU zmacklo, ze chce zavrit okno a v
* nekterych pripadech by ho to nezavrelo (kdyby se testovalo) a to by vypadalo
* blbe */
static void js_upcall_close_window_yes_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
really_exit_prog(fd->ses);
}
/* asks user if he really wants to close the window and calls really_exit_prog */
/* argument is struct fax_me_tender_nothing* */
/* must be called from select loop */
void js_upcall_close_window(void *data)
{
struct fax_me_tender_nothing *s=(struct fax_me_tender_nothing*)data;
struct f_data_c *fd;
struct terminal *term;
if (!s)internal_error("js_upcall_close_window called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
/* context must be a valid pointer ! */
fd=(struct f_data_c*)(s->ident);
if (!fd->js) return;
term=fd->ses->term;
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
if (js_manual_confirmation)
{
struct gimme_js_id* jsid;
jsid=mem_alloc(sizeof(struct gimme_js_id));
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
msg_box(
term, /* terminal */
getml(jsid,NULL), /* memory blocks to free */
TEXT_(T_EXIT_LINKS), /* title */
AL_CENTER, /* alignment */
TEXT_(T_SCRIPT_TRYING_TO_CLOSE_WINDOW),MSG_BOX_END, /* message */
(void *)jsid, /* data for button functions */
2, /* # of buttons */
TEXT_(T_YES),js_upcall_close_window_yes_pressed,NULL,
TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL
);
js_mem_free(s);
}
else
{
js_mem_free(s);
if (term->list_entry.next == term->list_entry.prev && are_there_downloads())
query_exit(fd->ses);
else
really_exit_prog(fd->ses);
}
}
/* returns parent window ID of the script */
long js_upcall_get_window_id(void *data)
{
struct f_data_c *fd;
if (!data)internal_error("js_upcall_get_window_id called with NULL pointer!");
fd=(struct f_data_c*)data;
return ((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_FRAME;
}
/* aux function for js_upcall_get_string */
static void js_upcall_get_string_ok_pressed(void *data, unsigned char *str)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_string(fd->js->ctx, stracpy(str)); /* call downcall */
}
static void js_upcall_get_string_kill_script_pressed(void *data, unsigned char *str)
{
js_kill_script_pressed(data);
}
struct history js_get_string_history={0, {&js_get_string_history.items, &js_get_string_history.items}};
/* creates input field for string, with text s->string1, default response
* s->string2 and buttons OK/Kill Script
* s->string1 and s->string2 will be dealocated
* s will be dealocated too
* must be called from select loop */
void js_upcall_get_string(void *data)
{
struct fax_me_tender_2_stringy *s=(struct fax_me_tender_2_stringy*)data;
struct gimme_js_id* jsid;
struct f_data_c *fd;
struct terminal *term;
unsigned char *str1,*str2;
if (!s)internal_error("js_upcall_get_string called with NULL pointer\n"); /* to jenom kdyby na mne PerM zkousel naky oplzlosti... */
/* context must be a valid pointer ! */
fd=(struct f_data_c*)(s->ident);
term=fd->ses->term;
if (!fd->js) return;
jsid=mem_alloc(sizeof(struct gimme_js_id));
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
str1=stracpy(s->string1);
str2=stracpy(s->string2);
js_mem_free(s->string1);
js_mem_free(s->string2);
input_field(
term, /* terminal */
getml(str1, str2,jsid,NULL), /* mem to free */
TEXT_(T_ENTER_STRING), /* title */
str1, /* question */
jsid, /* data for functions */
&js_get_string_history, /* history */
MAX_INPUT_URL_LEN, /* string len */
str2, /* string to fill the dialog with */
0, /* min value */
0, /* max value */
NULL, /* check fn */
2, /* the number of buttons */
TEXT_(T_OK), /* ok button */
js_upcall_get_string_ok_pressed,
TEXT_(T_KILL_SCRIPT), /* cancel button */
js_upcall_get_string_kill_script_pressed
);
js_mem_free(s);
}
/* clears window with javascript */
/* must be called from select loop */
/* javascript must halt before calling this upcall */
void js_upcall_clear_window(void *data)
{
/* context must be a valid pointer ! */
/*struct f_data_c *fd=(struct f_data_c*)data;*/
/* no jsint_destroy context or so here, it's called automatically from reinit_f_data_c */
/*
zatim jsem to zrusil ... tahle funkce musi byt volana pres timer, takhle je to uplne blbe a spadne to pri kazdem volani -- Mikulas
to je <|>vina, v komentari je jasne napsano, ze tahle fce musi byt volana ze select loop, takze to nema co padat -- Brain
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
reinit_f_data_c(fd);
*/
}
/* returns allocated string with window name */
unsigned char *js_upcall_get_window_name(void *data)
{
/* context must be a valid pointer ! */
struct f_data_c *fd=(struct f_data_c*)data;
return fd->loc?stracpy(fd->loc->name):NULL;
}
/* returns allocated field of ID's of links in JS document
* number of links is stored in len
* if number of links is 0, returns NULL
* on error returns NULL too
*/
long *js_upcall_get_links(void *data, long document_id, int *len)
{
struct f_data_c *js_ctx=(struct f_data_c*)data;
struct f_data_c *fd;
/*struct link *l;*/
int a;
long *to_je_Ono;
fd=jsint_find_document(document_id);
if (!js_ctx)internal_error("js_upcall_get_links called with NULL context pointer\n");
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if (!(fd->f_data))return NULL;
*len=fd->f_data->nlinks;
if (!(*len))return NULL;
/*l=fd->f_data->links;*/
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
to_je_Ono=mem_alloc((*len)*sizeof(long));
for (a=0;a<(*len);a++)
/*to_je_Ono[a]=JS_OBJ_T_LINK+(((l+a)->num)<<JS_OBJ_MASK_SIZE);*/
to_je_Ono[a]=JS_OBJ_T_LINK+(a<<JS_OBJ_MASK_SIZE);
return to_je_Ono;
}
/* returns allocated string with TARGET of the link
* if the link doesn't exist in the document, returns NULL
*/
unsigned char *js_upcall_get_link_target(void *data, long document_id, long link_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)data;
struct f_data_c *fd;
struct link *l;
if (!js_ctx)internal_error("js_upcall_get_link_target called with NULL context pointer\n");
if ((link_id&JS_OBJ_MASK)!=JS_OBJ_T_LINK)return NULL; /* this isn't link */
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
l=jsint_find_object(fd,link_id);
if (!l)return NULL;
return stracpy((l->target)?(l->target):(unsigned char *)(""));
}
/* returns allocated field of ID's of forms in JS document
* number of forms is stored in len
* if number of forms is 0, returns NULL
* on error returns NULL too
*/
long *js_upcall_get_forms(void *data, long document_id, int *len)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc;
struct list_head *lfc;
long *to_je_Ono;
long last=0;
if (!js_ctx)internal_error("js_upcall_get_forms called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if (!(fd->f_data))return NULL;
to_je_Ono=mem_alloc(sizeof(long));
*len=0;
foreachback(struct form_control, fc, lfc, fd->f_data->forms) {
long *p;
int a;
if ((*len)&&(fc->form_num)==last)continue;
for (a=0;a<(*len);a++)
if ((to_je_Ono[a]>>JS_OBJ_MASK_SIZE)==(fc->form_num))goto already_have; /* we already have this number */
(*len)++;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
p=mem_realloc(to_je_Ono,(*len)*sizeof(long));
to_je_Ono=p;
to_je_Ono[(*len)-1]=JS_OBJ_T_FORM|((fc->form_num)<<JS_OBJ_MASK_SIZE);
last=fc->form_num;
already_have:;
}
if (!(*len)){mem_free(to_je_Ono);to_je_Ono=NULL;}
return to_je_Ono;
}
/* returns allocated string with the form action
* when an error occurs, returns NULL
*/
unsigned char *js_upcall_get_form_action(void *data, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc;
if (!js_ctx)internal_error("js_upcall_get_form_action called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
fc=jsint_find_object(fd,form_id);
if (!fc)return NULL;
return stracpy(fc->action);
}
/* sets form action
*/
void js_upcall_set_form_action(void *context, long document_id, long form_id, unsigned char *action)
{
struct f_data_c *js_ctx=(struct f_data_c *)context;
struct f_data_c *fd;
struct form_control *fc;
if (!js_ctx) {
internal_error("js_upcall_set_form_action called with NULL context pointer\n");
}
fd=jsint_find_document(document_id);
if (!fd || !jsint_can_access(js_ctx,fd)) {
if (action) mem_free(action);
return;
}
if ( (form_id&JS_OBJ_MASK) != JS_OBJ_T_FORM ) {
if (action) mem_free(action);
return;
}
fc=jsint_find_object(fd,form_id);
if (!fc) {
if (action) mem_free(action);
return;
}
if (fc->action) {
mem_free (fc->action);
if ( fd->loc && fd->loc->url )
fc->action=join_urls(fd->loc->url,action);
else
fc->action=stracpy(action);
fd->f_data->uncacheable=1;
}
if (action) {
mem_free(action);
}
}
/* returns allocated string with the form target
* when an error occurs, returns NULL
*/
unsigned char *js_upcall_get_form_target(void *data, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc;
if (!js_ctx)internal_error("js_upcall_get_form_target called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
fc=jsint_find_object(fd,form_id);
if (!fc)return NULL;
return stracpy(fc->target);
}
/* returns allocated string with the form method
* when an error occurs, returns NULL
*/
unsigned char *js_upcall_get_form_method(void *data, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc;
if (!js_ctx)internal_error("js_upcall_get_form_method called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
fc=jsint_find_object(fd,form_id);
if (!fc)return NULL;
switch (fc->method)
{
case FM_GET:
return stracpy("GET");
case FM_POST:
case FM_POST_MP:
return stracpy("POST");
default:
internal_error("Invalid form method!\n");
return NULL; /* never called, but GCC likes it */
}
}
/* returns allocated string with the form encoding (value of attribute enctype)
* when an error occurs, returns NULL
*/
unsigned char *js_upcall_get_form_encoding(void *data, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc;
if (!js_ctx)internal_error("js_upcall_get_form_encoding called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
fc=jsint_find_object(fd,form_id);
if (!fc)return NULL;
switch (fc->method)
{
case FM_GET:
case FM_POST:
return stracpy("application/x-www-form-urlencoded");
case FM_POST_MP:
return stracpy("multipart/form-data");
default:
internal_error("Invalid form method!\n");
return NULL; /* never called, but GCC likes it */
}
}
/* returns allocated string containing protocol from current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_protocol(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *p;
int l;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
if (parse_url(loc, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)){mem_free(loc);return NULL;}
p=memacpy(loc,l+1); /* l is pointing to the colon, but we want protocol with colon */
mem_free(loc);
return p;
}
/* returns allocated string containing port of current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_port(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *p;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
p=get_port_str(loc);
mem_free(loc);
return p;
}
/* returns allocated string containing hostname of current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_hostname(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *p;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
p=get_host_name(loc);
mem_free(loc);
return p;
}
/* returns allocated string containing hostname and port of current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_host(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *p, *h;
int l1,l2;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, &h, &l1, NULL, &l2, NULL, NULL, NULL)){mem_free(loc);return NULL;}
p=memacpy(h,l1+l2);
mem_free(loc);
return p;
}
/* returns allocated string containing pathname of current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_pathname(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *d, *p;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
if (!d){mem_free(loc);return NULL;}
p=memacpy(d,strcspn(d,"?"));
mem_free(loc);
return p;
}
/* returns allocated string containing everything after ? in current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_search(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *d, *p;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
if (!d){mem_free(loc);return NULL;}
p=stracpy(strchr(d,'?'));
mem_free(loc);
return p;
}
/* returns allocated string containing everything between # and ? in current URL in the script context
* on error (or there's no protocol) NULL is returned
*/
unsigned char *js_upcall_get_location_hash(void *data)
{
struct f_data_c *fd;
unsigned char *loc;
unsigned char *d, *p;
if (!data)internal_error("js_upcall_get_location called with NULL pointer!");
fd=(struct f_data_c *)data;
loc=mem_alloc(MAX_STR_LEN);
if (!(get_current_url(fd->ses,loc,MAX_STR_LEN))){mem_free(loc);return NULL;}
if (parse_url(loc, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)){mem_free(loc);return NULL;}
if (!d){mem_free(loc);return NULL;}
d=strchr(d,'#');
if (!d){mem_free(loc);return NULL;}
d++;
p=memacpy(d,strcspn(d,"?"));
mem_free(loc);
return p;
}
/* returns allocated field of all form elements
* size of the field will be stored in len
* when an error occurs, returns NULL
*/
long *js_upcall_get_form_elements(void *data, long document_id, long form_id, int *len)
{
struct f_data_c *js_ctx=(struct f_data_c *)data;
struct f_data_c *fd;
struct form_control *fc, *fc2;
struct list_head *lfc2;
long *pole_Premysla_Zavorace;
int b;
if (!js_ctx)internal_error("js_upcall_get_form_elements called with NULL context pointer\n");
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return NULL; /* this isn't form */
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
fc=jsint_find_object(fd,form_id);
if (!fc)return NULL;
*len=0;
foreach(struct form_control, fc2, lfc2, fd->f_data->forms)
if (fc2->form_num==fc->form_num)(*len)++;
if (!(*len))return NULL;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
pole_Premysla_Zavorace=mem_alloc((*len)*sizeof(long));
b=0;
foreachback(struct form_control, fc2, lfc2, fd->f_data->forms)
if (fc2->form_num==fc->form_num)
{
switch (fc2->type)
{
case FC_TEXT: pole_Premysla_Zavorace[b]=JS_OBJ_T_TEXT; break;
case FC_PASSWORD: pole_Premysla_Zavorace[b]=JS_OBJ_T_PASSWORD; break;
case FC_TEXTAREA: pole_Premysla_Zavorace[b]=JS_OBJ_T_TEXTAREA; break;
case FC_CHECKBOX: pole_Premysla_Zavorace[b]=JS_OBJ_T_CHECKBOX; break;
case FC_RADIO: pole_Premysla_Zavorace[b]=JS_OBJ_T_RADIO; break;
case FC_IMAGE:
case FC_SELECT: pole_Premysla_Zavorace[b]=JS_OBJ_T_SELECT; break;
case FC_SUBMIT: pole_Premysla_Zavorace[b]=JS_OBJ_T_SUBMIT ; break;
case FC_RESET: pole_Premysla_Zavorace[b]=JS_OBJ_T_RESET ; break;
case FC_HIDDEN: pole_Premysla_Zavorace[b]=JS_OBJ_T_HIDDEN ; break;
case FC_BUTTON: pole_Premysla_Zavorace[b]=JS_OBJ_T_BUTTON ; break;
default: /* internal_error("Invalid form element type.\n"); */
(*len)--;
continue;
}
pole_Premysla_Zavorace[b]|=((fc2->g_ctrl_num)<<JS_OBJ_MASK_SIZE);
b++;
}
return pole_Premysla_Zavorace;
}
/* returns allocated field with anchors
* size of the field is stored in len
* when there're no anchors, *len is 0 and NULL is returned
* on error NULL is returned
*/
long *js_upcall_get_anchors(void *hej_Hombre, long document_id, int *len)
{
struct f_data_c *js_ctx=(struct f_data_c*)hej_Hombre;
struct f_data_c *fd;
int a;
long *to_je_Ono;
*len=0;
if (!js_ctx)internal_error("js_upcall_get_anchors called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
if (!(fd->f_data))return NULL;
*len = (int)list_size(&fd->f_data->tags);
if (!*len) return NULL;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
to_je_Ono = mem_alloc((*len)*sizeof(long));
for (a = 0; a < *len; a++)
to_je_Ono[a] = JS_OBJ_T_ANCHOR + (a << JS_OBJ_MASK_SIZE);
return to_je_Ono;
}
/* returns whether radio or checkbox is checked
* return value: 0=not checked
* 1=checked
* -1=error
*/
int js_upcall_get_checkbox_radio_checked(void *smirak, long document_id, long radio_tv_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)smirak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
int state;
if (!js_ctx)internal_error("js_upcall_get_checkbox_radio_checked called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
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 */
hopla=jsint_find_object(fd,radio_tv_id);
if (!hopla)return -1;
state=hopla->fs->state;
mem_free(hopla);
return state;
}
/* checks/unchecks radio or checkbox
*/
void js_upcall_set_checkbox_radio_checked(void *smirak, long document_id, long radio_tv_id, int value)
{
struct f_data_c *js_ctx=(struct f_data_c*)smirak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
if (!js_ctx)internal_error("js_upcall_set_checkbox_radio_checked called with NULL context pointer\n");
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 */
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
hopla=jsint_find_object(fd,radio_tv_id);
if (!hopla)return;
hopla->fs->state=!!value;
mem_free(hopla);
redraw_document(fd);
}
/* returns whether radio or checkbox is checked
* return value: 0=default not checked
* 1=default checked
* -1=error
*/
int js_upcall_get_checkbox_radio_default_checked(void *bidak_smirak, long document_id, long radio_tv_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak_smirak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
int default_checked;
if (!js_ctx)internal_error("js_upcall_get_checkbox_radio_default_checked called with NULL context pointer\n");
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 */
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
hopla=jsint_find_object(fd,radio_tv_id);
if (!hopla)return -1;
default_checked=hopla->fc->default_state;
mem_free(hopla);
return default_checked;
}
/* sets radio/checkbox default_checked in the form
*/
void js_upcall_set_checkbox_radio_default_checked(void *bidak_smirak, long document_id, long radio_tv_id, int value)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak_smirak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
int something_changed;
value=!!value;
if (!js_ctx)internal_error("js_upcall_set_checkbox_radio_default_checked called with NULL context pointer\n");
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 */
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return;
hopla=jsint_find_object(fd,radio_tv_id);
if (!hopla)return;
something_changed=(hopla->fc->default_state)^value;
hopla->fc->default_state=value;
fd->f_data->uncacheable|=something_changed;
mem_free(hopla);
}
/* returns allocated string with name of the form element
* don't forget to free the string after use
* on error returns NULL
*/
unsigned char *js_upcall_get_form_element_name(void *bidak, long document_id, long ksunt_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
unsigned char *hele_ho_bidaka;
if (!js_ctx)internal_error("js_upcall_get_form_element_name called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_RADIO:
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_SELECT:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_HIDDEN:
case JS_OBJ_T_BUTTON:
break;
default:
return NULL; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla)return NULL;
hele_ho_bidaka=stracpy(hopla->fc->name);
mem_free(hopla);
return hele_ho_bidaka;
}
/* sets name of the form element
* name is allocated string, this function deallocates it
*/
void js_upcall_set_form_element_name(void *bidak, long document_id, long ksunt_id, unsigned char *name)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
if (!js_ctx)internal_error("js_upcall_set_form_element_name called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_RADIO:
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_SELECT:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_HIDDEN:
case JS_OBJ_T_BUTTON:
break;
default:
if(name) mem_free(name);
return; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla){if (name)mem_free(name);return;}
if ((name||(hopla->fc->name))&&strcmp(cast_const_char name,cast_const_char hopla->fc->name))
{
mem_free(hopla->fc->name);
hopla->fc->name=stracpy(name);
fd->f_data->uncacheable=1;
}
mem_free(hopla);
if(name) mem_free(name);
}
/* returns allocated string with value of VALUE attribute of the form element
* on error returns NULL
* don't forget to free the string after use
*/
unsigned char *js_upcall_get_form_element_default_value(void *bidak, long document_id, long ksunt_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
unsigned char *hele_ho_bidaka;
if (!js_ctx)internal_error("js_upcall_get_form_element_default_value called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_RADIO:
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_SELECT:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_HIDDEN:
break;
default:
return NULL; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla)return NULL;
hele_ho_bidaka=convert(fd->f_data->opt.cp, fd->f_data->cp, hopla->fc->default_value, NULL);
mem_free(hopla);
return hele_ho_bidaka;
}
/* sets attribute VALUE of the form element
* name is allocated string that, this function frees it
* when name is NULL default value will be empty
*/
void js_upcall_set_form_element_default_value(void *bidak, long document_id, long ksunt_id, unsigned char *name)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
if (!js_ctx)internal_error("js_upcall_set_form_element_default_value called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_RADIO:
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_SELECT:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_HIDDEN:
break;
default:
if (name)mem_free(name);
return; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla){if (name)mem_free(name);return;}
if ((name||(hopla->fc->default_value))&&strcmp(cast_const_char name,cast_const_char hopla->fc->default_value))
{
mem_free(hopla->fc->default_value);
hopla->fc->default_value=convert(fd->f_data->cp, fd->f_data->opt.cp, name, NULL);
fd->f_data->uncacheable=1;
}
mem_free(hopla);
if (name)mem_free(name);
}
static unsigned char **get_js_event_ptr(struct js_event_spec **j, long type)
{
create_js_event_spec(j);
if (type == Conkeydown) return &(*j)->keydown_code;
else if (type == Conkeypress) return &(*j)->keypress_code;
else if (type == Conkeyup) return &(*j)->keyup_code;
else return NULL;
}
void js_upcall_set_form_element_event_handler(void *bidak, long document_id, long ksunt_id, long type, unsigned char *name)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
int i;
if (!js_ctx)internal_error("js_upcall_set_form_element_event_handler called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
if ((ksunt_id&JS_OBJ_MASK) == JS_OBJ_T_FRAME || (ksunt_id&JS_OBJ_MASK) == JS_OBJ_T_DOCUMENT) {
unsigned char **p = get_js_event_ptr(&fd->f_data->js_event, type);
if (!p) {
mem_free(name);
return;
}
if (*p) mem_free(*p);
*p = name;
fd->f_data->uncacheable=1;
return;
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla){if (name)mem_free(name);return;}
for (i = 0; i < fd->f_data->nlinks; i++) {
struct link *l = &fd->f_data->links[i];
if (l->form == hopla->fc) {
unsigned char **p = get_js_event_ptr(&l->js_event, type);
mem_free(hopla);
if (!p) {
mem_free(name);
return;
}
if (*p) mem_free(*p);
*p = name;
fd->f_data->uncacheable=1;
return;
}
}
mem_free(hopla);
mem_free(name);
}
/* returns allocated string with actual value of password, text or textarea element
* on error returns NULL
* don't forget to free the string after use
*/
unsigned char *js_upcall_get_form_element_value(void *bidak, long document_id, long ksunt_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
unsigned char *hele_ho_bidaka;
if (!js_ctx)internal_error("js_upcall_get_form_element_value called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
break;
default:
return NULL; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla)return NULL;
hele_ho_bidaka=convert(fd->f_data->opt.cp, fd->f_data->cp, hopla->fs->string, NULL);
mem_free(hopla);
return hele_ho_bidaka;
}
/* sets actual value of password, text or textarea element
* name is allocated string that, this function frees it
* when name is NULL default value will be empty
*/
void js_upcall_set_form_element_value(void *bidak, long document_id, long ksunt_id, unsigned char *name)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct hopla_mladej *hopla;
if (!js_ctx)internal_error("js_upcall_set_form_element_value called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd)){if (name)mem_free(name);return;}
fd=jsint_find_document(document_id);
switch (ksunt_id&JS_OBJ_MASK)
{
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
break;
default:
if (name)mem_free(name);
return; /* To neni Jim Beam! */
}
hopla=jsint_find_object(fd,ksunt_id);
if (!hopla){if (name)mem_free(name);return;}
free_format_text_cache_entry(hopla->fs);
mem_free(hopla->fs->string);
hopla->fs->string=convert(fd->f_data->cp, fd->f_data->opt.cp, name, NULL);
if ((size_t)hopla->fs->state > strlen(cast_const_char hopla->fs->string))
hopla->fs->state = strlen(cast_const_char hopla->fs->string);
if ((ksunt_id&JS_OBJ_MASK) != JS_OBJ_T_TEXTAREA) {
if ((size_t)hopla->fs->vpos > strlen(cast_const_char hopla->fs->string))
hopla->fs->vpos = strlen(cast_const_char hopla->fs->string);
}
mem_free(hopla);
if (name)mem_free(name);
redraw_document(fd);
}
/* emulates click on everything */
void js_upcall_click(void *bidak, long document_id, long elem_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
if (!js_ctx)internal_error("js_upcall_click called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
switch (elem_id&JS_OBJ_MASK)
{
case JS_OBJ_T_CHECKBOX:
case JS_OBJ_T_RADIO:
case JS_OBJ_T_SUBMIT:
case JS_OBJ_T_RESET:
case JS_OBJ_T_BUTTON:
{
struct hopla_mladej *hopla;
int a;
struct link *l;
if (!fd->f_data)return;
hopla=jsint_find_object(fd,elem_id);
if (!hopla)return;
for (a=0;a<fd->f_data->nlinks;a++)
{
l=&(fd->f_data->links[a]);
if (l->form&&l->form==hopla->fc) /* to je on! */
{
int old_link=fd->vs->current_link;
int old_orig_link=fd->vs->orig_link;
fd->vs->current_link=a;
fd->vs->orig_link=a;
enter(fd->ses,fd,0);
draw_fd(fd);
fd->vs->current_link=old_link;
fd->vs->orig_link=old_orig_link;
change_screen_status(fd->ses);
print_screen_status(fd->ses);
break;
}
}
mem_free(hopla);
}
break;
}
}
#ifdef G
static int find_go_link_num;
static struct g_object *to_je_on_bidak;
static void find_go(struct g_object *p, struct g_object *c)
{
if (c->draw == g_text_draw) {
struct g_object_text *t = get_struct(c, struct g_object_text, goti.go);
if (t->goti.link_num==find_go_link_num){to_je_on_bidak=c;return;}
}
if (c->get_list) c->get_list(c, find_go);
}
#endif
/* emulates focus on password, text and textarea */
void js_upcall_focus(void *bidak, long document_id, long elem_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
if (!js_ctx)internal_error("js_upcall_focus called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
switch (elem_id&JS_OBJ_MASK)
{
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
{
struct hopla_mladej *hopla;
int a;
struct link *l;
if (!fd->f_data)return;
hopla=jsint_find_object(fd,elem_id);
if (!hopla)return;
for (a=0;a<fd->f_data->nlinks;a++)
{
l=&(fd->f_data->links[a]);
if (l->form&&l->form==hopla->fc) /* to je on! */
{
struct session *ses = fd->ses;
/*int x = 0;*/
while (fd != current_frame(ses)) next_frame(ses, 1)/*, x = 1*/;
fd->vs->current_link=a;
fd->vs->orig_link=a;
if (fd->ses->term->spec->braille) {
if (fd->f_data->links[a].n) {
fd->vs->brl_x = fd->vs->orig_brl_x = fd->f_data->links[a].pos[0].x;
fd->vs->brl_y = fd->vs->orig_brl_y = fd->f_data->links[a].pos[0].y;
}
}
#ifdef G
if (F)
{
fd->ses->locked_link=1;
to_je_on_bidak=NULL;
find_go_link_num=a;
/* tak tedka tu budu carovat g_object_text, kterej patri k tomuhle linku */
if (fd->f_data->root->get_list)fd->f_data->root->get_list(fd->f_data->root,find_go);
fd->f_data->locked_on=to_je_on_bidak;
}
#endif
if (l->js_event&&l->js_event->focus_code)
jsint_execute_code(fd,l->js_event->focus_code,strlen(cast_const_char l->js_event->focus_code),-1,-1,-1, NULL);
/*draw_fd(fd);*/
draw_formatted(ses);
change_screen_status(fd->ses);
print_screen_status(fd->ses);
break;
}
}
mem_free(hopla);
}
break;
}
}
/* emulates focus on password, text and textarea */
void js_upcall_blur(void *bidak, long document_id, long elem_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
if (!js_ctx)internal_error("js_upcall_blur called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
/* in text mode do nothing, because we don't know where to go with cursor */
#ifdef G
if (F)
switch (elem_id&JS_OBJ_MASK)
{
case JS_OBJ_T_TEXT:
case JS_OBJ_T_PASSWORD:
case JS_OBJ_T_TEXTAREA:
{
struct hopla_mladej *hopla;
int a;
struct link *l;
if (!fd->f_data)return;
hopla=jsint_find_object(fd,elem_id);
if (!hopla)return;
for (a=0;a<fd->f_data->nlinks;a++)
{
l=&(fd->f_data->links[a]);
if (l->form&&l->form==hopla->fc) /* to je on! */
{
fd->ses->locked_link=0;
if (l->js_event&&l->js_event->blur_code)
jsint_execute_code(fd,l->js_event->blur_code,strlen(cast_const_char l->js_event->blur_code),-1,-1,-1, NULL);
/* pro jistotu */
draw_fd(fd);
change_screen_status(fd->ses);
print_screen_status(fd->ses);
break;
}
}
mem_free(hopla);
}
break;
}
#endif
}
/* emulates submit of a form */
void js_upcall_submit(void *bidak, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
struct form_control *form;
int has_onsubmit;
unsigned char *u;
if (!js_ctx)internal_error("js_upcall_submit called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
if (fd->ses->rq && fd->ses->defered_url) return;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return;
form=jsint_find_object(fd,form_id);
if (!form)return;
u=get_form_url(fd->ses,fd,form,&has_onsubmit);
if (u) {
goto_url_f(fd->ses,NULL,u,NULL,fd,form->form_num, has_onsubmit,0,0);
mem_free(u);
}
draw_fd(fd);
change_screen_status(fd->ses);
print_screen_status(fd->ses);
}
/* emulates reset of a form */
void js_upcall_reset(void *bidak, long document_id, long form_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)bidak;
struct f_data_c *fd;
if (!js_ctx)internal_error("js_upcall_reset called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
if ((form_id&JS_OBJ_MASK)!=JS_OBJ_T_FORM)return;
if (!fd->f_data)return;
reset_form(fd,form_id>>JS_OBJ_MASK_SIZE);
draw_fd(fd);
change_screen_status(fd->ses);
print_screen_status(fd->ses);
}
/* returns length (number of radio buttons) of a radio
* on error returns -1
*/
int js_upcall_get_radio_length(void *p, long document_id, long radio_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)p;
struct f_data_c *fd;
struct form_control *f;
struct list_head *lf;
struct hopla_mladej *hopla;
struct form_control *radio;
int count=0;
if (!js_ctx)internal_error("js_upcall_get_radio_length called with NULL context pointer\n");
if ((radio_id&JS_OBJ_MASK)!=JS_OBJ_T_RADIO) return -1;
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return -1;
hopla=jsint_find_object(fd,radio_id);
if (!hopla)return -1;
radio=hopla->fc;
/* find form elements with the same type, form_num (belonging to the same form) and name */
foreachback(struct form_control, f, lf, fd->f_data->forms)
if (f->type==radio->type&&f->form_num==radio->form_num&&!strcmp(cast_const_char radio->name,cast_const_char f->name))count++;
mem_free(hopla);
return count;
}
/* returns number of items in a select form element
* on error returns -1
*/
int js_upcall_get_select_length(void *p, long document_id, long select_id)
{
int l;
struct f_data_c *js_ctx=(struct f_data_c*)p;
struct f_data_c *fd;
struct hopla_mladej *hopla;
if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
hopla=jsint_find_object(fd,select_id);
if (!hopla)return -1;
l = hopla->fc->nvalues;
mem_free(hopla);
return l;
}
/* returns allocated field of select items
* don't forget to free: text and value of each item and the field
* on error returns NULL
* n is number of items in the field
*/
struct js_select_item* js_upcall_get_select_options(void *p, long document_id, long select_id, int *n)
{
struct f_data_c *js_ctx=(struct f_data_c*)p;
struct f_data_c *fd;
struct hopla_mladej *hopla;
struct js_select_item* elektricke_pole;
int ukazme_si_na_nej;
*n=0;
if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return NULL;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
hopla=jsint_find_object(fd,select_id);
if (!hopla)return NULL;
*n=hopla->fc->nvalues;
if ((unsigned)*n > MAXINT / sizeof(struct js_select_item)) overalloc();
elektricke_pole=mem_alloc((*n)*sizeof(struct js_select_item));
for (ukazme_si_na_nej=0;ukazme_si_na_nej<(*n);ukazme_si_na_nej++)
{
elektricke_pole[ukazme_si_na_nej].text=stracpy((hopla->fc->labels)[ukazme_si_na_nej]);
elektricke_pole[ukazme_si_na_nej].value=stracpy((hopla->fc->values)[ukazme_si_na_nej]);
elektricke_pole[ukazme_si_na_nej].selected=(ukazme_si_na_nej==(hopla->fs->state));
elektricke_pole[ukazme_si_na_nej].default_selected=(ukazme_si_na_nej==(hopla->fc->default_state));
}
mem_free(hopla);
return elektricke_pole;
}
/* returns index of just selected item in a select form element
* on error returns -1
*/
int js_upcall_get_select_index(void *p, long document_id, long select_id)
{
struct f_data_c *js_ctx=(struct f_data_c*)p;
struct f_data_c *fd;
struct hopla_mladej *hopla;
int l;
if (!js_ctx)internal_error("js_upcall_get_select_length called with NULL context pointer\n");
if ((select_id&JS_OBJ_MASK)!=JS_OBJ_T_SELECT) return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
hopla=jsint_find_object(fd,select_id);
if (!hopla)return -1;
l = hopla->fs->state;
mem_free(hopla);
return l;
}
struct gimme_js_id_string
{
long id;
long js_id;
unsigned char *string;
int n;
};
/* open a link in a new xterm */
static void send_vodevri_v_novym_vokne(struct terminal *term, void *open_window_, void *ses_)
{
int (*open_window)(struct terminal *, unsigned char *, unsigned char *) = *(int (* const *)(struct terminal *, unsigned char *, unsigned char *))open_window_;
struct session *ses = (struct session *)ses_;
if (ses->dn_url) {
unsigned char *enc_url = encode_url(ses->dn_url);
open_window(term, path_to_exe, enc_url);
mem_free(enc_url);
}
}
static void (* const send_vodevri_v_novym_vokne_ptr)(struct terminal *term, void *open_window_, void *ses_) = send_vodevri_v_novym_vokne;
/* aux function for js_upcall_goto_url */
static void js_upcall_goto_url_ok_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id_string *jsid=(struct gimme_js_id_string*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
/* it doesn't matter, that fd->js is NULL */
if (jsid->n&&can_open_in_new(fd->ses->term)) /* open in new window */
{
if (fd->ses->dn_url) mem_free(fd->ses->dn_url);
fd->ses->dn_url=stracpy(jsid->string);
open_in_new_window(fd->ses->term, (void *)&send_vodevri_v_novym_vokne_ptr, fd->ses);
}
else
goto_url(fd->ses,jsid->string);
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
}
/* aux function for js_upcall_goto_url */
static void js_upcall_goto_url_cancel_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id *jsid=(struct gimme_js_id*)data;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
if (!(fd->js)||jsid->js_id!=fd->js->ctx->js_id)return;
js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
}
/* gets struct fax_me_tender_int_string */
/* asks user whether to go to the url or not */
/* structure and the text are both deallocated */
/* must be called from select loop */
/* if num in fax_me_tender_int_string is not null, open in a new window */
void js_upcall_goto_url(void * data)
{
struct fax_me_tender_int_string *s=(struct fax_me_tender_int_string*)data;
struct f_data_c *fd;
struct terminal *term;
unsigned char *dest_url;
int in_new_win;
fd=(struct f_data_c*)(s->ident);
term=fd->ses->term;
if (!fd->js) return;
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
if (!s)internal_error("js_upcall_goto_url called with NULL pointer\n");
if (!s->string){js_mem_free(data);goto goto_url_failed;}
if (fd->loc&&fd->loc->url) dest_url=join_urls(fd->loc->url,s->string);
else dest_url=stracpy(s->string);
if (!(dest_url)){js_mem_free(s->string);js_mem_free(data);goto goto_url_failed;}
js_mem_free(s->string);
in_new_win=s->num;
if (js_manual_confirmation)
{
struct gimme_js_id_string* jsid;
/* goto the same url */
{
unsigned char txt[MAX_STR_LEN];
void *p;
p=get_current_url(fd->ses,txt,MAX_STR_LEN);
if (p&&fd->loc&&fd->loc->url&&!strcmp(cast_const_char txt,cast_const_char dest_url))
{
mem_free(dest_url);
js_mem_free(data);
goto goto_url_failed;
}
}
jsid=mem_alloc(sizeof(struct gimme_js_id_string));
/* context must be a valid pointer ! */
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
jsid->string=dest_url;
jsid->n=s->num;
msg_box(
term, /* terminal */
getml(jsid->string,jsid,NULL), /* memory blocks to free */
TEXT_(T_GOTO_URL), /* title */
AL_CENTER, /* alignment */
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 */
(void *)jsid, /* data for button functions */
3, /* # of buttons */
TEXT_(T_ALLOW),js_upcall_goto_url_ok_pressed,B_ENTER,
TEXT_(T_REJECT),js_upcall_goto_url_cancel_pressed,B_ESC,
TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL /* dirty trick: gimme_js_id_string and gimme_js_id begins with the same long */
);
js_mem_free(s);
}
else
{
js_mem_free(s);
if (in_new_win&&can_open_in_new(fd->ses->term)) /* open in new window */
{
if (fd->ses->dn_url) mem_free(fd->ses->dn_url);
fd->ses->dn_url=stracpy(dest_url);
open_in_new_window(fd->ses->term, (void *)&send_vodevri_v_novym_vokne_ptr, fd->ses);
}
else
goto_url(fd->ses,dest_url);
js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
mem_free(dest_url);
}
return;
goto_url_failed:
js_downcall_vezmi_null(fd->js->ctx); /* call downcall */
return;
}
/* returns number of items in history */
int js_upcall_get_history_length(void *context)
{
struct f_data_c *fd=(struct f_data_c*)context;
if (!fd)internal_error("PerMe, PerMe, ja si te podam!\n");
return (int)list_size(&fd->ses->history);
}
/* aux function for js_upcall_goto_history */
static void js_upcall_goto_history_ok_pressed(void *data)
{
struct f_data_c *fd;
struct gimme_js_id_string *jsid=(struct gimme_js_id_string*)data;
int a;
fd=jsint_find_document(jsid->id);
if (!fd)return; /* context no longer exists */
a = (int)list_size(&fd->ses->history);
if (a<jsid->n&&(fd->js)&&jsid->js_id==fd->js->ctx->js_id){js_downcall_vezmi_null(fd->js->ctx);return;} /* call downcall */
go_backwards(fd->ses->term,(void*)(my_intptr_t)(jsid->n),fd->ses);
}
/* gets struct fax_me_tender_int_string
* either num or string is set, but not both, the other must be NULL
* asks user whether to go to the url or not
* structure and the text are both deallocated
* must be called from select loop
* number can be:
* >0 go forward in history (not supported)
* 0 do nothing (means use string)
* <0 go backward in history (supported :) )
* if string is defined - find appropriate history item and go to the url, when
* the URL doesn't exist do nothing
*
* JAK TO FUNGUJE:
* string se prekonvertuje na cislo (projde se historie)
* po zmacknuti OK se spocita delka historie a pokud je dostatecna, n-krat
* zavola go_back. Pokud neni, tak se chovame jako pri cancelu.
*/
void js_upcall_goto_history(void * data)
{
struct fax_me_tender_int_string *s=(struct fax_me_tender_int_string*)data;
struct f_data_c *fd;
struct terminal *term;
unsigned char *url=NULL;
unsigned char txt[16];
long history_num=0;
/* context must be a valid pointer ! */
fd=(struct f_data_c*)(s->ident);
if (!fd->js) return;
/* kill timer, that called me */
js_spec_vykill_timer(fd->js->ctx,0);
if (!s)internal_error("Hele, tyhle prasarny si zkousej na nekoho jinyho, jo?!\n");
if (!(s->num)&&!(s->string))internal_error("Tak tohle na mne nezkousej, bidaku!\n");
if ((s->num)&&(s->string))internal_error("Ta sedla!\n");
/* find the history item */
if (s->num) /* goto n-th item */
{
struct location *loc;
struct list_head *lloc;
int a=0;
if ((s->num)>0){if (s->string)js_mem_free(s->string);js_mem_free(data);goto goto_history_failed;} /* forward not supported */
s->num=-s->num;
history_num=s->num;
foreach(struct location, loc, lloc, fd->ses->history) {
if (a==s->num){url=stracpy(loc->url);break;}
a++;
}
}
else /* goto given url */
{
struct location *loc;
struct list_head *lloc;
int a=0;
foreach(struct location, loc, lloc, fd->ses->history) {
if (!strcmp(cast_const_char s->string,cast_const_char loc->url)){url=stracpy(s->string);history_num=a;break;}
a++;
}
}
if (s->string)js_mem_free(s->string);
if (!url){js_mem_free(data);goto goto_history_failed;}
term=fd->ses->term;
if (js_manual_confirmation)
{
struct gimme_js_id_string* jsid;
jsid=mem_alloc(sizeof(struct gimme_js_id_string));
/* fill in jsid */
jsid->id=((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT;
jsid->js_id=fd->js->ctx->js_id;
jsid->string=url;
jsid->n=history_num;
snprintf(txt,16," (-%d) ",jsid->n);
msg_box(
term, /* terminal */
getml(url,jsid,NULL), /* memory blocks to free */
TEXT_(T_GOTO_HISTORY), /* title */
AL_CENTER, /* alignment */
TEXT_(T_JS_IS_ATTEMPTING_TO_GO_INTO_HISTORY), txt, TEXT_(T_TO_URL), " \"",url,"\".",MSG_BOX_END, /* message */
(void *)jsid, /* data for button functions */
3, /* # of buttons */
TEXT_(T_ALLOW),js_upcall_goto_history_ok_pressed,B_ENTER,
TEXT_(T_REJECT),js_upcall_goto_url_cancel_pressed,B_ESC,
TEXT_(T_KILL_SCRIPT), js_kill_script_pressed,NULL /* dirty trick: gimme_js_id_string and gimme_js_id begins with the same long */
);
js_mem_free(s);
}
else
{
js_mem_free(s);
mem_free(url);
go_backwards(term,(void*)(history_num),fd->ses);
}
return;
goto_history_failed:
js_downcall_vezmi_null(fd->js->ctx);
return;
}
/* set default status-line text
* tak_se_ukaz_Kolbene is allocated string or NULL
*/
void js_upcall_set_default_status(void *context, unsigned char *tak_se_ukaz_Kolbene)
{
struct f_data_c *fd=(struct f_data_c*)context;
unsigned char *trouba;
if (!fd)internal_error("Tak tohle teda ne, bobanku!\n");
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... */
if (fd->ses->default_status)mem_free(fd->ses->default_status);
skip_nonprintable(tak_se_ukaz_Kolbene);
if (fd->f_data&&tak_se_ukaz_Kolbene)
{
/* ... a ted ty pochybne reci o majetku ... */
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! */
mem_free(tak_se_ukaz_Kolbene);
/* a je to v troube... */
}
else
{
trouba=tak_se_ukaz_Kolbene;
}
fd->ses->default_status=trouba;
change_screen_status(fd->ses);
print_screen_status(fd->ses);
}
/* returns allocated string with default status-line value or NULL when default value is empty
*/
unsigned char* js_upcall_get_default_status(void *context)
{
struct f_data_c *fd=(struct f_data_c *)context;
unsigned char *tak_se_ukaz_Danku=NULL;
unsigned char *trouba;
if (!fd)internal_error("Ale hovno!\n");
if (fd->ses->default_status&&(*fd->ses->default_status))tak_se_ukaz_Danku=stracpy(fd->ses->default_status);
skip_nonprintable(tak_se_ukaz_Danku);
if (fd->f_data&&tak_se_ukaz_Danku)
{
trouba=convert(fd->f_data->opt.cp, fd->f_data->cp, tak_se_ukaz_Danku, NULL);
mem_free(tak_se_ukaz_Danku);
}
else
{
trouba=tak_se_ukaz_Danku;
}
/* Tak to mame Kolben a Danek po peti korunach... */
return trouba; /* No jo, je to v troube! */
}
/* set status-line text
* tak_se_ukaz_Kolbene is allocated string or NULL
*/
void js_upcall_set_status(void *context, unsigned char *tak_se_ukaz_Kolbene)
{
struct f_data_c *fd=(struct f_data_c*)context;
unsigned char *trouba;
if (!fd)internal_error("To leda tak -PRd!\n");
if (!(*tak_se_ukaz_Kolbene)){mem_free(tak_se_ukaz_Kolbene);tak_se_ukaz_Kolbene=NULL;}
if (fd->ses->st)mem_free(fd->ses->st);
skip_nonprintable(tak_se_ukaz_Kolbene);
if (fd->f_data&&tak_se_ukaz_Kolbene)
{
trouba=convert(fd->f_data->cp, fd->f_data->opt.cp, tak_se_ukaz_Kolbene, NULL);
mem_free(tak_se_ukaz_Kolbene);
/* a je to v troube... */
}
else
{
trouba=tak_se_ukaz_Kolbene;
}
fd->ses->st=trouba;
print_screen_status(fd->ses);
}
/* returns allocated string with default status-line value or NULL when default value is empty
*/
unsigned char* js_upcall_get_status(void *context)
{
struct f_data_c *fd=(struct f_data_c *)context;
unsigned char *tak_se_ukaz_Danku=NULL;
unsigned char *trouba;
if (!fd)internal_error("To leda tak hovno!\n");
if (fd->ses->st&&(*fd->ses->st))tak_se_ukaz_Danku=stracpy(fd->ses->st);
skip_nonprintable(tak_se_ukaz_Danku);
if (fd->f_data&&tak_se_ukaz_Danku)
{
trouba=convert(fd->f_data->opt.cp, fd->f_data->cp, tak_se_ukaz_Danku, NULL);
mem_free(tak_se_ukaz_Danku);
}
else
{
trouba=tak_se_ukaz_Danku;
}
/* Kolben a Danek, to mame po peti korunach... */
return trouba;
}
/* returns allocated string with cookies, or NULL on error */
unsigned char * js_upcall_get_cookies(void *context)
{
struct f_data_c *fd=(struct f_data_c *)context;
unsigned char *s=init_str();
int l=0;
int nc=0;
time_t now;
struct cookie *c;
struct list_head *lc;
unsigned char *server, *data;
struct c_domain *cd;
struct list_head *lcd;
if (!fd)internal_error("Tak tomu rikam selhani komunikace...\n");
/* zavolame set_cookies, ten zparsuje fd->js->ctx->cookies a necha tam nezparsovatelnej zbytek */
if (!fd->js||!fd->js->ctx) {mem_free(s);return NULL;}
if (!fd->rq) goto ty_uz_se_nevratis;
jsint_set_cookies(fd,0);
server = get_host_name(fd->rq->url);
data = get_url_data(fd->rq->url);
if (data > fd->rq->url) data--;
foreach(struct c_domain, cd, lcd, c_domains) if (is_in_domain(cd->domain, server)) goto ok;
mem_free(server);
ty_uz_se_nevratis:
if (fd->js->ctx->cookies)add_to_str(&s,&l,fd->js->ctx->cookies);
else {mem_free(s);s=NULL;}
return s;
ok:
now = get_absolute_seconds();
foreach(struct cookie, c, lc, all_cookies) if (is_in_domain(c->domain, server)) if (is_path_prefix(c->path, data)) {
if (cookie_expired(c, now)) {
lc = lc->prev;
del_from_list(c);
free_cookie(c);
continue;
}
if (c->secure) continue;
if (!nc) nc = 1;
else add_to_str(&s, &l, "; ");
add_to_str(&s, &l, c->name);
if (c->value) {
add_to_str(&s, &l, "=");
add_to_str(&s, &l, c->value);
}
}
if (!nc) {mem_free(s);s=NULL;}
mem_free(server);
/* za strinzik sestaveny z vnitrni reprezentace susenek jeste prilepime nezparsovatelnej zbytek */
if (fd->js->ctx->cookies)
{
if (!s)s=stracpy(fd->js->ctx->cookies);
else {add_to_str(&s,&l,"; ");add_to_str(&s,&l,fd->js->ctx->cookies);}
}
/*debug("get_cookies: \"%s\"", s);*/
return s;
}
/* FIXME: document.all nechodi, musi se prepsat, aby vracel dvojice frame:idcko */
/* adds all in given f_data_c, the f_data_c must be accessible by the javascript */
static void add_all_recursive_in_fd(long **field, int *len, struct f_data_c *fd, struct f_data_c *js_ctx)
{
struct f_data_c *ff;
struct list_head *lff;
struct form_control *fc;
struct list_head *lfc;
/* add all accessible frames */
foreach(struct f_data_c, ff, lff, fd->subframes)
if (jsint_can_access(js_ctx,ff))
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;
if (!(fd->f_data))goto tady_uz_nic_peknyho_nebude;
#ifdef G
/* add all images */
if (F) {
struct g_object_image *gi;
struct list_head *lgi;
foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
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;
}
}
#endif
/* add all forms */
foreachback(struct form_control, fc, lfc, fd->f_data->forms)
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;
/* add all form elements */
foreachback(struct form_control, fc, lfc, fd->f_data->forms)
{
long tak_mu_to_ukaz=0;
tak_mu_to_ukaz=(fc->g_ctrl_num)<<JS_OBJ_MASK_SIZE;
switch (fc->type)
{
case FC_TEXT: tak_mu_to_ukaz|=JS_OBJ_T_TEXT; break;
case FC_PASSWORD: tak_mu_to_ukaz|=JS_OBJ_T_PASSWORD; break;
case FC_TEXTAREA: tak_mu_to_ukaz|=JS_OBJ_T_TEXTAREA; break;
case FC_CHECKBOX: tak_mu_to_ukaz|=JS_OBJ_T_CHECKBOX; break;
case FC_RADIO: tak_mu_to_ukaz|=JS_OBJ_T_RADIO; break;
case FC_IMAGE:
case FC_SELECT: tak_mu_to_ukaz|=JS_OBJ_T_SELECT; break;
case FC_SUBMIT: tak_mu_to_ukaz|=JS_OBJ_T_SUBMIT ; break;
case FC_RESET: tak_mu_to_ukaz|=JS_OBJ_T_RESET ; break;
case FC_HIDDEN: tak_mu_to_ukaz|=JS_OBJ_T_HIDDEN ; break;
case FC_BUTTON: tak_mu_to_ukaz|=JS_OBJ_T_BUTTON ; break;
default:/* internal_error("Invalid form element type.\n"); */
tak_mu_to_ukaz=0;break;
}
if (tak_mu_to_ukaz&&!((*field)=add_fd_id(*field,len,js_upcall_get_frame_id(fd),tak_mu_to_ukaz,fc->name)))return;
}
tady_uz_nic_peknyho_nebude:
foreach(struct f_data_c, ff, lff, fd->subframes)
if (jsint_can_access(js_ctx,ff)) add_all_recursive_in_fd(field,len,ff,js_ctx);
}
/* returns allocated field of all objects in the document (document.all)
* size of the field will be stored in len
* the field has 3x more items than the number of objects
* field[x+0]==id of frame
* field[x+1]==id of the object
* field[x+2]==allocated unsigned char* with name of the object or NULL (when there's no name)
*
* when an error occurs, returns NULL
*/
long * js_upcall_get_all(void *chuligane, long document_id, int *len)
{
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
long *pole_neorane; /* Premysle Zavoraci, kde se flakas? Zase forbesis, co? */
struct f_data_c *fd;
if (!js_ctx)internal_error("js_upcall_get_all called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
*len=0;
pole_neorane=mem_alloc(sizeof(long));
add_all_recursive_in_fd(&pole_neorane,len,fd,js_ctx);
/* nothing was found */
if (!pole_neorane)return NULL;
if (!(*len))mem_free(pole_neorane),pole_neorane=NULL;
return pole_neorane;
}
/* returns allocated field of all images
* size of the field will be stored in len
* when an error occurs, returns NULL
*/
long *js_upcall_get_images(void *chuligane, long document_id, int *len)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
long *pole_Premysla_Zavorace;
int a;
if (F) {
struct g_object_image *gi;
struct list_head *lgi;
if (!js_ctx)internal_error("js_upcall_get_images called with NULL context pointer\n");
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return NULL;
*len = list_size(&fd->f_data->images);
if (!(*len))return NULL;
if ((unsigned)*len > MAXINT / sizeof(long)) overalloc();
pole_Premysla_Zavorace=mem_alloc((*len)*sizeof(long));
a=0;
foreach(struct g_object_image, gi, lgi, fd->f_data->images) {
unsigned id = gi->id;;
pole_Premysla_Zavorace[a]=JS_OBJ_T_IMAGE+(id<<JS_OBJ_MASK_SIZE);
a++;
}
return pole_Premysla_Zavorace;
} else
#endif
{
document_id=document_id;
*len=0;
return NULL;
}
}
/* returns width of given image or -1 on error */
int js_upcall_get_image_width(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct f_data_c *fd;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_width called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
return gi->goti.go.xw;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns height of given image or -1 on error */
int js_upcall_get_image_height(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct f_data_c *fd;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_height called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
return gi->goti.go.yw;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns border of given image or -1 on error */
int js_upcall_get_image_border(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_border called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
return gi->border;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns vspace of given image or -1 on error */
int js_upcall_get_image_vspace(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_vspace called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
return gi->vspace;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns hspace of given image or -1 on error */
int js_upcall_get_image_hspace(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_hspace called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
return gi->hspace;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns allocated string with name of given image or NULL on error */
unsigned char * js_upcall_get_image_name(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_name called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
gi=jsint_find_object(fd,image_id);
if (!gi)return NULL;
return stracpy(gi->name);
}else
#endif
{
document_id=document_id;
image_id=image_id;
return NULL;
}
}
/* returns allocated string with name of given image or NULL on error */
unsigned char * js_upcall_get_image_alt(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_alt called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
gi=jsint_find_object(fd,image_id);
if (!gi)return NULL;
return stracpy(gi->alt);
}else
#endif
{
chuligane=chuligane;
document_id=document_id;
image_id=image_id;
return NULL;
}
}
/* sets image name to given value */
/* name is deallocated after use with mem_free */
void js_upcall_set_image_name(void *chuligane, long document_id, long image_id, unsigned char *name)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_set_image_name called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return;
gi=jsint_find_object(fd,image_id);
if (!gi)return;
if (gi->name)mem_free(gi->name);
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 */
if (name)mem_free(name);
return;
}else
#endif
{
chuligane=chuligane;
document_id=document_id;
image_id=image_id;
if (name)mem_free(name);
return;
}
}
/* sets image alt to given value */
/* alt is deallocated after use with mem_free */
void js_upcall_set_image_alt(void *chuligane, long document_id, long image_id, unsigned char *alt)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_set_image_alt called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return;
fd=jsint_find_document(document_id);
if (!fd||!fd->f_data||!jsint_can_access(js_ctx,fd))return;
gi=jsint_find_object(fd,image_id);
if (!gi)return;
if (gi->alt)mem_free(gi->alt);
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 */
if (fd->f_data&&gi->goti.link_num>=0&&gi->goti.link_num<fd->f_data->nlinks)
{
struct link *l=&fd->f_data->links[gi->goti.link_num];
if (l->img_alt)mem_free(l->img_alt);
l->img_alt=stracpy(alt);
}
if (alt)mem_free(alt);
change_screen_status(fd->ses);
print_screen_status(fd->ses);
return;
}else
#endif
{
chuligane=chuligane;
document_id=document_id;
image_id=image_id;
if (alt)mem_free(alt);
return;
}
}
/* returns allocated string with source URL of given image or NULL on error */
unsigned char * js_upcall_get_image_src(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_get_image_src called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return NULL;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
gi=jsint_find_object(fd,image_id);
if (!gi)return NULL;
return stracpy(gi->orig_src);
}else
#endif
{
document_id=document_id;
image_id=image_id;
return NULL;
}
}
/* changes image URL
* gets struct fax_me_tender_string_2_longy
* num1 = document_id, num2 = image_id, string = url
*
* frees the string and the fax_me_tender struct with js_mem_free function
*/
void js_upcall_set_image_src(void *chuligane)
{
unsigned char *zvrat;
struct fax_me_tender_string_2_longy *fax=(struct fax_me_tender_string_2_longy*)chuligane;
struct f_data_c *js_ctx;
#ifdef G
struct f_data_c *fd;
struct g_object_image *gi;
long image_id,document_id;
unsigned char *vecirek;
if (F)
{
js_ctx=(struct f_data_c*)fax->ident;
js_spec_vykill_timer(js_ctx->js->ctx,0);
if (!chuligane)internal_error("js_upcall_set_image_src called with NULL argument\n");
if (!js_ctx)internal_error("js_upcall_set_image_src called with NULL context pointer\n");
image_id=fax->obj_id;
document_id=fax->doc_id;
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)goto abych_tu_nepovecerel;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))goto abych_tu_nepovecerel;
gi=jsint_find_object(fd,image_id);
if (!gi||!fd->f_data)goto abych_tu_nepovecerel;
/* string joinnem s url */
if (fd->f_data&&fd->f_data->script_href_base) vecirek=join_urls(fd->f_data->script_href_base,fax->string);
else if (fd->loc&&fd->loc->url) vecirek=join_urls(fd->loc->url,fax->string);
else vecirek=stracpy(fax->string);
/* a mame to kompatidebilni s verzi pred jointem */
change_image(gi,vecirek,fax->string,fd->f_data);
if (vecirek) mem_free(vecirek);
fd->f_data->uncacheable = 1;
abych_tu_nepovecerel:;
}else
#endif
{
js_ctx=(struct f_data_c*)fax->ident;
if (!js_ctx)internal_error("js_upcall_set_image_src called with NULL context pointer\n");
js_spec_vykill_timer(js_ctx->js->ctx,0);
if (!chuligane)internal_error("js_upcall_set_image_src called with NULL argument\n");
}
zvrat=stracpy(fax->string);
js_mem_free(fax->string);
js_mem_free(fax);
js_downcall_vezmi_string(js_ctx->js->ctx,zvrat);
}
/* returns 1 if image has completed loading, 0 when not, -1 on error */
int js_upcall_image_complete(void *chuligane, long document_id, long image_id)
{
#ifdef G
struct f_data_c *fd;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct g_object_image *gi;
if (F)
{
if (!js_ctx)internal_error("js_upcall_image_complete called with NULL context pointer\n");
if ((image_id&JS_OBJ_MASK)!=JS_OBJ_T_IMAGE)return -1;
fd=jsint_find_document(document_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
gi=jsint_find_object(fd,image_id);
if (!gi)return -1;
if (!gi->af||!gi->af->rq||!gi->af->rq->state)return -1;
return gi->af->rq->state==O_OK;
}else
#endif
{
document_id=document_id;
image_id=image_id;
return -1;
}
}
/* returns parent of given frame (or document), or -1 on error or no permissions */
/* if frame_id is already top frame returns the same frame */
long js_upcall_get_parent(void *chuligane, long frame_id)
{
struct f_data_c *fd, *ff;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
if (!js_ctx)internal_error("js_upcall_get_parent called with NULL context pointer\n");
if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return -1;
fd=jsint_find_document(frame_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
for (ff=fd->parent;ff&&!ff->rq;ff=ff->parent);
if (!ff)ff=fd->ses->screen;
return jsint_can_access(fd,ff)?js_upcall_get_frame_id(ff):-1;
}
/* returns top of given frame (or document), or -1 on error */
/* returns highest grandparent accessible from given frame */
long js_upcall_get_frame_top(void *chuligane, long frame_id)
{
struct f_data_c *fd, *ff;
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
if (!js_ctx)internal_error("js_upcall_get_frame_top called with NULL context pointer\n");
if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return -1;
fd=jsint_find_document(frame_id);
if (!fd||!jsint_can_access(js_ctx,fd))return -1;
for (ff=fd->parent;ff;ff=ff->parent)
{
if (ff->rq)
{
if (!jsint_can_access(fd,ff))break;
fd=ff;
}
}
return js_upcall_get_frame_id(fd);
}
/* returns allocated field of subframes or NULL on error */
/* count cointains length of the field */
/* don't forget to free the field after use */
long * js_upcall_get_subframes(void *chuligane, long frame_id, int *count)
{
struct f_data_c *js_ctx=(struct f_data_c*)chuligane;
struct f_data_c *fd;
struct f_data_c *f;
struct list_head *lf;
int a;
long *pole;
*count=0;
if (!js_ctx)internal_error("js_upcall_get_subframes called with NULL context pointer\n");
if ((frame_id&JS_OBJ_MASK)!=JS_OBJ_T_FRAME&&(frame_id&JS_OBJ_MASK)!=JS_OBJ_T_DOCUMENT)return NULL;
fd=jsint_find_document(frame_id);
if (!fd||!jsint_can_access(js_ctx,fd))return NULL;
foreach(struct f_data_c, f, lf, fd->subframes)
if (jsint_can_access(fd,f)) (*count)++;
if (!*count)return NULL;
if ((unsigned)*count > MAXINT / sizeof(long)) overalloc();
pole=mem_alloc((*count)*sizeof(long));
a=0;
foreach(struct f_data_c, f, lf, fd->subframes)
if (jsint_can_access(fd,f))
{pole[a]=js_upcall_get_frame_id(f);a++;}
return pole;
}
/*--------------------- DOWNCALLS ---------------------------*/
void js_downcall_game_over(void *context)
{
struct f_data_c *fd=(struct f_data_c*)(((js_context*)(context))->ptr);
/* js_error(get_text_translation(TEXT_(T_SCRIPT_KILLED_BY_USER),fd->ses->term),context);
* Tato hlaska me srala. Na to bych neprisel, ze jsem prave zabil
* rucne javascript. */
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 */
jsint_destroy(fd);
#if 0
js_durchfall=0;
if(((js_context*)context)->running)
js_volej_kolbena(context);
/* Kolben - ale nespi mi - co s tim budeme delat? */
((js_context*)context)->running=0;
#endif
}
void js_downcall_vezmi_int(void *context, int i)
{
}
void js_downcall_vezmi_float(void *context, float f)
{
}
#else
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)
{
}
void jsint_destroy(struct f_data_c *fd)
{
}
void jsint_scan_script_tags(struct f_data_c *fd)
{
}
int jsint_get_source(struct f_data_c *fd, unsigned char **start, size_t *len)
{
return 0;
}
#endif