mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Bug 784: Keep form_control.default_value in the document charset.
Previously, html_special_form_control converted form_control.default_value to the terminal charset, and init_form_state then copied the value to form_state.value. However, when CONFIG_UTF8 is defined and UTF-8 I/O is enabled, form_state.value is supposed to be in UTF-8, rather than in the terminal charset. This mismatch could not be conveniently fixed in html_special_form_control because that does not know which terminal is being used and whether UTF-8 I/O is enabled there. Also, constructing a conversion table from the document charset to form_state.value could have ruined renderer_context.convert_table, because src/intl/charsets.c does not support multiple concurrent conversion tables. So instead, we now keep form_control.default_value in the document charset, and convert it in the viewer each time it is needed. Because the result of the conversion is kept in form_state.value between incremental renderings, this shouldn't even slow things down too much. I am not implementing the proper charset conversions for the DOM defaultValue property yet, because the current code doesn't have them for other string properties either, and bug 805 is already open for that.
This commit is contained in:
parent
0df5b7fdf5
commit
5e83337d49
@ -86,6 +86,10 @@ struct form_control {
|
|||||||
unsigned char *id; /* used by scripts */
|
unsigned char *id; /* used by scripts */
|
||||||
unsigned char *name;
|
unsigned char *name;
|
||||||
unsigned char *alt;
|
unsigned char *alt;
|
||||||
|
/* For FC_TEXT, FC_PASSWORD, and FC_TEXTAREA: @default_value
|
||||||
|
* is in the charset of the document.
|
||||||
|
*
|
||||||
|
* For FC_FILE: The parser does not set @default_value. */
|
||||||
unsigned char *default_value;
|
unsigned char *default_value;
|
||||||
int default_state;
|
int default_state;
|
||||||
int size;
|
int size;
|
||||||
|
@ -1809,18 +1809,6 @@ html_special_form_control(struct part *part, struct form_control *fc)
|
|||||||
|
|
||||||
fc->g_ctrl_num = renderer_context.g_ctrl_num++;
|
fc->g_ctrl_num = renderer_context.g_ctrl_num++;
|
||||||
|
|
||||||
/* We don't want to recode hidden fields. */
|
|
||||||
if (fc->type == FC_TEXT || fc->type == FC_PASSWORD ||
|
|
||||||
fc->type == FC_TEXTAREA) {
|
|
||||||
unsigned char *dv = convert_string(renderer_context.convert_table,
|
|
||||||
fc->default_value,
|
|
||||||
strlen(fc->default_value),
|
|
||||||
part->document->options.cp,
|
|
||||||
CSM_FORM, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (dv) mem_free_set(&fc->default_value, dv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list_empty(part->document->forms)) {
|
if (list_empty(part->document->forms)) {
|
||||||
/* No forms encountered yet, that means a homeless form
|
/* No forms encountered yet, that means a homeless form
|
||||||
* control. Generate a dummy form for those Flying
|
* control. Generate a dummy form for those Flying
|
||||||
|
@ -200,6 +200,7 @@ input_get(struct SEE_interpreter *interp, struct SEE_object *o,
|
|||||||
} else if (p == s_defaultChecked) {
|
} else if (p == s_defaultChecked) {
|
||||||
SEE_SET_BOOLEAN(res, fc->default_state);
|
SEE_SET_BOOLEAN(res, fc->default_state);
|
||||||
} else if (p == s_defaultValue) {
|
} else if (p == s_defaultValue) {
|
||||||
|
/* FIXME (bug 805): convert from the charset of the document */
|
||||||
str = string_to_SEE_string(interp, fc->default_value);
|
str = string_to_SEE_string(interp, fc->default_value);
|
||||||
SEE_SET_STRING(res, str);
|
SEE_SET_STRING(res, str);
|
||||||
} else if (p == s_disabled) {
|
} else if (p == s_disabled) {
|
||||||
|
@ -206,6 +206,7 @@ input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
|||||||
boolean_to_jsval(ctx, vp, fc->default_state);
|
boolean_to_jsval(ctx, vp, fc->default_state);
|
||||||
break;
|
break;
|
||||||
case JSP_INPUT_DEFAULT_VALUE:
|
case JSP_INPUT_DEFAULT_VALUE:
|
||||||
|
/* FIXME (bug 805): convert from the charset of the document */
|
||||||
string_to_jsval(ctx, vp, fc->default_value);
|
string_to_jsval(ctx, vp, fc->default_value);
|
||||||
break;
|
break;
|
||||||
case JSP_INPUT_DISABLED:
|
case JSP_INPUT_DISABLED:
|
||||||
|
@ -150,11 +150,24 @@ selected_item(struct terminal *term, void *item_, void *ses_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_form_state(struct form_control *fc, struct form_state *fs)
|
init_form_state(struct document_view *doc_view,
|
||||||
|
struct form_control *fc, struct form_state *fs)
|
||||||
{
|
{
|
||||||
|
struct terminal *term;
|
||||||
|
int doc_cp, viewer_cp;
|
||||||
|
|
||||||
assert(fc && fs);
|
assert(fc && fs);
|
||||||
if_assert_failed return;
|
if_assert_failed return;
|
||||||
|
|
||||||
|
doc_cp = doc_view->document->cp;
|
||||||
|
term = doc_view->session->tab->term;
|
||||||
|
#ifdef CONFIG_UTF8
|
||||||
|
if (term->utf8)
|
||||||
|
viewer_cp = get_cp_index("UTF-8");
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
viewer_cp = get_opt_codepage_tree(term->spec, "charset");
|
||||||
|
|
||||||
mem_free_set(&fs->value, NULL);
|
mem_free_set(&fs->value, NULL);
|
||||||
|
|
||||||
switch (fc->type) {
|
switch (fc->type) {
|
||||||
@ -167,8 +180,14 @@ init_form_state(struct form_control *fc, struct form_state *fs)
|
|||||||
#endif /* CONFIG_FORMHIST */
|
#endif /* CONFIG_FORMHIST */
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case FC_TEXTAREA:
|
case FC_TEXTAREA:
|
||||||
if (fs->value == NULL)
|
if (fs->value == NULL) {
|
||||||
fs->value = stracpy(fc->default_value);
|
fs->value = convert_string(
|
||||||
|
get_translation_table(doc_cp, viewer_cp),
|
||||||
|
fc->default_value,
|
||||||
|
strlen(fc->default_value),
|
||||||
|
viewer_cp, CSM_FORM,
|
||||||
|
&fs->state, NULL, NULL);
|
||||||
|
}
|
||||||
fs->state = fs->value ? strlen(fs->value) : 0;
|
fs->state = fs->value ? strlen(fs->value) : 0;
|
||||||
#ifdef CONFIG_UTF8
|
#ifdef CONFIG_UTF8
|
||||||
if (fc->type == FC_TEXTAREA)
|
if (fc->type == FC_TEXTAREA)
|
||||||
@ -182,7 +201,12 @@ init_form_state(struct form_control *fc, struct form_state *fs)
|
|||||||
fs->vpos = 0;
|
fs->vpos = 0;
|
||||||
break;
|
break;
|
||||||
case FC_SELECT:
|
case FC_SELECT:
|
||||||
fs->value = stracpy(fc->default_value);
|
fs->value = convert_string(
|
||||||
|
get_translation_table(doc_cp, viewer_cp),
|
||||||
|
fc->default_value,
|
||||||
|
strlen(fc->default_value),
|
||||||
|
viewer_cp, CSM_FORM,
|
||||||
|
&fs->state, NULL, NULL);
|
||||||
fs->state = fc->default_state;
|
fs->state = fc->default_state;
|
||||||
fixup_select_state(fc, fs);
|
fixup_select_state(fc, fs);
|
||||||
break;
|
break;
|
||||||
@ -195,6 +219,7 @@ init_form_state(struct form_control *fc, struct form_state *fs)
|
|||||||
case FC_RESET:
|
case FC_RESET:
|
||||||
case FC_BUTTON:
|
case FC_BUTTON:
|
||||||
case FC_HIDDEN:
|
case FC_HIDDEN:
|
||||||
|
/* We don't want to recode hidden fields. */
|
||||||
fs->value = stracpy(fc->default_value);
|
fs->value = stracpy(fc->default_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -236,7 +261,7 @@ find_form_state(struct document_view *doc_view, struct form_control *fc)
|
|||||||
fs->g_ctrl_num = fc->g_ctrl_num;
|
fs->g_ctrl_num = fc->g_ctrl_num;
|
||||||
fs->position = fc->position;
|
fs->position = fc->position;
|
||||||
fs->type = fc->type;
|
fs->type = fc->type;
|
||||||
init_form_state(fc, fs);
|
init_form_state(doc_view, fc, fs);
|
||||||
|
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
@ -1096,7 +1121,7 @@ do_reset_form(struct document_view *doc_view, struct form *form)
|
|||||||
foreach (fc, form->items) {
|
foreach (fc, form->items) {
|
||||||
struct form_state *fs = find_form_state(doc_view, fc);
|
struct form_state *fs = find_form_state(doc_view, fc);
|
||||||
|
|
||||||
if (fs) init_form_state(fc, fs);
|
if (fs) init_form_state(doc_view, fc, fs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user