char *nullgen(Panel *, int);
Field *newfield(Form *form){
Field *f;
- f=emallocz(sizeof(Field), 1);
+ f=emalloc(sizeof(Field));
if(form->efields==0)
form->fields=f;
else
htmlerror(g->name, g->lineno, "nested forms illegal\n");
break;
}
- g->form=emallocz(sizeof(Form), 1);
+ g->form=emalloc(sizeof(Form));
s=pl_getattr(g->attr, "action");
- g->form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
+ g->form->action=strdup((s && *s) ? s : g->dst->url->fullname);
s=pl_getattr(g->attr, "method");
- if(s==0)
+ if(s==0 || *s==0)
g->form->method=GET;
else if(cistrcmp(s, "post")==0)
g->form->method=POST;
g->form->next = g->dst->form;
g->dst->form = g->form;
-
break;
case Tag_input:
case Tag_button:
if(g->form==0){
- BadTag:
- htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n",
- tag[g->tag].name);
- break;
- }
- f=newfield(g->form);
+ /* no form, assume link button */
+ form = emalloc(sizeof(Form));
+ form->method = 0;
+ form->fields = 0;
+ form->efields = 0;
+ if(g->state->link[0])
+ form->action = strdup(g->state->link);
+ form->next = g->dst->form;
+ g->dst->form = form;
+ f=newfield(form);
+ } else
+ f=newfield(g->form);
s=pl_getattr(g->attr, "name");
- if(s==0)
+ if(s==0 || *s == 0)
f->name=0;
else
f->name=strdup(s);
f->value=strdup(s);
f->checked=pl_hasattr(g->attr, "checked");
s=pl_getattr(g->attr, "size");
- if(s==0)
+ if(s==0 || *s==0)
f->size=20;
else
f->size=atoi(s);
s=pl_getattr(g->attr, "maxlength");
- if(s==0)
+ if(s==0 || *s==0)
f->maxlength=0x3fffffff;
else
f->maxlength=atoi(s);
f->type=RADIO;
else if(cistrcmp(s, "submit")==0)
f->type=SUBMIT;
+ else if(cistrcmp(s, "image")==0){
+ f->type=SUBMIT;
+ s=pl_getattr(g->attr, "src");
+ if(s && *s)
+ nstrcpy(g->state->image, s, sizeof(g->state->image));
+ s=pl_getattr(g->attr, "width");
+ if(s && *s)
+ g->state->width=strtolength(g, HORIZ, s);
+ s=pl_getattr(g->attr, "height");
+ if(s && *s)
+ g->state->height=strtolength(g, VERT, s);
+ s=pl_getattr(g->attr, "alt");
+ if(s==0 || *s == 0) s = f->value;
+ pl_htmloutput(g, g->nsp, s, f);
+ g->state->image[0] = 0;
+ g->state->width=0;
+ g->state->height=0;
+ break;
+ }
else if(cistrcmp(s, "button")==0)
f->type=BUTTON;
- else if(cistrcmp(s, "image")==0)
- f->type=FILE;
else if(cistrcmp(s, "file")==0)
f->type=FILE;
else if(cistrcmp(s, "reset")==0)
f->type=TYPEIN;
if(cistrcmp(s, "password")==0)
f->type=PASSWD;
-
s=f->name;
if(s && cistrcmp(s, "isindex")==0)
f->type=INDEX;
pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f);
break;
case Tag_select:
- if(g->form==0) goto BadTag;
+ if(g->form==0){
+ BadTag:
+ htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n",
+ tag[g->tag].name);
+ break;
+ }
f=newfield(g->form);
s=pl_getattr(g->attr, "name");
- if(s==0){
+ if(s==0 || *s==0){
f->name=strdup("select");
htmlerror(g->name, g->lineno, "select has no name=\n");
}
else
f->name=strdup(s);
- s=pl_getattr(g->attr, "size");
- if(s==0) f->size=4;
- else{
- f->size=atoi(s);
- if(f->size<=0) f->size=1;
- }
f->multiple=pl_hasattr(g->attr, "multiple");
f->type=SELECT;
+ f->size=0;
f->options=0;
g->text=g->token;
g->tp=g->text;
case Tag_option:
if(g->form==0) goto BadTag;
if((f=g->form->efields)==0) goto BadTag;
- o=emallocz(sizeof(Option), 1);
+ if(f->size<8)
+ f->size++;
+ o=emalloc(sizeof(Option));
for(op=&f->options;*op;op=&(*op)->next);
*op=o;
o->next=0;
if(g->form==0) goto BadTag;
f=newfield(g->form);
s=pl_getattr(g->attr, "name");
- if(s==0){
+ if(s==0 || *s==0){
f->name=strdup("enter text");
htmlerror(g->name, g->lineno, "select has no name=\n");
}
else
f->name=strdup(s);
s=pl_getattr(g->attr, "rows");
- f->rows=s?atoi(s):8;
+ f->rows=(s && *s)?atoi(s):8;
s=pl_getattr(g->attr, "cols");
- f->cols=s?atoi(s):30;
+ f->cols=(s && *s)?atoi(s):30;
f->type=TEXTWIN;
/* suck up initial text */
pl_htmloutput(g, g->nsp, f->name, f);
form->fields=0;
form->efields=0;
s=pl_getattr(g->attr, "action");
- form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
+ form->action=strdup((s && *s) ? s : g->dst->url->fullname);
form->method=GET;
form->fields=0;
f=newfield(form);
f->p=plbutton(0, 0, f->value[0]?f->value:"file", h_fileinput);
break;
case SELECT:
+ if(f->size <= 0)
+ f->size=1;
f->pulldown=plgroup(0,0);
scrl=plscrollbar(f->pulldown, PACKW|FILLY);
win=pllist(f->pulldown, PACKN, nullgen, f->size, h_select);
f->p=plframe(0,0);
pllabel(f->p, PACKN|FILLX, f->name);
scrl=plscrollbar(f->p, PACKW|FILLY);
- f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height),
- 0, 0, 0);
+ f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), 0, 0, 0);
f->textwin->userp=f;
plscroll(f->textwin, 0, scrl);
break;
free(t->text);
t->text=0;
t->p=f->p;
- t->hot=1;
+ t->flags|=PL_HOT;
}
}
void h_checkinput(Panel *p, int, int v){
case PASSWD:
plinitentry(f->p, USERFL, f->size*chrwidth, f->value, 0);
break;
+ case FILE:
+ free(f->value);
+ f->value=strdup("");
+ if(f->p==nil) break;
+ f->p->state=0;
+ pldraw(f->p, screen);
+ break;
case CHECK:
case RADIO:
f->state=f->checked;
}
pldraw(text, screen);
}
+
void h_buttoninput(Panel *p, int){
+ Field *f;
+
+ f = p->userp;
+ if(f && f->form && f->form->method != POST && f->form->action)
+ geturl(f->form->action, -1, 0, 0);
}
+
void h_fileinput(Panel *p, int){
char name[NNAME];
Field *f;
break;
case CHECK:
case RADIO:
+ case SUBMIT:
if(!f->state) break;
case HIDDEN:
if(f->name==0 || f->value==0)
- continue;
+ break;
fprint(fd, "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s",
sep, f->name, f->value);
sep = "\r\n--" BOUNDARY;
break;
case SELECT:
- if(f->name==0)
- continue;
+ if(f->name==0) break;
for(o=f->options;o;o=o->next)
if(o->selected && o->value){
fprint(fd, "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s",
}
break;
case TEXTWIN:
- if(f->name==0)
- continue;
+ if(f->name==0) break;
n=plelen(f->textwin);
rp=pleget(f->textwin);
p=b=malloc(UTFmax*n+1);
if(b == nil)
- continue;
+ break;
while(n > 0){
p += runetochar(p, rp);
rp++;
break;
case FILE:
if(f->name==0 || f->value[0]==0)
- continue;
+ break;
if(p = strrchr(f->value, '/'))
p++;
if(p == 0 || *p == 0)
p = f->value;
if((b = malloc(nb = 8192)) == nil)
- continue;
+ break;
if((ifd = open(f->value, OREAD)) >= 0){
if(filetype(ifd, b, nb) < 0)
strcpy(b, "application/octet-stream");
break;
case CHECK:
case RADIO:
+ case SUBMIT:
if(!f->state) break;
case HIDDEN:
if(f->name==0 || f->value==0)
- continue;
+ break;
fprint(fd, "%s%U=%U", sep, f->name, f->value);
sep = "&";
break;
case SELECT:
- if(f->name==0)
- continue;
+ if(f->name==0) break;
for(o=f->options;o;o=o->next)
if(o->selected && o->value){
fprint(fd, "%s%U=%U", sep, f->name, o->value);
}
break;
case TEXTWIN:
- if(f->name==0)
- continue;
+ if(f->name==0) break;
n=plelen(f->textwin);
rp=pleget(f->textwin);
p=b=malloc(UTFmax*n+1);
if(b == nil)
- continue;
+ break;
while(n > 0){
p += runetochar(p, rp);
rp++;
void h_submitinput(Panel *p, int){
char buf[NNAME];
Form *form;
+ Field *f;
int n, fd;
- form=((Field *)p->userp)->form;
- if(form->method==GET){
+ f = p->userp;
+ form=f->form;
+ for(f=form->fields;f;f=f->next)
+ if(f->type==SUBMIT)
+ f->state = (f->p == p);
+
+ switch(form->method){
+ case GET:
strcpy(buf, "/tmp/mfXXXXXXXXXXX");
fd = create(mktemp(buf), ORDWR|ORCLOSE, 0600);
- } else
+ break;
+ case POST:
fd = urlpost(selurl(form->action), form->ctype);
+ break;
+ default:
+ return;
+ }
+
if(fd < 0){
message("submit: %r");
return;
return;
}
buf[n] = 0;
- if(debug)fprint(2, "GET %s\n", buf);
geturl(buf, -1, 0, 0);
} else {
/* only set for multipart/form-data */
mencodeform(form, fd);
else
uencodeform(form, fd);
- if(debug)fprint(2, "POST %s\n", form->action);
geturl(form->action, fd, 0, 0);
}
}