Forms code is a bit more RAII.
This commit is contained in:
122
src/form.cc
122
src/form.cc
@ -57,35 +57,11 @@ static Embed *Html_input_image(DilloHtml *html, const char *tag, int tagsize);
|
||||
|
||||
static void Html_option_finish(DilloHtml *html);
|
||||
|
||||
/*
|
||||
* Typedefs
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
DILLO_HTML_INPUT_UNKNOWN,
|
||||
DILLO_HTML_INPUT_TEXT,
|
||||
DILLO_HTML_INPUT_PASSWORD,
|
||||
DILLO_HTML_INPUT_CHECKBOX,
|
||||
DILLO_HTML_INPUT_RADIO,
|
||||
DILLO_HTML_INPUT_IMAGE,
|
||||
DILLO_HTML_INPUT_FILE,
|
||||
DILLO_HTML_INPUT_BUTTON,
|
||||
DILLO_HTML_INPUT_HIDDEN,
|
||||
DILLO_HTML_INPUT_SUBMIT,
|
||||
DILLO_HTML_INPUT_RESET,
|
||||
DILLO_HTML_INPUT_BUTTON_SUBMIT,
|
||||
DILLO_HTML_INPUT_BUTTON_RESET,
|
||||
DILLO_HTML_INPUT_SELECT,
|
||||
DILLO_HTML_INPUT_SEL_LIST,
|
||||
DILLO_HTML_INPUT_TEXTAREA,
|
||||
DILLO_HTML_INPUT_INDEX
|
||||
} DilloHtmlInputType;
|
||||
|
||||
/*
|
||||
* Class declarations
|
||||
*/
|
||||
|
||||
class DilloHtmlForm {
|
||||
class DilloHtmlFormImpl : public DilloHtmlForm {
|
||||
friend class DilloHtmlReceiver;
|
||||
friend class DilloHtmlInput;
|
||||
|
||||
@ -111,28 +87,33 @@ class DilloHtmlForm {
|
||||
|
||||
public: //BUG: for now everything is public
|
||||
DilloHtmlMethod method;
|
||||
DilloHtmlMethod get_method() const override { return method; }
|
||||
|
||||
DilloUrl *action;
|
||||
DilloHtmlEnc content_type;
|
||||
DilloHtmlEnc get_content_type() const override { return content_type; }
|
||||
char *submit_charset;
|
||||
|
||||
std::vector< std::shared_ptr< DilloHtmlInput > > inputs;
|
||||
std::vector< std::shared_ptr< DilloHtmlInput > > *get_inputs() override { return &inputs; }
|
||||
|
||||
|
||||
int num_entry_fields;
|
||||
|
||||
std::unique_ptr< DilloHtmlReceiver > form_receiver;
|
||||
|
||||
public:
|
||||
DilloHtmlForm (DilloHtml *html,
|
||||
DilloHtmlFormImpl (DilloHtml *html,
|
||||
DilloHtmlMethod method, const DilloUrl *action,
|
||||
DilloHtmlEnc content_type, const char *charset,
|
||||
bool enabled);
|
||||
~DilloHtmlForm ();
|
||||
~DilloHtmlFormImpl () override;
|
||||
std::shared_ptr< DilloHtmlInput > getInput (Resource *resource);
|
||||
std::shared_ptr< DilloHtmlInput > getRadioInput (const char *name);
|
||||
void submit(DilloHtmlInput *active_input, EventButton *event);
|
||||
void reset ();
|
||||
void display_hiddens(bool display);
|
||||
void addInput(std::unique_ptr< DilloHtmlInput > input, DilloHtmlInputType type);
|
||||
void addInput(std::unique_ptr< DilloHtmlInput > input, DilloHtmlInputType type) override;
|
||||
void setEnabled(bool enabled);
|
||||
};
|
||||
|
||||
@ -141,11 +122,11 @@ class DilloHtmlReceiver:
|
||||
public Resource::ClickedReceiver
|
||||
{
|
||||
private:
|
||||
friend class DilloHtmlForm;
|
||||
DilloHtmlForm* form;
|
||||
friend class DilloHtmlFormImpl;
|
||||
DilloHtmlFormImpl* form;
|
||||
|
||||
public:
|
||||
DilloHtmlReceiver (DilloHtmlForm* form2) { form = form2; }
|
||||
DilloHtmlReceiver (DilloHtmlFormImpl* form2) { form = form2; }
|
||||
~DilloHtmlReceiver () { }
|
||||
|
||||
private:
|
||||
@ -157,8 +138,8 @@ private:
|
||||
|
||||
class DilloHtmlInput {
|
||||
|
||||
// DilloHtmlForm::addInput() calls connectTo()
|
||||
friend class DilloHtmlForm;
|
||||
// DilloHtmlFormImpl::addInput() calls connectTo()
|
||||
friend class DilloHtmlFormImpl;
|
||||
|
||||
public: //BUG: for now everything is public
|
||||
DilloHtmlInputType type;
|
||||
@ -174,7 +155,7 @@ public: //BUG: for now everything is public
|
||||
|
||||
private:
|
||||
void connectTo(DilloHtmlReceiver *form_receiver);
|
||||
void activate(DilloHtmlForm *form, int num_entry_fields,EventButton *event);
|
||||
void activate(DilloHtmlFormImpl *form, int num_entry_fields,EventButton *event);
|
||||
void readFile(BrowserWindow *bw);
|
||||
|
||||
public:
|
||||
@ -250,20 +231,15 @@ public:
|
||||
* Form API
|
||||
*/
|
||||
|
||||
DilloHtmlForm *a_Html_form_new (DilloHtml *html, DilloHtmlMethod method,
|
||||
std::unique_ptr< DilloHtmlForm > a_Html_form_new (DilloHtml *html, DilloHtmlMethod method,
|
||||
const DilloUrl *action,
|
||||
DilloHtmlEnc content_type, const char *charset,
|
||||
bool enabled)
|
||||
{
|
||||
return new DilloHtmlForm (html, method, action, content_type, charset,
|
||||
return std::make_unique< DilloHtmlFormImpl > (html, method, action, content_type, charset,
|
||||
enabled);
|
||||
}
|
||||
|
||||
void a_Html_form_delete (DilloHtmlForm *form)
|
||||
{
|
||||
delete form;
|
||||
}
|
||||
|
||||
void a_Html_input_delete (DilloHtmlInput *input)
|
||||
{
|
||||
delete input;
|
||||
@ -271,17 +247,17 @@ void a_Html_input_delete (DilloHtmlInput *input)
|
||||
|
||||
void a_Html_form_submit2(void *vform)
|
||||
{
|
||||
((DilloHtmlForm *)vform)->submit(NULL, NULL);
|
||||
((DilloHtmlFormImpl *)vform)->submit(NULL, NULL);
|
||||
}
|
||||
|
||||
void a_Html_form_reset2(void *vform)
|
||||
{
|
||||
((DilloHtmlForm *)vform)->reset();
|
||||
((DilloHtmlFormImpl *)vform)->reset();
|
||||
}
|
||||
|
||||
void a_Html_form_display_hiddens2(void *vform, bool display)
|
||||
{
|
||||
((DilloHtmlForm *)vform)->display_hiddens(display);
|
||||
((DilloHtmlFormImpl *)vform)->display_hiddens(display);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -318,7 +294,7 @@ static std::shared_ptr< DilloHtmlInput > Html_get_radio_input(DilloHtml *html, c
|
||||
std::vector< std::shared_ptr< DilloHtmlInput > > *inputs;
|
||||
|
||||
if (html->InFlags & IN_FORM)
|
||||
inputs = &html->getCurrentForm()->inputs;
|
||||
inputs = html->getCurrentForm()->get_inputs();
|
||||
else
|
||||
inputs = &html->inputs_outside_form;
|
||||
|
||||
@ -340,7 +316,7 @@ static std::shared_ptr< DilloHtmlInput > Html_get_current_input(DilloHtml &html)
|
||||
std::vector< std::shared_ptr< DilloHtmlInput > > *inputs;
|
||||
|
||||
if (html.InFlags & IN_FORM)
|
||||
inputs = &html.getCurrentForm()->inputs;
|
||||
inputs = html.getCurrentForm()->get_inputs();
|
||||
else
|
||||
inputs = &html.inputs_outside_form;
|
||||
|
||||
@ -524,11 +500,11 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
|
||||
bool valid = true;
|
||||
if (html->InFlags & IN_FORM) {
|
||||
DilloHtmlForm *form = html->getCurrentForm();
|
||||
if (form->method != DILLO_HTML_METHOD_POST) {
|
||||
if (form->get_method() != DILLO_HTML_METHOD_POST) {
|
||||
valid = false;
|
||||
BUG_MSG("<form> with file input MUST use HTTP POST method.");
|
||||
MSG("File input ignored in form not using HTTP POST method\n");
|
||||
} else if (form->content_type != DILLO_HTML_ENC_MULTIPART) {
|
||||
} else if (form->get_content_type() != DILLO_HTML_ENC_MULTIPART) {
|
||||
valid = false;
|
||||
BUG_MSG("<form> with file input MUST use multipart/form-data"
|
||||
" encoding.");
|
||||
@ -988,7 +964,7 @@ void Html_tag_close_button(DilloHtml *html)
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
DilloHtmlForm::DilloHtmlForm (DilloHtml *html2,
|
||||
DilloHtmlFormImpl::DilloHtmlFormImpl (DilloHtml *html2,
|
||||
DilloHtmlMethod method2,
|
||||
const DilloUrl *action2,
|
||||
DilloHtmlEnc content_type2,
|
||||
@ -1008,16 +984,16 @@ DilloHtmlForm::DilloHtmlForm (DilloHtml *html2,
|
||||
/*
|
||||
* Destructor
|
||||
*/
|
||||
DilloHtmlForm::~DilloHtmlForm ()
|
||||
DilloHtmlFormImpl::~DilloHtmlFormImpl ()
|
||||
{
|
||||
delete action;
|
||||
dFree(submit_charset);
|
||||
inputs.clear();
|
||||
}
|
||||
|
||||
void DilloHtmlForm::eventHandler(Resource *resource, EventButton *event)
|
||||
void DilloHtmlFormImpl::eventHandler(Resource *resource, EventButton *event)
|
||||
{
|
||||
_MSG("DilloHtmlForm::eventHandler\n");
|
||||
_MSG("DilloHtmlFormImpl::eventHandler\n");
|
||||
if (event && (event->button == 3)) {
|
||||
a_UIcmd_form_popup(html->bw, html->page_url, this, showing_hiddens);
|
||||
} else {
|
||||
@ -1025,7 +1001,7 @@ void DilloHtmlForm::eventHandler(Resource *resource, EventButton *event)
|
||||
if (input) {
|
||||
input->activate (this, num_entry_fields, event);
|
||||
} else {
|
||||
MSG("DilloHtmlForm::eventHandler: ERROR, input not found!\n");
|
||||
MSG("DilloHtmlFormImpl::eventHandler: ERROR, input not found!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1034,7 +1010,7 @@ void DilloHtmlForm::eventHandler(Resource *resource, EventButton *event)
|
||||
* Submit.
|
||||
* (Called by eventHandler())
|
||||
*/
|
||||
void DilloHtmlForm::submit(DilloHtmlInput *active_input, EventButton *event)
|
||||
void DilloHtmlFormImpl::submit(DilloHtmlInput *active_input, EventButton *event)
|
||||
{
|
||||
if (!dStrAsciiCasecmp(URL_SCHEME(html->page_url), "https") &&
|
||||
dStrAsciiCasecmp(URL_SCHEME(action), "https")) {
|
||||
@ -1066,7 +1042,7 @@ void DilloHtmlForm::submit(DilloHtmlInput *active_input, EventButton *event)
|
||||
* Build a new query URL.
|
||||
* (Called by submit())
|
||||
*/
|
||||
std::unique_ptr< DilloUrl > DilloHtmlForm::buildQueryUrl(DilloHtmlInput *active_input)
|
||||
std::unique_ptr< DilloUrl > DilloHtmlFormImpl::buildQueryUrl(DilloHtmlInput *active_input)
|
||||
{
|
||||
std::unique_ptr< DilloUrl > new_url;
|
||||
|
||||
@ -1075,7 +1051,7 @@ std::unique_ptr< DilloUrl > DilloHtmlForm::buildQueryUrl(DilloHtmlInput *active_
|
||||
std::string DataStr;
|
||||
DilloHtmlInput *active_submit = NULL;
|
||||
|
||||
_MSG("DilloHtmlForm::buildQueryUrl: action=%s\n",URL_STR_(action));
|
||||
_MSG("DilloHtmlFormImpl::buildQueryUrl: action=%s\n",URL_STR_(action));
|
||||
|
||||
if (active_input) {
|
||||
if ((active_input->type == DILLO_HTML_INPUT_SUBMIT) ||
|
||||
@ -1114,7 +1090,7 @@ std::unique_ptr< DilloUrl > DilloHtmlForm::buildQueryUrl(DilloHtmlInput *active_
|
||||
dFree(action_str);
|
||||
}
|
||||
} else {
|
||||
MSG("DilloHtmlForm::buildQueryUrl: Method unknown\n");
|
||||
MSG("DilloHtmlFormImpl::buildQueryUrl: Method unknown\n");
|
||||
}
|
||||
|
||||
return new_url;
|
||||
@ -1123,7 +1099,7 @@ std::unique_ptr< DilloUrl > DilloHtmlForm::buildQueryUrl(DilloHtmlInput *active_
|
||||
/**
|
||||
* Construct the data for a query URL
|
||||
*/
|
||||
std::optional< std::string > DilloHtmlForm::buildQueryData(DilloHtmlInput *active_submit)
|
||||
std::optional< std::string > DilloHtmlFormImpl::buildQueryData(DilloHtmlInput *active_submit)
|
||||
{
|
||||
std::string DataStr;
|
||||
char *boundary = nullptr;
|
||||
@ -1256,7 +1232,7 @@ static void generate_boundary(Dstr *boundary)
|
||||
* Generate a boundary string for use in separating the parts of a
|
||||
* multipart/form-data submission.
|
||||
*/
|
||||
char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
|
||||
char *DilloHtmlFormImpl::makeMultipartBoundary(iconv_t char_encoder,
|
||||
DilloHtmlInput *active_submit)
|
||||
{
|
||||
std::vector< std::string > values;
|
||||
@ -1307,7 +1283,7 @@ char *DilloHtmlForm::makeMultipartBoundary(iconv_t char_encoder,
|
||||
* Return value: same input Dstr if no encoding is needed.
|
||||
* new Dstr when encoding (input Dstr is freed).
|
||||
*/
|
||||
std::string DilloHtmlForm::encodeText(iconv_t char_encoder, std::string &&input)
|
||||
std::string DilloHtmlFormImpl::encodeText(iconv_t char_encoder, std::string &&input)
|
||||
{
|
||||
int rc = 0;
|
||||
Dstr *output;
|
||||
@ -1375,7 +1351,7 @@ std::string DilloHtmlForm::encodeText(iconv_t char_encoder, std::string &&input)
|
||||
/**
|
||||
* Urlencode 'str' and append it to 'dstr'
|
||||
*/
|
||||
void DilloHtmlForm::strUrlencodeAppend(std::string &dstr, std::string_view str_)
|
||||
void DilloHtmlFormImpl::strUrlencodeAppend(std::string &dstr, std::string_view str_)
|
||||
{
|
||||
const std::string str{ str_ };
|
||||
auto encoded= Alepha::AutoRAII
|
||||
@ -1389,7 +1365,7 @@ void DilloHtmlForm::strUrlencodeAppend(std::string &dstr, std::string_view str_)
|
||||
/**
|
||||
* Append a name-value pair to url data using url encoding.
|
||||
*/
|
||||
void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const std::string_view name,
|
||||
void DilloHtmlFormImpl::inputUrlencodeAppend(std::string &data, const std::string_view name,
|
||||
const std::string_view value)
|
||||
{
|
||||
if (not name.empty()) {
|
||||
@ -1404,7 +1380,7 @@ void DilloHtmlForm::inputUrlencodeAppend(std::string &data, const std::string_vi
|
||||
* Append files to URL data using multipart encoding.
|
||||
* Currently only accepts one file.
|
||||
*/
|
||||
void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
void DilloHtmlFormImpl::filesInputMultipartAppend(std::string &data,
|
||||
std::string_view boundary,
|
||||
std::string_view name,
|
||||
const std::string &file,
|
||||
@ -1453,7 +1429,7 @@ void DilloHtmlForm::filesInputMultipartAppend(std::string &data,
|
||||
/**
|
||||
* Append a name-value pair to url data using multipart encoding.
|
||||
*/
|
||||
void DilloHtmlForm::inputMultipartAppend(std::string &data,
|
||||
void DilloHtmlFormImpl::inputMultipartAppend(std::string &data,
|
||||
std::string_view boundary,
|
||||
std::string_view name,
|
||||
std::string_view value)
|
||||
@ -1476,7 +1452,7 @@ void DilloHtmlForm::inputMultipartAppend(std::string &data,
|
||||
/**
|
||||
* Append an image button click position to url data using url encoding.
|
||||
*/
|
||||
void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, const std::string_view name, const std::string_view x,
|
||||
void DilloHtmlFormImpl::imageInputUrlencodeAppend(std::string &data, const std::string_view name, const std::string_view x,
|
||||
const std::string_view y)
|
||||
{
|
||||
if (not name.empty()) {
|
||||
@ -1495,7 +1471,7 @@ void DilloHtmlForm::imageInputUrlencodeAppend(std::string &data, const std::stri
|
||||
/**
|
||||
* Append an image button click position to url data using multipart encoding.
|
||||
*/
|
||||
void DilloHtmlForm::imageInputMultipartAppend(std::string &data, const std::string_view boundary,
|
||||
void DilloHtmlFormImpl::imageInputMultipartAppend(std::string &data, const std::string_view boundary,
|
||||
const std::string_view name_, const std::string_view x_, const std::string_view y_)
|
||||
{
|
||||
std::string name{ name_ };
|
||||
@ -1517,7 +1493,7 @@ void DilloHtmlForm::imageInputMultipartAppend(std::string &data, const std::stri
|
||||
* Reset all inputs containing reset to their initial values. In
|
||||
* general, reset is the reset button for the form.
|
||||
*/
|
||||
void DilloHtmlForm::reset ()
|
||||
void DilloHtmlFormImpl::reset ()
|
||||
{
|
||||
int size = inputs.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
@ -1527,7 +1503,7 @@ void DilloHtmlForm::reset ()
|
||||
/**
|
||||
* Show/hide "hidden" form controls
|
||||
*/
|
||||
void DilloHtmlForm::display_hiddens(bool display)
|
||||
void DilloHtmlFormImpl::display_hiddens(bool display)
|
||||
{
|
||||
int size = inputs.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -1539,7 +1515,7 @@ void DilloHtmlForm::display_hiddens(bool display)
|
||||
showing_hiddens = display;
|
||||
}
|
||||
|
||||
void DilloHtmlForm::setEnabled(bool enabled)
|
||||
void DilloHtmlFormImpl::setEnabled(bool enabled)
|
||||
{
|
||||
for (int i = 0; i < inputs.size(); i++)
|
||||
inputs.at(i)->setEnabled(enabled);
|
||||
@ -1548,7 +1524,7 @@ void DilloHtmlForm::setEnabled(bool enabled)
|
||||
/**
|
||||
* Add a new input.
|
||||
*/
|
||||
void DilloHtmlForm::addInput(std::unique_ptr< DilloHtmlInput > input, DilloHtmlInputType type)
|
||||
void DilloHtmlFormImpl::addInput(std::unique_ptr< DilloHtmlInput > input, DilloHtmlInputType type)
|
||||
{
|
||||
input->connectTo (form_receiver.get());
|
||||
input->setEnabled (enabled);
|
||||
@ -1564,7 +1540,7 @@ void DilloHtmlForm::addInput(std::unique_ptr< DilloHtmlInput > input, DilloHtmlI
|
||||
/**
|
||||
* Return the input with a given resource.
|
||||
*/
|
||||
std::shared_ptr< DilloHtmlInput > DilloHtmlForm::getInput (Resource *resource)
|
||||
std::shared_ptr< DilloHtmlInput > DilloHtmlFormImpl::getInput (Resource *resource)
|
||||
{
|
||||
for (int idx = 0; idx < inputs.size(); idx++) {
|
||||
auto input = inputs.at(idx);
|
||||
@ -1578,7 +1554,7 @@ std::shared_ptr< DilloHtmlInput > DilloHtmlForm::getInput (Resource *resource)
|
||||
/**
|
||||
* Return a Radio input for the given name.
|
||||
*/
|
||||
std::shared_ptr< DilloHtmlInput > DilloHtmlForm::getRadioInput (const char *name)
|
||||
std::shared_ptr< DilloHtmlInput > DilloHtmlFormImpl::getRadioInput (const char *name)
|
||||
{
|
||||
for (int idx = 0; idx < inputs.size(); idx++) {
|
||||
auto input = inputs.at(idx);
|
||||
@ -1703,7 +1679,7 @@ void DilloHtmlInput::connectTo(DilloHtmlReceiver *form_receiver)
|
||||
/**
|
||||
* Activate a form
|
||||
*/
|
||||
void DilloHtmlInput::activate(DilloHtmlForm *form, int num_entry_fields,
|
||||
void DilloHtmlInput::activate(DilloHtmlFormImpl *form, int num_entry_fields,
|
||||
EventButton *event)
|
||||
{
|
||||
switch (type) {
|
||||
|
||||
Reference in New Issue
Block a user