3926 lines
109 KiB
C
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
|