You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

124 lines
6.3 KiB

#include "INPUTElement.h"
#include "../components/InputComponent.h"
#include "../components/ButtonComponent.h"
#include "../components/DocumentComponent.h"
#include "../../Log.h"
#include "../../html/HTMLParser.h"
#include "../../FormData.h"
#include <ctime>
INPUTElement::INPUTElement() {
isInline = true;
}
std::unique_ptr<Component> INPUTElement::renderer(const ElementRenderRequest &request) {
// const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int windowWidth, const int windowHeight
// what should our default size be?
//std::cout << "INPUTElement::renderer - creating InputComponent at " << x << "x" << y << std::endl;
TagNode *tagNode = dynamic_cast<TagNode*>(request.node.get());
if (tagNode) {
std::string type = "text";
auto propIter = tagNode->properties.find("type");
if (propIter != tagNode->properties.end()) {
//std::cout << "input is of type: " << propIter->second << std::endl;
type = propIter->second;
}
//std::cout << "type is " << type << std::endl;
if (type == "text") {
std::unique_ptr<InputComponent> inputComponent = std::make_unique<InputComponent>(0, 0, 125.0f, 13.0f, request.parentComponent->win->windowWidth, request.parentComponent->win->windowHeight);
inputComponent->node = tagNode;
inputComponent->name = "textInput";
auto propIter2 = tagNode->properties.find("value");
if (propIter2 != tagNode->properties.end()) {
inputComponent->value = propIter2->second;
}
return std::move(inputComponent);
} else if (type == "submit") {
//std::cout << "Creating submit" << std::endl;
std::unique_ptr<ButtonComponent> butComponent = std::make_unique<ButtonComponent>(0, 0, 62.0f, 13.0f, request.parentComponent->win->windowWidth, request.parentComponent->win->windowHeight);
auto propIter3 = tagNode->properties.find("value");
if (propIter3 != tagNode->properties.end()) {
butComponent->value = propIter3->second;
// resize button to text size
butComponent->resizeToTextSize();
} else {
butComponent->value = "Submit";
}
butComponent->onClick=[tagNode, request]() {
// recurse up to find oug form tag
std::shared_ptr<Node> formNode = Node::findTagNodeParent("form", request.node);
if (!formNode) {
std::cout << "INPUTElement::renderer:butComponent->onClick - Can't find form parent for submit" << std::endl;
return;
}
if (!request.docComponent) {
std::cout << "INPUTElement::renderer:butComponent->onClick - Can't find documentComponent for submit" << std::endl;
return;
}
TagNode *formTagNode = dynamic_cast<TagNode*>(formNode.get());
auto formNodeActionIter = formTagNode->properties.find("action");
if (formNodeActionIter == formTagNode->properties.end()) {
std::cout << "Form has no action" << std::endl;
return;
}
auto formNodeMethodIter = formTagNode->properties.find("method");
std::string method="GET";
if (formNodeMethodIter != formTagNode->properties.end()) {
method=formNodeMethodIter->second;
}
std::cout << "Form method is " << method << std::endl;
auto formData = buildFormData(formNode, nullptr);
// add our name/value (because we skip all submit buttons, there can only be one)
auto submitButtonNameValue = tagNode->getTagNodeNameValue();
if (submitButtonNameValue) {
formData->insert(*submitButtonNameValue);
}
if (method=="POST" || method=="post") {
// need documentComponent
URL uAction = request.docComponent->currentURL.merge(URL(formNodeActionIter->second));
std::cout << "Action URL is " << uAction.toString() << std::endl;
// download URL
WebResource res = getOnlineWebResource(uAction, std::move(formData));
request.docComponent->handleResource(res, uAction.toString());
} else {
// need documentComponent
std::string queryString = "";
if (formData) {
// iterator over formData
for (auto &entry : *formData) {
queryString += entry.first + "=" + entry.second + "&";
}
// strip last & off
queryString = queryString.substr(0, queryString.size() - 1);
std::cout << "queryString is " << queryString << std::endl;
// The moral of the story is, if you have binary (non-alphanumeric) data (or a significantly sized payload) to transmit, use multipart/form-data
auto search = queryString.find(" ");
if (search != std::string::npos) {
queryString.replace(search, 1, "+");
}
}
URL uAction = request.docComponent->currentURL.merge(URL(formNodeActionIter->second+"?"+queryString));
std::cout << "Action URL is " << uAction.toString() << std::endl;
// download URL
WebResource res = getOnlineWebResource(uAction, nullptr);
request.docComponent->handleResource(res, uAction.toString());
}
};
return std::move(butComponent);
} else if (type == "hidden") {
// we don't need a UI component but we do belong in the form
} else {
// submit, button, checkbox, file
//std::cout << "INPUTElement::renderer - ignoring input is of type: " << type << std::endl;
}
}
return nullptr;
}