mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +03:00
[project @ 2004-07-19 20:40:11 by joty]
form.h (struct form_control): renamed caret_char_offset to caret_box_offset; Added caret_form_offset & length. form.c: initialise new entries in struct form_control; form_successful_controls() : code reshuffling to improve readibility. box.h: TABing. box.c (box_input): init struct form_control::length. browser.c (browser_window_input_callback): UTF-8 support. Text area code needs similar changes. svn path=/import/netsurf/; revision=1117
This commit is contained in:
parent
f94da48139
commit
c93b54b07c
@ -183,7 +183,7 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
|
||||
*/
|
||||
|
||||
void browser_window_callback(content_msg msg, struct content *c,
|
||||
void *p1, void *p2, union content_msg_data data)
|
||||
void *p1, void *p2, union content_msg_data data)
|
||||
{
|
||||
struct browser_window *bw = p1;
|
||||
char status[40];
|
||||
@ -524,7 +524,7 @@ void download_window_callback(fetch_msg msg, void *p, const char *data,
|
||||
/* not possible */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -881,7 +881,7 @@ void browser_window_textarea_click(struct browser_window *bw,
|
||||
|
||||
textarea->gadget->caret_inline_container = inline_container;
|
||||
textarea->gadget->caret_text_box = text_box;
|
||||
textarea->gadget->caret_char_offset = char_offset;
|
||||
textarea->gadget->caret_box_offset = textarea->gadget->caret_form_offset = char_offset;
|
||||
textarea->gadget->caret_pixel_offset = pixel_offset;
|
||||
browser_window_place_caret(bw,
|
||||
box_x + text_box->x + pixel_offset,
|
||||
@ -906,7 +906,7 @@ void browser_window_textarea_callback(struct browser_window *bw,
|
||||
struct box *text_box = textarea->gadget->caret_text_box;
|
||||
struct box *new_br, *new_text, *t;
|
||||
struct box *prev;
|
||||
int char_offset = textarea->gadget->caret_char_offset;
|
||||
int char_offset = textarea->gadget->caret_box_offset;
|
||||
int pixel_offset = textarea->gadget->caret_pixel_offset;
|
||||
int dy;
|
||||
int box_x, box_y;
|
||||
@ -1148,7 +1148,7 @@ void browser_window_textarea_callback(struct browser_window *bw,
|
||||
|
||||
textarea->gadget->caret_inline_container = inline_container;
|
||||
textarea->gadget->caret_text_box = text_box;
|
||||
textarea->gadget->caret_char_offset = char_offset;
|
||||
textarea->gadget->caret_box_offset = textarea->gadget->caret_form_offset = char_offset;
|
||||
textarea->gadget->caret_pixel_offset = pixel_offset;
|
||||
browser_window_place_caret(bw,
|
||||
box_x + text_box->x + pixel_offset,
|
||||
@ -1179,10 +1179,13 @@ void browser_window_input_click(struct browser_window* bw,
|
||||
{
|
||||
int char_offset, pixel_offset, dx = 0;
|
||||
struct box *text_box = input->children->children;
|
||||
int uchars;
|
||||
unsigned int offset;
|
||||
|
||||
nsfont_position_in_string(text_box->font, text_box->text,
|
||||
text_box->length, x - text_box->x,
|
||||
&char_offset, &pixel_offset);
|
||||
assert(char_offset <= text_box->length);
|
||||
|
||||
text_box->x = 0;
|
||||
if ((input->width < text_box->width) &&
|
||||
@ -1193,7 +1196,31 @@ void browser_window_input_click(struct browser_window* bw,
|
||||
text_box->x = input->width - text_box->width;
|
||||
dx -= text_box->x;
|
||||
}
|
||||
input->gadget->caret_char_offset = char_offset;
|
||||
input->gadget->caret_box_offset = char_offset;
|
||||
/* Update caret_form_offset */
|
||||
for (uchars = 0, offset = 0; offset < char_offset; ++uchars) {
|
||||
if ((text_box->text[offset] & 0x80) == 0x00) {
|
||||
++offset;
|
||||
continue;
|
||||
}
|
||||
assert((text_box->text[offset] & 0xC0) == 0xC0);
|
||||
for (++offset; offset < char_offset && (text_box->text[offset] & 0xC0) == 0x80; ++offset)
|
||||
;
|
||||
}
|
||||
/* uchars is the number of real Unicode characters at the left
|
||||
* side of the caret.
|
||||
*/
|
||||
for (offset = 0; uchars > 0 && offset < input->gadget->length; --uchars) {
|
||||
if ((input->gadget->value[offset] & 0x80) == 0x00) {
|
||||
++offset;
|
||||
continue;
|
||||
}
|
||||
assert((input->gadget->value[offset] & 0xC0) == 0xC0);
|
||||
for (++offset; offset < input->gadget->length && (input->gadget->value[offset] & 0xC0) == 0x80; ++offset)
|
||||
;
|
||||
}
|
||||
assert(uchars == 0);
|
||||
input->gadget->caret_form_offset = offset;
|
||||
input->gadget->caret_pixel_offset = pixel_offset;
|
||||
browser_window_place_caret(bw,
|
||||
box_x + text_box->x + pixel_offset,
|
||||
@ -1213,83 +1240,96 @@ void browser_window_input_click(struct browser_window* bw,
|
||||
void browser_window_input_callback(struct browser_window *bw,
|
||||
unsigned int key, void *p)
|
||||
{
|
||||
struct box *input = p;
|
||||
struct box *input = (struct box *)p;
|
||||
struct box *text_box = input->children->children;
|
||||
int char_offset = input->gadget->caret_char_offset;
|
||||
unsigned int box_offset = input->gadget->caret_box_offset;
|
||||
unsigned int form_offset = input->gadget->caret_form_offset;
|
||||
int pixel_offset, dx;
|
||||
int box_x, box_y;
|
||||
struct form *form = input->gadget->form;
|
||||
char utf8[5];
|
||||
unsigned int utf8_len, i;
|
||||
char *text, *value;
|
||||
struct form* form = input->gadget->form;
|
||||
bool changed = false;
|
||||
|
||||
box_coords(input, &box_x, &box_y);
|
||||
|
||||
if (!(key <= 0x001F || (0x007F <= key && key <= 0x009F))) {
|
||||
char key_to_insert;
|
||||
const char *utf8key;
|
||||
size_t utf8keySize;
|
||||
|
||||
/** \todo: text_box has data in UTF-8 and its length in
|
||||
* bytes is not necessarily equal to number of characters.
|
||||
*/
|
||||
if (input->gadget->length >= input->gadget->maxlength)
|
||||
return;
|
||||
|
||||
/* normal character insertion */
|
||||
/** \todo convert key to UTF-8 properly */
|
||||
utf8[0] = key;
|
||||
utf8_len = 1;
|
||||
|
||||
/** \todo this is wrong for passwords, because multi-byte
|
||||
* UTF-8 sequences in the value get only one character in
|
||||
* the password, so we can't just use char_offset in
|
||||
* input->gadget->value */
|
||||
|
||||
text = realloc(text_box->text, text_box->length + 8);
|
||||
if (!text) {
|
||||
warn_user("NoMemory", 0);
|
||||
/* Insert key in gadget */
|
||||
key_to_insert = (char)key;
|
||||
if ((utf8key = cnv_local_enc_str(&key_to_insert, 1)) == NULL)
|
||||
return;
|
||||
}
|
||||
text_box->text = text;
|
||||
utf8keySize = strlen(utf8key);
|
||||
input->gadget->value = xrealloc(input->gadget->value, input->gadget->length + utf8keySize + 1);
|
||||
memmove(input->gadget->value + form_offset + utf8keySize,
|
||||
input->gadget->value + form_offset,
|
||||
input->gadget->length - form_offset);
|
||||
memcpy(input->gadget->value + form_offset, utf8key, utf8keySize);
|
||||
input->gadget->length += utf8keySize;
|
||||
input->gadget->value[input->gadget->length] = 0;
|
||||
form_offset += utf8keySize;
|
||||
free((void *)utf8key);
|
||||
|
||||
value = realloc(input->gadget->value, text_box->length + 8);
|
||||
if (!value) {
|
||||
warn_user("NoMemory", 0);
|
||||
/* Insert key in text box */
|
||||
/* Convert space into NBSP */
|
||||
key_to_insert = (input->gadget->type == GADGET_PASSWORD) ? '*' : (key == ' ') ? 160 : key;
|
||||
if ((utf8key = cnv_local_enc_str(&key_to_insert, 1)) == NULL)
|
||||
return;
|
||||
}
|
||||
input->gadget->value = value;
|
||||
|
||||
memmove(input->gadget->value + char_offset + utf8_len,
|
||||
input->gadget->value + char_offset,
|
||||
text_box->length - char_offset);
|
||||
for (i = 0; i != utf8_len; i++)
|
||||
input->gadget->value[char_offset + i] = key;
|
||||
|
||||
if (input->gadget->type == GADGET_PASSWORD) {
|
||||
text_box->text[text_box->length] = '*';
|
||||
text_box->length++;
|
||||
char_offset++;
|
||||
} else {
|
||||
memmove(text_box->text + char_offset + utf8_len,
|
||||
text_box->text + char_offset,
|
||||
text_box->length - char_offset);
|
||||
for (i = 0; i != utf8_len; i++)
|
||||
text_box->text[char_offset + i] = utf8[i];
|
||||
text_box->length += utf8_len;
|
||||
char_offset += utf8_len;
|
||||
}
|
||||
utf8keySize = strlen(utf8key);
|
||||
text_box->text = xrealloc(text_box->text, text_box->length + utf8keySize + 1);
|
||||
memmove(text_box->text + box_offset + utf8keySize,
|
||||
text_box->text + box_offset,
|
||||
text_box->length - box_offset);
|
||||
memcpy(text_box->text + box_offset, utf8key, utf8keySize);
|
||||
text_box->length += utf8keySize;
|
||||
text_box->text[text_box->length] = 0;
|
||||
input->gadget->value[text_box->length] = 0;
|
||||
box_offset += utf8keySize;
|
||||
free((void *)utf8key);
|
||||
|
||||
text_box->width = nsfont_width(text_box->font, text_box->text,
|
||||
(unsigned int)text_box->length);
|
||||
|
||||
changed = true;
|
||||
|
||||
} else if ((key == 8 || key == 127) && char_offset != 0) {
|
||||
} else if (key == 8 || key == 127) {
|
||||
/* delete to left */
|
||||
/** \todo delete entire UTF-8 character, handling passwords */
|
||||
utf8_len = 1;
|
||||
memmove(text_box->text + char_offset - utf8_len,
|
||||
text_box->text + char_offset,
|
||||
text_box->length - char_offset);
|
||||
memmove(input->gadget->value + char_offset - utf8_len,
|
||||
input->gadget->value + char_offset,
|
||||
text_box->length - char_offset);
|
||||
text_box->length--;
|
||||
input->gadget->value[text_box->length] = 0;
|
||||
char_offset--;
|
||||
int prev_offset;
|
||||
|
||||
if (box_offset == 0)
|
||||
return;
|
||||
|
||||
/* Gadget */
|
||||
prev_offset = form_offset;
|
||||
/* Go to the previous valid UTF-8 character */
|
||||
while (form_offset != 0
|
||||
&& !((input->gadget->value[--form_offset] & 0x80) == 0x00 || (input->gadget->value[form_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
memmove(input->gadget->value + form_offset,
|
||||
input->gadget->value + prev_offset,
|
||||
input->gadget->length - prev_offset);
|
||||
input->gadget->length -= prev_offset - form_offset;
|
||||
input->gadget->value[input->gadget->length] = 0;
|
||||
|
||||
/* Text box */
|
||||
prev_offset = box_offset;
|
||||
/* Go to the previous valid UTF-8 character */
|
||||
while (box_offset != 0
|
||||
&& !((text_box->text[--box_offset] & 0x80) == 0x00 || (text_box->text[box_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
memmove(text_box->text + box_offset,
|
||||
text_box->text + prev_offset,
|
||||
text_box->length - prev_offset);
|
||||
text_box->length -= prev_offset - box_offset;
|
||||
text_box->text[text_box->length] = 0;
|
||||
|
||||
text_box->width = nsfont_width(text_box->font, text_box->text,
|
||||
(unsigned int)text_box->length);
|
||||
|
||||
@ -1299,12 +1339,18 @@ void browser_window_input_callback(struct browser_window *bw,
|
||||
/* Ctrl+U */
|
||||
text_box->text[0] = 0;
|
||||
text_box->length = 0;
|
||||
box_offset = 0;
|
||||
|
||||
input->gadget->value[0] = 0;
|
||||
char_offset = 0;
|
||||
input->gadget->length = 0;
|
||||
form_offset = 0;
|
||||
|
||||
text_box->width = 0;
|
||||
changed = true;
|
||||
|
||||
} else if (key == 10 || key == 13) {
|
||||
/* Return/Enter hit */
|
||||
LOG(("Submit, text <%s>, gadget <%s>\n", text_box->text, input->gadget->value));
|
||||
if (form)
|
||||
browser_form_submit(bw, form, 0);
|
||||
|
||||
@ -1324,7 +1370,7 @@ void browser_window_input_callback(struct browser_window *bw,
|
||||
input = next_input->box;
|
||||
text_box = input->children->children;
|
||||
box_coords(input, &box_x, &box_y);
|
||||
char_offset = 0;
|
||||
form_offset = box_offset = 0;
|
||||
|
||||
} else if (key == 11) {
|
||||
/* Shift+Tab */
|
||||
@ -1342,34 +1388,49 @@ void browser_window_input_callback(struct browser_window *bw,
|
||||
input = prev_input->box;
|
||||
text_box = input->children->children;
|
||||
box_coords(input, &box_x, &box_y);
|
||||
char_offset = 0;
|
||||
form_offset = box_offset = 0;
|
||||
|
||||
} else if (key == 26) {
|
||||
/* Ctrl+Left */
|
||||
char_offset = 0;
|
||||
box_offset = form_offset = 0;
|
||||
|
||||
} else if (key == 27) {
|
||||
/* Ctrl+Right */
|
||||
char_offset = text_box->length;
|
||||
box_offset = text_box->length;
|
||||
form_offset = input->gadget->length;
|
||||
|
||||
} else if (key == 28 && (unsigned int)char_offset != text_box->length) {
|
||||
} else if (key == 28) {
|
||||
/* Right cursor -> */
|
||||
/** \todo UTF-8 */
|
||||
utf8_len = 1;
|
||||
char_offset += utf8_len;
|
||||
/* Text box */
|
||||
/* Go to the next valid UTF-8 character */
|
||||
while (box_offset != text_box->length
|
||||
&& !((text_box->text[++box_offset] & 0x80) == 0x00 || (text_box->text[box_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
/* Gadget */
|
||||
/* Go to the next valid UTF-8 character */
|
||||
while (form_offset != input->gadget->length
|
||||
&& !((input->gadget->value[++form_offset] & 0x80) == 0x00 || (input->gadget->value[form_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
|
||||
} else if (key == 29 && char_offset != 0) {
|
||||
} else if (key == 29) {
|
||||
/* Left cursor <- */
|
||||
/** \todo UTF-8 */
|
||||
utf8_len = 1;
|
||||
char_offset -= utf8_len;
|
||||
/* Text box */
|
||||
/* Go to the previous valid UTF-8 character */
|
||||
while (box_offset != 0
|
||||
&& !((text_box->text[--box_offset] & 0x80) == 0x00 || (text_box->text[box_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
/* Gadget */
|
||||
/* Go to the previous valid UTF-8 character */
|
||||
while (form_offset != 0
|
||||
&& !((input->gadget->value[--form_offset] & 0x80) == 0x00 || (input->gadget->value[form_offset] & 0xC0) == 0xC0))
|
||||
;
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
pixel_offset = nsfont_width(text_box->font, text_box->text,
|
||||
(unsigned int)char_offset);
|
||||
(unsigned int)box_offset);
|
||||
dx = text_box->x;
|
||||
text_box->x = 0;
|
||||
if (input->width < text_box->width && input->width / 2 < pixel_offset) {
|
||||
@ -1378,9 +1439,11 @@ void browser_window_input_callback(struct browser_window *bw,
|
||||
text_box->x = input->width - text_box->width;
|
||||
}
|
||||
dx -= text_box->x;
|
||||
|
||||
input->gadget->caret_char_offset = char_offset;
|
||||
input->gadget->caret_pixel_offset = pixel_offset;
|
||||
|
||||
input->gadget->caret_box_offset = box_offset;
|
||||
input->gadget->caret_form_offset = form_offset;
|
||||
|
||||
browser_window_place_caret(bw,
|
||||
box_x + text_box->x + pixel_offset,
|
||||
box_y + text_box->y,
|
||||
@ -1477,45 +1540,45 @@ void browser_window_form_select(struct browser_window *bw,
|
||||
}
|
||||
|
||||
|
||||
gui_pointer_shape get_pointer_shape(css_cursor cursor) {
|
||||
gui_pointer_shape get_pointer_shape(css_cursor cursor)
|
||||
{
|
||||
gui_pointer_shape pointer;
|
||||
|
||||
gui_pointer_shape pointer;
|
||||
switch (cursor) {
|
||||
case CSS_CURSOR_CROSSHAIR:
|
||||
pointer = GUI_POINTER_CROSS;
|
||||
break;
|
||||
case CSS_CURSOR_POINTER:
|
||||
pointer = GUI_POINTER_POINT;
|
||||
break;
|
||||
case CSS_CURSOR_MOVE:
|
||||
pointer = GUI_POINTER_MOVE;
|
||||
break;
|
||||
case CSS_CURSOR_E_RESIZE:
|
||||
case CSS_CURSOR_W_RESIZE:
|
||||
pointer = GUI_POINTER_LR;
|
||||
break;
|
||||
case CSS_CURSOR_N_RESIZE:
|
||||
case CSS_CURSOR_S_RESIZE:
|
||||
pointer = GUI_POINTER_UD;
|
||||
break;
|
||||
case CSS_CURSOR_NE_RESIZE:
|
||||
case CSS_CURSOR_SW_RESIZE:
|
||||
pointer = GUI_POINTER_LD;
|
||||
break;
|
||||
case CSS_CURSOR_SE_RESIZE:
|
||||
case CSS_CURSOR_NW_RESIZE:
|
||||
pointer = GUI_POINTER_RD;
|
||||
break;
|
||||
case CSS_CURSOR_TEXT:
|
||||
pointer = GUI_POINTER_CARET;
|
||||
break;
|
||||
default:
|
||||
pointer = GUI_POINTER_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cursor) {
|
||||
case CSS_CURSOR_CROSSHAIR:
|
||||
pointer = GUI_POINTER_CROSS;
|
||||
break;
|
||||
case CSS_CURSOR_POINTER:
|
||||
pointer = GUI_POINTER_POINT;
|
||||
break;
|
||||
case CSS_CURSOR_MOVE:
|
||||
pointer = GUI_POINTER_MOVE;
|
||||
break;
|
||||
case CSS_CURSOR_E_RESIZE:
|
||||
case CSS_CURSOR_W_RESIZE:
|
||||
pointer = GUI_POINTER_LR;
|
||||
break;
|
||||
case CSS_CURSOR_N_RESIZE:
|
||||
case CSS_CURSOR_S_RESIZE:
|
||||
pointer = GUI_POINTER_UD;
|
||||
break;
|
||||
case CSS_CURSOR_NE_RESIZE:
|
||||
case CSS_CURSOR_SW_RESIZE:
|
||||
pointer = GUI_POINTER_LD;
|
||||
break;
|
||||
case CSS_CURSOR_SE_RESIZE:
|
||||
case CSS_CURSOR_NW_RESIZE:
|
||||
pointer = GUI_POINTER_RD;
|
||||
break;
|
||||
case CSS_CURSOR_TEXT:
|
||||
pointer = GUI_POINTER_CARET;
|
||||
break;
|
||||
default:
|
||||
pointer = GUI_POINTER_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
return pointer;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
|
||||
@ -1540,35 +1603,35 @@ void browser_form_submit(struct browser_window *bw, struct form *form,
|
||||
data = form_url_encode(success);
|
||||
url = xcalloc(1, strlen(form->action) + strlen(data) + 2);
|
||||
if(form->action[strlen(form->action)-1] == '?') {
|
||||
sprintf(url, "%s%s", form->action, data);
|
||||
sprintf(url, "%s%s", form->action, data);
|
||||
}
|
||||
else {
|
||||
sprintf(url, "%s?%s", form->action, data);
|
||||
sprintf(url, "%s?%s", form->action, data);
|
||||
}
|
||||
url1 = url_join(url, base);
|
||||
if (!url1)
|
||||
break;
|
||||
browser_window_go(bw, url1);
|
||||
break;
|
||||
break;
|
||||
|
||||
case method_POST_URLENC:
|
||||
case method_POST_URLENC:
|
||||
data = form_url_encode(success);
|
||||
url = url_join(form->action, base);
|
||||
if (!url)
|
||||
break;
|
||||
browser_window_go_post(bw, url, data, 0, true);
|
||||
break;
|
||||
break;
|
||||
|
||||
case method_POST_MULTIPART:
|
||||
case method_POST_MULTIPART:
|
||||
url = url_join(form->action, base);
|
||||
if (!url)
|
||||
break;
|
||||
browser_window_go_post(bw, url, 0, success, true);
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
form_free_successful(success);
|
||||
free(data);
|
||||
|
17
render/box.c
17
render/box.c
@ -1179,8 +1179,8 @@ void add_option(xmlNode* n, struct form_control* current_select, const char *tex
|
||||
struct box_result box_input(xmlNode *n, struct box_status *status,
|
||||
struct css_style *style)
|
||||
{
|
||||
struct box* box = 0;
|
||||
struct form_control *gadget = 0;
|
||||
struct box* box = NULL;
|
||||
struct form_control *gadget = NULL;
|
||||
char *s, *type, *url;
|
||||
|
||||
type = (char *) xmlGetProp(n, (const xmlChar *) "type");
|
||||
@ -1219,21 +1219,20 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
||||
xmlFree(type);
|
||||
return (struct box_result) {0, false, true};
|
||||
}
|
||||
gadget->length = strlen(gadget->value);
|
||||
}
|
||||
|
||||
} else if (type && (strcasecmp(type, "checkbox") == 0 ||
|
||||
strcasecmp(type, "radio") == 0)) {
|
||||
box = box_create(style, NULL, 0,
|
||||
status->content->data.html.box_pool);
|
||||
box->gadget = gadget = form_new_control(GADGET_RADIO);
|
||||
box->gadget = gadget = form_new_control((type[0] == 'c' || type[0] == 'C') ? GADGET_CHECKBOX : GADGET_RADIO);
|
||||
if (!gadget) {
|
||||
box_free_box(box);
|
||||
xmlFree(type);
|
||||
return (struct box_result) {0, false, true};
|
||||
}
|
||||
gadget->box = box;
|
||||
if (type[0] == 'c' || type[0] == 'C')
|
||||
gadget->type = GADGET_CHECKBOX;
|
||||
|
||||
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "checked"))) {
|
||||
gadget->selected = true;
|
||||
@ -1248,6 +1247,7 @@ struct box_result box_input(xmlNode *n, struct box_status *status,
|
||||
xmlFree(type);
|
||||
return (struct box_result) {0, false, true};
|
||||
}
|
||||
gadget->length = strlen(gadget->value);
|
||||
}
|
||||
|
||||
} else if (type && (strcasecmp(type, "submit") == 0 ||
|
||||
@ -1365,7 +1365,7 @@ struct box *box_input_text(xmlNode *n, struct box_status *status,
|
||||
struct box *inline_container, *inline_box;
|
||||
box->type = BOX_INLINE_BLOCK;
|
||||
|
||||
box->gadget = form_new_control(GADGET_TEXTBOX);
|
||||
box->gadget = form_new_control((password) ? GADGET_PASSWORD : GADGET_TEXTBOX);
|
||||
box->gadget->box = box;
|
||||
|
||||
box->gadget->maxlength = 100;
|
||||
@ -1376,13 +1376,14 @@ struct box *box_input_text(xmlNode *n, struct box_status *status,
|
||||
|
||||
s = (char *) xmlGetProp(n, (const xmlChar *) "value");
|
||||
box->gadget->value = strdup((s != NULL) ? s : "");
|
||||
box->gadget->initial_value = strdup(box->gadget->value);
|
||||
box->gadget->initial_value = strdup((box->gadget->value != NULL) ? box->gadget->value : "");
|
||||
if (s)
|
||||
xmlFree(s);
|
||||
if (box->gadget->value == NULL || box->gadget->initial_value == NULL) {
|
||||
box_free(box);
|
||||
return NULL;
|
||||
}
|
||||
box->gadget->length = strlen(box->gadget->value);
|
||||
|
||||
inline_container = box_create(0, 0, 0,
|
||||
status->content->data.html.box_pool);
|
||||
@ -1392,13 +1393,11 @@ struct box *box_input_text(xmlNode *n, struct box_status *status,
|
||||
inline_box->type = BOX_INLINE;
|
||||
inline_box->style_clone = 1;
|
||||
if (password) {
|
||||
box->gadget->type = GADGET_PASSWORD;
|
||||
inline_box->length = strlen(box->gadget->value);
|
||||
inline_box->text = malloc(inline_box->length + 1);
|
||||
memset(inline_box->text, '*', inline_box->length);
|
||||
inline_box->text[inline_box->length] = '\0';
|
||||
} else {
|
||||
box->gadget->type = GADGET_TEXTBOX;
|
||||
/* replace spaces/TABs with hard spaces to prevent line wrapping */
|
||||
inline_box->text = cnv_space2nbsp(box->gadget->value);
|
||||
inline_box->length = strlen(inline_box->text);
|
||||
|
29
render/box.h
29
render/box.h
@ -98,12 +98,12 @@ typedef enum {
|
||||
|
||||
/* parameters for <object> and related elements */
|
||||
struct object_params {
|
||||
char* data;
|
||||
char* type;
|
||||
char* codetype;
|
||||
char* codebase;
|
||||
char* classid;
|
||||
struct plugin_params* params;
|
||||
char* data;
|
||||
char* type;
|
||||
char* codetype;
|
||||
char* codebase;
|
||||
char* classid;
|
||||
struct plugin_params* params;
|
||||
/* not a parameter, but stored here for convenience */
|
||||
char* basehref;
|
||||
char* filename;
|
||||
@ -115,12 +115,11 @@ struct object_params {
|
||||
};
|
||||
|
||||
struct plugin_params {
|
||||
|
||||
char* name;
|
||||
char* value;
|
||||
char* type;
|
||||
char* valuetype;
|
||||
struct plugin_params* next;
|
||||
char* name;
|
||||
char* value;
|
||||
char* type;
|
||||
char* valuetype;
|
||||
struct plugin_params* next;
|
||||
};
|
||||
|
||||
/** Node in box tree. All dimensions are in pixels. */
|
||||
@ -207,10 +206,10 @@ struct box {
|
||||
/** Form control data, or 0 if not a form control. */
|
||||
struct form_control* gadget;
|
||||
|
||||
char *usemap; /** (Image)map to use with this object, or 0 if none */
|
||||
char *usemap; /** (Image)map to use with this object, or 0 if none */
|
||||
|
||||
/** Background image for this box, or 0 if none */
|
||||
struct content *background;
|
||||
/** Background image for this box, or 0 if none */
|
||||
struct content *background;
|
||||
|
||||
/** Object in this box (usually an image), or 0 if none. */
|
||||
struct content* object;
|
||||
|
220
render/form.c
220
render/form.c
@ -33,19 +33,22 @@ struct form_control *form_new_control(form_control_type type)
|
||||
{
|
||||
struct form_control *control;
|
||||
|
||||
control = malloc(sizeof *control);
|
||||
if (!control)
|
||||
return 0;
|
||||
if ((control = malloc(sizeof *control)) == NULL)
|
||||
return NULL;
|
||||
control->type = type;
|
||||
control->name = 0;
|
||||
control->value = 0;
|
||||
control->initial_value = 0;
|
||||
control->name = NULL;
|
||||
control->value = NULL;
|
||||
control->initial_value = NULL;
|
||||
control->disabled = false;
|
||||
control->form = 0;
|
||||
control->box = 0;
|
||||
control->form = NULL;
|
||||
control->box = NULL;
|
||||
control->caret_inline_container = NULL;
|
||||
control->caret_text_box = NULL;
|
||||
control->caret_box_offset = control->caret_form_offset = 0;
|
||||
control->length = control->maxlength = 0;
|
||||
control->selected = false;
|
||||
control->prev = 0;
|
||||
control->next = 0;
|
||||
control->prev = NULL;
|
||||
control->next = NULL;
|
||||
return control;
|
||||
}
|
||||
|
||||
@ -57,11 +60,11 @@ struct form_control *form_new_control(form_control_type type)
|
||||
void form_add_control(struct form *form, struct form_control *control)
|
||||
{
|
||||
control->form = form;
|
||||
if (form->controls) {
|
||||
if (form->controls != NULL) {
|
||||
assert(form->last_control);
|
||||
form->last_control->next = control;
|
||||
control->prev = form->last_control;
|
||||
control->next = 0;
|
||||
control->next = NULL;
|
||||
form->last_control = control;
|
||||
} else {
|
||||
form->controls = form->last_control = control;
|
||||
@ -106,11 +109,13 @@ struct form_successful_control *form_successful_controls(struct form *form,
|
||||
struct form_control *control;
|
||||
struct form_option *option;
|
||||
struct form_successful_control sentinel, *last_success;
|
||||
|
||||
last_success = &sentinel;
|
||||
sentinel.next = 0;
|
||||
|
||||
for (control = form->controls; control; control = control->next) {
|
||||
struct form_successful_control *success_new;
|
||||
bool add_val;
|
||||
|
||||
/* ignore disabled controls */
|
||||
if (control->disabled)
|
||||
@ -120,93 +125,120 @@ struct form_successful_control *form_successful_controls(struct form *form,
|
||||
if (!control->name)
|
||||
continue;
|
||||
|
||||
/* only the activated submit button is successful */
|
||||
if (control->type == GADGET_SUBMIT && control != submit_button)
|
||||
continue;
|
||||
switch (control->type) {
|
||||
case GADGET_HIDDEN:
|
||||
case GADGET_TEXTBOX:
|
||||
case GADGET_PASSWORD:
|
||||
add_val = true;
|
||||
break;
|
||||
|
||||
/* ignore checkboxes and radio buttons which aren't selected */
|
||||
if (control->type == GADGET_CHECKBOX && !control->selected)
|
||||
continue;
|
||||
if (control->type == GADGET_RADIO && !control->selected)
|
||||
continue;
|
||||
case GADGET_RADIO:
|
||||
case GADGET_CHECKBOX:
|
||||
/* ignore checkboxes and radio buttons which
|
||||
* aren't selected
|
||||
*/
|
||||
add_val = control->selected;
|
||||
break;
|
||||
|
||||
/* select */
|
||||
if (control->type == GADGET_SELECT) {
|
||||
for (option = control->data.select.items; option;
|
||||
option = option->next) {
|
||||
if (option->selected) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xstrdup(control->name);
|
||||
success_new->value = xstrdup(option->value);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
case GADGET_SELECT:
|
||||
/* select */
|
||||
for (option = control->data.select.items;
|
||||
option != NULL;
|
||||
option = option->next) {
|
||||
if (option->selected) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = cnv_str_local_enc(control->name);
|
||||
success_new->value = cnv_str_local_enc(option->value);
|
||||
success_new->next = NULL;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
}
|
||||
}
|
||||
|
||||
add_val = false;
|
||||
break;
|
||||
|
||||
case GADGET_TEXTAREA:
|
||||
/* textarea */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = cnv_str_local_enc(control->name);
|
||||
success_new->value = form_textarea_value(control);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
|
||||
add_val = false;
|
||||
break;
|
||||
|
||||
case GADGET_IMAGE: {
|
||||
/* image */
|
||||
const size_t len = strlen(control->name) + 3;
|
||||
|
||||
/* x */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xcalloc(1, len);
|
||||
sprintf(success_new->name, "%s.x", control->name);
|
||||
success_new->value = xcalloc(1, 20);
|
||||
sprintf(success_new->value, "%i", control->data.image.mx);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
|
||||
/* y */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xcalloc(1, len);
|
||||
sprintf(success_new->name, "%s.y", control->name);
|
||||
success_new->value = xcalloc(1, 20);
|
||||
sprintf(success_new->value, "%i", control->data.image.my);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
|
||||
add_val = false;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* textarea */
|
||||
if (control->type == GADGET_TEXTAREA) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xstrdup(control->name);
|
||||
success_new->value = form_textarea_value(control);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
continue;
|
||||
}
|
||||
case GADGET_SUBMIT:
|
||||
/* only the activated submit button is
|
||||
* successful
|
||||
*/
|
||||
add_val = (control != submit_button) ? false : true;
|
||||
break;
|
||||
|
||||
/* image */
|
||||
if (control->type == GADGET_IMAGE) {
|
||||
unsigned int len = strlen(control->name) + 3;
|
||||
/* x */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xcalloc(1, len);
|
||||
sprintf(success_new->name, "%s.x", control->name);
|
||||
success_new->value = xcalloc(1, 20);
|
||||
sprintf(success_new->value, "%i", control->data.image.mx);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
/* y */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xcalloc(1, len);
|
||||
sprintf(success_new->name, "%s.y", control->name);
|
||||
success_new->value = xcalloc(1, 20);
|
||||
sprintf(success_new->value, "%i", control->data.image.my);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
}
|
||||
case GADGET_RESET:
|
||||
/* ignore reset */
|
||||
add_val = false;
|
||||
break;
|
||||
|
||||
/* ignore reset */
|
||||
if (control->type == GADGET_RESET)
|
||||
continue;
|
||||
case GADGET_FILE:
|
||||
/* file */
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = true;
|
||||
success_new->name = cnv_str_local_enc(control->name);
|
||||
success_new->value = cnv_str_local_enc(control->value);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
|
||||
/* file */
|
||||
if (control->type == GADGET_FILE && control->value) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = true;
|
||||
success_new->name = xstrdup(control->name);
|
||||
success_new->value = xstrdup(control->value);
|
||||
success_new->next = 0;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
continue;
|
||||
add_val = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* all others added if they have a value */
|
||||
if (control->value) {
|
||||
if (add_val && control->value != NULL) {
|
||||
success_new = xcalloc(1, sizeof(*success_new));
|
||||
success_new->file = false;
|
||||
success_new->name = xstrdup(control->name);
|
||||
success_new->value = xstrdup(control->value);
|
||||
success_new->next = 0;
|
||||
success_new->name = cnv_str_local_enc(control->name);
|
||||
success_new->value = cnv_str_local_enc(control->value);
|
||||
success_new->next = NULL;
|
||||
last_success->next = success_new;
|
||||
last_success = success_new;
|
||||
}
|
||||
@ -228,10 +260,10 @@ char *form_textarea_value(struct form_control *textarea)
|
||||
|
||||
/* find required length */
|
||||
for (inline_container = textarea->box->children;
|
||||
inline_container;
|
||||
inline_container != NULL;
|
||||
inline_container = inline_container->next) {
|
||||
for (text_box = inline_container->children;
|
||||
text_box;
|
||||
text_box != NULL;
|
||||
text_box = text_box->next) {
|
||||
len += text_box->length + 1;
|
||||
}
|
||||
@ -241,10 +273,10 @@ char *form_textarea_value(struct form_control *textarea)
|
||||
/* construct value */
|
||||
s = value = xcalloc(1, len);
|
||||
for (inline_container = textarea->box->children;
|
||||
inline_container;
|
||||
inline_container != NULL;
|
||||
inline_container = inline_container->next) {
|
||||
for (text_box = inline_container->children;
|
||||
text_box;
|
||||
text_box != NULL;
|
||||
text_box = text_box->next) {
|
||||
strncpy(s, text_box->text, text_box->length);
|
||||
s += text_box->length;
|
||||
@ -269,14 +301,14 @@ char *form_url_encode(struct form_successful_control *control)
|
||||
unsigned int len = 0, len1;
|
||||
|
||||
for (; control; control = control->next) {
|
||||
char *name = curl_escape(control->name, 0);
|
||||
char *value = curl_escape(control->value, 0);
|
||||
const char *name = curl_escape(control->name, 0);
|
||||
const char *value = curl_escape(control->value, 0);
|
||||
len1 = len + strlen(name) + strlen(value) + 2;
|
||||
s = xrealloc(s, len1 + 1);
|
||||
sprintf(s + len, "%s=%s&", name, value);
|
||||
len = len1;
|
||||
curl_free(name);
|
||||
curl_free(value);
|
||||
curl_free(name);
|
||||
curl_free(value);
|
||||
}
|
||||
if (len)
|
||||
s[len - 1] = 0;
|
||||
|
@ -58,13 +58,14 @@ struct form_control {
|
||||
struct box *box;
|
||||
struct box *caret_inline_container;
|
||||
struct box *caret_text_box;
|
||||
int caret_char_offset;
|
||||
unsigned int caret_box_offset, caret_form_offset;
|
||||
unsigned int length;
|
||||
int caret_pixel_offset;
|
||||
unsigned int maxlength;
|
||||
bool selected;
|
||||
union {
|
||||
struct {
|
||||
int mx, my;
|
||||
int mx, my;
|
||||
} image;
|
||||
struct {
|
||||
int num_items;
|
||||
|
Loading…
Reference in New Issue
Block a user