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
124 lines
6.3 KiB
#include "INPUTElement.h" |
|
#include "../components/InputComponent.h" |
|
#include "../components/ButtonComponent.h" |
|
#include "../components/DocumentComponent.h" |
|
#include "../../Log.h" |
|
#include "../../parsers/markup/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->setValue(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, 0xA0A0A0FF, 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; |
|
}
|
|
|