|
|
|
#include "SegfaultApp.h"
|
|
|
|
#include <Wt/WContainerWidget.h>
|
|
#include <Wt/WPushButton.h>
|
|
#include <Wt/WTemplate.h>
|
|
#include <Wt/WText.h>
|
|
|
|
#include <Wt/WDialog.h>
|
|
|
|
namespace TestCase
|
|
{
|
|
namespace SegfaultOnF5
|
|
{
|
|
|
|
std::unique_ptr<Application> createApplication(const Wt::WEnvironment& env)
|
|
{
|
|
return std::make_unique<Application>(env);
|
|
}
|
|
|
|
|
|
DefaultWidget::DefaultWidget()
|
|
{
|
|
createLayout();
|
|
setupConnections();
|
|
}
|
|
|
|
void DefaultWidget::setupForFail()
|
|
{
|
|
tmpl_Layout->setCondition("if_Layer2", true);
|
|
tmpl_Layout->setCondition("if_Fault", true);
|
|
btn_Fail = tmpl_Layout->bindNew<Wt::WPushButton>("btn_Fail", "This Button should not be seen in the example");
|
|
|
|
btn_Fail->clicked().connect([this](){
|
|
|
|
addNew<Wt::WText>("This also should never be seen, but the connection itself is key");
|
|
});
|
|
btn_Fail->clicked().preventPropagation();
|
|
}
|
|
|
|
|
|
void DefaultWidget::handlePathChange(const std::string& path)
|
|
{
|
|
if(path.rfind("/fault", 0) == 0)
|
|
{
|
|
faultContainer->setHidden(false);
|
|
tmpl_Layout->setHidden(true);
|
|
}
|
|
}
|
|
|
|
void DefaultWidget::createLayout()
|
|
{
|
|
faultContainer = addNew<Wt::WContainerWidget>();
|
|
faultContainer->addNew<Wt::WText>("If this Widget is shown on Application Startup and navigated away from the app, Destruction should cause a Segfault.");
|
|
faultContainer->addNew<Wt::WBreak>();
|
|
faultContainer->addNew<Wt::WText>("On the other hand, if after starting here and this button is pressed to show the other widget, it should not.");
|
|
|
|
faultContainer->addNew<Wt::WBreak>();
|
|
btn_Success = faultContainer->addNew<Wt::WPushButton>("Click to avoid Sefault");
|
|
|
|
faultContainer->setHidden(true);
|
|
|
|
tmpl_Layout = addNew<Wt::WTemplate>(
|
|
"<div>"
|
|
"<p>"
|
|
"This is the default Widget to be shown. If you see this before navigating away, a Segfault should not happen"
|
|
"</p>"
|
|
"${<if_Fault>}"
|
|
"<p>This should be seen</p>"
|
|
"${<if_Layer2>}"
|
|
"${btn_Fail}"
|
|
"${</if_Layer2>}"
|
|
"${</if_Fault>}"
|
|
"</div>"
|
|
);
|
|
tmpl_Layout->setCondition("if_Fault", false);
|
|
|
|
}
|
|
|
|
void DefaultWidget::setupConnections()
|
|
{
|
|
|
|
tmpl_Layout->clicked().connect([this](){
|
|
this->btn_Fail->setDisabled(true);
|
|
});
|
|
|
|
btn_Success->clicked().connect([this](){
|
|
faultContainer->setHidden(true);
|
|
tmpl_Layout->setHidden(false);
|
|
Wt::WApplication::instance()->setInternalPath("/");
|
|
});
|
|
}
|
|
|
|
|
|
|
|
|
|
Application::Application(const Wt::WEnvironment &env)
|
|
: Wt::WApplication(env)
|
|
{
|
|
createLayout();
|
|
setupConnections();
|
|
|
|
wgt_Default->setupForFail();
|
|
|
|
wgt_Default->handlePathChange(internalPath());
|
|
}
|
|
|
|
void Application::createLayout()
|
|
{
|
|
wgt_Default = root()->addNew<DefaultWidget>();
|
|
}
|
|
|
|
void Application::setupConnections()
|
|
{
|
|
internalPathChanged().connect(wgt_Default, &DefaultWidget::handlePathChange);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|