diff options
author | jcid <devnull@localhost> | 2008-08-06 14:58:39 +0200 |
---|---|---|
committer | jcid <devnull@localhost> | 2008-08-06 14:58:39 +0200 |
commit | 9eba6c5572de8bfe82606206e8a44a403d936f32 (patch) | |
tree | 9a52e3a46def566c13dc562c0f72a6862fc85dd0 /src | |
parent | addc25b3b4bc19ddfe99e844df7fb3ac38c5866c (diff) |
- Allowed form inputs outside FORM (it's in the standard).
Diffstat (limited to 'src')
-rw-r--r-- | src/form.cc | 183 | ||||
-rw-r--r-- | src/form.hh | 2 | ||||
-rw-r--r-- | src/html.cc | 5 | ||||
-rw-r--r-- | src/html_common.hh | 1 |
4 files changed, 106 insertions, 85 deletions
diff --git a/src/form.cc b/src/form.cc index 73342f40..d708d2bc 100644 --- a/src/form.cc +++ b/src/form.cc @@ -37,7 +37,6 @@ using namespace dw::core::style; */ class DilloHtmlReceiver; -class DilloHtmlInput; class DilloHtmlSelect; class DilloHtmlOption; @@ -120,15 +119,10 @@ public: DilloHtmlMethod method, const DilloUrl *action, DilloHtmlEnc enc, const char *charset); ~DilloHtmlForm (); - DilloHtmlInput *getCurrentInput (); DilloHtmlInput *getInput (dw::core::ui::Resource *resource); DilloHtmlInput *getRadioInput (const char *name); void reset (); - void addInput(DilloHtmlInputType type, - dw::core::ui::Embed *embed, - const char *name, - const char *init_str, - bool init_val); + void addInput(DilloHtmlInput *input, DilloHtmlInputType type); }; class DilloHtmlReceiver: @@ -221,11 +215,72 @@ void a_Html_form_delete (DilloHtmlForm *form) delete form; } +void a_Html_input_delete (DilloHtmlInput *input) +{ + delete input; +} + /* * Form parsing functions */ /* + * Add an HTML control + */ +static void Html_add_input(DilloHtml *html, DilloHtmlInputType type, + dw::core::ui::Embed *embed, const char *name, + const char *init_str, bool init_val) +{ + _MSG("name=[%s] init_str=[%s] init_val=[%d]\n", name, init_str, init_val); + DilloHtmlInput *input = new DilloHtmlInput(type, embed, name, init_str, + init_val); + if (html->InFlags & IN_FORM) { + html->getCurrentForm()->addInput(input, type); + } else { + int ni = html->inputs_outside_form->size(); + html->inputs_outside_form->increase(); + html->inputs_outside_form->set(ni, input); + } +} + +/* + * Find radio input by name + */ +static DilloHtmlInput *Html_get_radio_input(DilloHtml *html, const char *name) +{ + lout::misc::SimpleVector<DilloHtmlInput*>* inputs; + + if (html->InFlags & IN_FORM) + inputs = html->getCurrentForm()->inputs; + else + inputs = html->inputs_outside_form; + + for (int idx = 0; idx < inputs->size(); idx++) { + DilloHtmlInput *input = inputs->get(idx); + if (input->type == DILLO_HTML_INPUT_RADIO && + input->name && !dStrcasecmp(input->name, name)) + return input; + } + return NULL; +} + +/* + * Get the current input. + * Note that this _assumes_ that there _is_ a current input. + */ +static DilloHtmlInput *Html_get_current_input(DilloHtml *html) +{ + lout::misc::SimpleVector<DilloHtmlInput*>* inputs; + + if (html->InFlags & IN_FORM) + inputs = html->getCurrentForm()->inputs; + else + inputs = html->inputs_outside_form; + + return inputs->get (inputs->size() - 1); +} + +/* * Handle <FORM> tag */ void Html_tag_open_form(DilloHtml *html, const char *tag, int tagsize) @@ -338,17 +393,12 @@ void Html_tag_close_form(DilloHtml *html, int TagIdx) */ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) { - DilloHtmlForm *form; DilloHtmlInputType inp_type; dw::core::ui::Embed *embed = NULL; char *value, *name, *type, *init_str; const char *attrbuf, *label; bool init_val = false; - if (!(html->InFlags & IN_FORM)) { - BUG_MSG("<input> element outside <form>\n"); - return; - } if (html->InFlags & IN_SELECT) { BUG_MSG("<input> element inside <select>\n"); return; @@ -358,8 +408,6 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) return; } - form = html->getCurrentForm (); - /* Get 'value', 'name' and 'type' */ value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL); name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL); @@ -383,7 +431,7 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) } else if (!dStrcasecmp(type, "radio")) { inp_type = DILLO_HTML_INPUT_RADIO; dw::core::ui::RadioButtonResource *rb_r = NULL; - DilloHtmlInput *input = form->getRadioInput(name); + DilloHtmlInput *input = Html_get_radio_input(html, name); if (input) rb_r = (dw::core::ui::RadioButtonResource*) @@ -432,15 +480,22 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) init_str = value; } } else if (!dStrcasecmp(type, "file")) { - if (form->method != DILLO_HTML_METHOD_POST) { - BUG_MSG("Forms with file input MUST use HTTP POST method\n"); - MSG("File input ignored in form not using HTTP POST method\n"); - } else if (form->enc != DILLO_HTML_ENC_MULTIPART) { - BUG_MSG("Forms with file input MUST use multipart/form-data" - " encoding\n"); - MSG("File input ignored in form not using multipart/form-data" - " encoding\n"); - } else { + bool valid = true; + if (html->InFlags & IN_FORM) { + DilloHtmlForm *form = html->getCurrentForm(); + if (form->method != DILLO_HTML_METHOD_POST) { + valid = false; + BUG_MSG("Forms with file input MUST use HTTP POST method\n"); + MSG("File input ignored in form not using HTTP POST method\n"); + } else if (form->enc != DILLO_HTML_ENC_MULTIPART) { + valid = false; + BUG_MSG("Forms with file input MUST use multipart/form-data" + " encoding\n"); + MSG("File input ignored in form not using multipart/form-data" + " encoding\n"); + } + } + if (valid) { inp_type = DILLO_HTML_INPUT_FILE; init_str = dStrdup("File selector"); dw::core::ui::LabelButtonResource *lbr = @@ -470,7 +525,7 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) } if (inp_type != DILLO_HTML_INPUT_UNKNOWN) { - form->addInput(inp_type, embed, name, + Html_add_input(html, inp_type, embed, name, (init_str) ? init_str : "", init_val); } @@ -515,7 +570,6 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize) */ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize) { - DilloHtmlForm *form; DilloUrl *action; dw::core::ui::Embed *embed; const char *attrbuf; @@ -532,8 +586,7 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize) html->formNew(DILLO_HTML_METHOD_GET, action, DILLO_HTML_ENC_URLENCODING, html->charset); - - form = html->getCurrentForm (); + html->InFlags |= IN_FORM; DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); @@ -543,7 +596,7 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize) dw::core::ui::EntryResource *entryResource = HT2LT(html)->getResourceFactory()->createEntryResource (10, false); embed = new dw::core::ui::Embed (entryResource); - form->addInput(DILLO_HTML_INPUT_INDEX, embed, NULL, NULL, FALSE); + Html_add_input(html, DILLO_HTML_INPUT_INDEX, embed, NULL, NULL, FALSE); if (prefs.standard_widget_colors) { HTML_SET_TOP_ATTR(html, color, NULL); @@ -552,6 +605,7 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize) DW2TB(html->dw)->addWidget (embed, S_TOP(html)->style); a_Url_free(action); + html->InFlags &= ~IN_FORM; } /* @@ -560,17 +614,10 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize) */ void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize) { - DilloHtmlForm *form; char *name; const char *attrbuf; int cols, rows; - /* We can't push a new <FORM> because the 'action' URL is unknown */ - if (!(html->InFlags & IN_FORM)) { - BUG_MSG("<textarea> outside <form>\n"); - html->ReqTagClose = TRUE; - return; - } if (html->InFlags & IN_TEXTAREA) { BUG_MSG("nested <textarea>\n"); html->ReqTagClose = TRUE; @@ -578,7 +625,6 @@ void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize) } html->InFlags |= IN_TEXTAREA; - form = html->getCurrentForm (); a_Html_stash_init(html); S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_VERBATIM; @@ -601,7 +647,7 @@ void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize) if (a_Html_get_attr(html, tag, tagsize, "readonly")) textres->setEditable(false); - form->addInput(DILLO_HTML_INPUT_TEXTAREA, embed, name, NULL, false); + Html_add_input(html, DILLO_HTML_INPUT_TEXTAREA, embed, name, NULL, false); DW2TB(html->dw)->addWidget (embed, S_TOP(html)->style); @@ -630,7 +676,7 @@ void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize) // gtk_widget_show(widget); // gtk_widget_show(scroll); // -// form->addInput(DILLO_HTML_INPUT_TEXTAREA, +// Html_add_input(html, DILLO_HTML_INPUT_TEXTAREA, // widget, name, NULL, FALSE); // dFree(name); // @@ -647,12 +693,10 @@ void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize) void Html_tag_close_textarea(DilloHtml *html, int TagIdx) { char *str; - DilloHtmlForm *form; DilloHtmlInput *input; int i; - if (html->InFlags & IN_FORM && - html->InFlags & IN_TEXTAREA) { + if (html->InFlags & IN_TEXTAREA) { /* Remove the line ending that follows the opening tag */ if (html->Stash->str[0] == '\r') dStr_erase(html->Stash, 0, 1); @@ -672,8 +716,7 @@ void Html_tag_close_textarea(DilloHtml *html, int TagIdx) /* The HTML3.2 spec says it can have "text and character entities". */ str = a_Html_parse_entities(html, html->Stash->str, html->Stash->len); - form = html->getCurrentForm (); - input = form->getCurrentInput (); + input = Html_get_current_input(html); input->init_str = str; ((dw::core::ui::MultiLineTextResource *)input->embed->getResource ()) ->setText(str); @@ -692,10 +735,6 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize) // const char *attrbuf; // int size, type, multi; - if (!(html->InFlags & IN_FORM)) { - BUG_MSG("<select> outside <form>\n"); - return; - } if (html->InFlags & IN_SELECT) { BUG_MSG("nested <select>\n"); return; @@ -703,7 +742,6 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize) html->InFlags |= IN_SELECT; html->InFlags &= ~IN_OPTION; - DilloHtmlForm *form = html->getCurrentForm (); char *name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL); dw::core::ui::ResourceFactory *factory = HT2LT(html)->getResourceFactory (); @@ -746,7 +784,7 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize) // type = DILLO_HTML_INPUT_SEL_LIST; // } - form->addInput(type, embed, name, NULL, false); + Html_add_input(html, type, embed, name, NULL, false); a_Html_stash_init(html); dFree(name); } @@ -756,15 +794,13 @@ void Html_tag_open_select(DilloHtml *html, const char *tag, int tagsize) */ void Html_tag_close_select(DilloHtml *html, int TagIdx) { - if (html->InFlags & IN_FORM && - html->InFlags & IN_SELECT) { + if (html->InFlags & IN_SELECT) { if (html->InFlags & IN_OPTION) Html_option_finish(html); html->InFlags &= ~IN_SELECT; html->InFlags &= ~IN_OPTION; - DilloHtmlForm *form = html->getCurrentForm (); - DilloHtmlInput *input = form->getCurrentInput (); + DilloHtmlInput *input = Html_get_current_input(html); DilloHtmlSelect *select = input->select; // BUG(?): should not do this for MULTI selections @@ -783,15 +819,15 @@ void Html_tag_close_select(DilloHtml *html, int TagIdx) */ void Html_tag_open_option(DilloHtml *html, const char *tag, int tagsize) { - if (!(html->InFlags & IN_FORM && - html->InFlags & IN_SELECT )) + if (!(html->InFlags & IN_SELECT)) { + BUG_MSG("<option> element outside <select>\n"); return; + } if (html->InFlags & IN_OPTION) Html_option_finish(html); html->InFlags |= IN_OPTION; - DilloHtmlForm *form = html->getCurrentForm (); - DilloHtmlInput *input = form->getCurrentInput (); + DilloHtmlInput *input = Html_get_current_input(html); if (input->type == DILLO_HTML_INPUT_SELECT || input->type == DILLO_HTML_INPUT_SEL_LIST) { @@ -816,21 +852,15 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize) * Buttons are rendered on one line, this is (at several levels) a * bit simpler. May be changed in the future. */ - DilloHtmlForm *form; DilloHtmlInputType inp_type; char *type; - if (!(html->InFlags & IN_FORM)) { - BUG_MSG("<button> element outside <form>\n"); - return; - } if (html->InFlags & IN_BUTTON) { BUG_MSG("nested <button>\n"); return; } html->InFlags |= IN_BUTTON; - form = html->getCurrentForm (); type = a_Html_get_attr_wdef(html, tag, tagsize, "type", ""); if (!dStrcasecmp(type, "button")) { @@ -880,7 +910,7 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize) value = a_Html_get_attr_wdef(html, tag, tagsize, "value", NULL); name = a_Html_get_attr_wdef(html, tag, tagsize, "name", NULL); - form->addInput(inp_type, embed, name, value, FALSE); + Html_add_input(html, inp_type, embed, name, value, FALSE); dFree(name); dFree(value); } @@ -1398,14 +1428,6 @@ void DilloHtmlForm::appendClickposMultipart(Dstr *data, } /* - * Get the current input. - */ -DilloHtmlInput *DilloHtmlForm::getCurrentInput () -{ - return inputs->get (inputs->size() - 1); -} - -/* * Reset all inputs containing reset to their initial values. In * general, reset is the reset button for the form. */ @@ -1417,18 +1439,10 @@ void DilloHtmlForm::reset () } /* - * Add a new input, setting the initial values. + * Add a new input. */ -void DilloHtmlForm::addInput(DilloHtmlInputType type, - dw::core::ui::Embed *embed, - const char *name, - const char *init_str, - bool init_val) +void DilloHtmlForm::addInput(DilloHtmlInput *input, DilloHtmlInputType type) { - _MSG("name=[%s] init_str=[%s] init_val=[%d]\n", - name, init_str, init_val); - DilloHtmlInput *input = - new DilloHtmlInput (type,embed,name,init_str,init_val); input->connectTo (form_receiver); int ni = inputs->size (); inputs->increase (); @@ -1911,8 +1925,7 @@ static dw::core::ui::Embed *Html_input_image(DilloHtml *html, */ static void Html_option_finish(DilloHtml *html) { - DilloHtmlForm *form = html->getCurrentForm (); - DilloHtmlInput *input = form->getCurrentInput (); + DilloHtmlInput *input = Html_get_current_input(html); if (input->type == DILLO_HTML_INPUT_SELECT || input->type == DILLO_HTML_INPUT_SEL_LIST) { DilloHtmlOption *option = diff --git a/src/form.hh b/src/form.hh index af7ff6f4..8375ba50 100644 --- a/src/form.hh +++ b/src/form.hh @@ -23,6 +23,7 @@ typedef enum { */ class DilloHtmlForm; +class DilloHtmlInput; class DilloHtml; /* @@ -36,6 +37,7 @@ DilloHtmlForm *a_Html_form_new(DilloHtml *html, const char *charset); void a_Html_form_delete(DilloHtmlForm* form); +void a_Html_input_delete(DilloHtmlInput* input); /* * Form parsing functions diff --git a/src/html.cc b/src/html.cc index 0ee3eb90..347cb4fa 100644 --- a/src/html.cc +++ b/src/html.cc @@ -503,6 +503,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, /* Init page-handling variables */ forms = new misc::SimpleVector <DilloHtmlForm*> (1); + inputs_outside_form = new misc::SimpleVector <DilloHtmlInput*> (1); links = new misc::SimpleVector <DilloUrl*> (64); images = new misc::SimpleVector <DilloLinkImage*> (16); //a_Dw_image_map_list_init(&maps); @@ -570,6 +571,10 @@ DilloHtml::~DilloHtml() a_Html_form_delete (forms->get(i)); delete(forms); + for (int i = 0; i < inputs_outside_form->size(); i++) + a_Html_input_delete(inputs_outside_form->get(i)); + delete(inputs_outside_form); + for (int i = 0; i < links->size(); i++) if (links->get(i)) a_Url_free(links->get(i)); diff --git a/src/html_common.hh b/src/html_common.hh index 77a97ff6..aac9f189 100644 --- a/src/html_common.hh +++ b/src/html_common.hh @@ -197,6 +197,7 @@ public: //BUG: for now everything is public /* Variables required after parsing (for page functionality) */ /* -------------------------------------------------------------------*/ lout::misc::SimpleVector<DilloHtmlForm*> *forms; + lout::misc::SimpleVector<DilloHtmlInput*> *inputs_outside_form; lout::misc::SimpleVector<DilloUrl*> *links; lout::misc::SimpleVector<DilloLinkImage*> *images; dw::ImageMapsList maps; |