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.

152 lines
3.4 KiB

#include <iostream>
#include <emscripten.h>
#include <exception>
#include <map>
#include <sstream>
#include "src/class/Element.h"
#include "src/proc/string.cpp"
#include "src/proc/event.cpp"
#include "src/proc/uuid.cpp"
extern "C" {
//char* itest();
int str_pass_size();
void fire_event_bus(int key_pass);
}
// These are REQUIRED.
int str_pass_size() {
return cjs::str::pass_size();
}
void fire_event_bus(int string_pass) {
return cjs::event::handle_bus_fire(string_pass);
}
class Properties {
private:
std::map<std::string, std::string> _data = {};
public:
bool has(std::string key) {
return _data.find(key) != _data.end();
}
std::string get(std::string key) {
return _data[key];
}
std::string get(std::string key, std::string fallback) {
if ( !has(key) ) return fallback;
return get(key);
}
Properties* set(std::string key, std::string value) {
_data[key] = value;
return this;
}
};
class Component {
protected:
Element* container;
Properties* _properties;
virtual void mount_child(std::string selector, Component* component) {
Element* tag = container->querySelectChild(selector);
component->set_container(tag);
component->mount();
delete tag;
}
virtual std::string tmpl(std::string base) {
return "";
}
public:
virtual ~Component() {}
Component(Element* in_container) {
container = in_container;
_properties = new Properties();
}
Component(std::string selector) {
container = new Element(selector);
_properties = new Properties();
}
Component() {
container = nullptr;
_properties = new Properties();
}
virtual void set_container(Element* element) {
container = element;
}
virtual void mount() = 0;
virtual Properties* properties() {
return _properties;
}
};
class InputComponent : public Component {
public:
using Component::Component;
void mount() {
std::stringstream html;
if ( properties()->has("label") ) {
html << "<label>" << properties()->get("label") << "</label>";
}
html << "<br><input type=\"" << properties()->get("type", "text") << "\"";
if ( properties()->get("required", "false") == "true" ) {
html << " required";
}
if ( properties()->has("placeholder") ) {
html << " placeholder=\"" << properties()->get("placeholder") << "\"";
}
html << "/>";
}
};
class GreeterComponent : public Component {
public:
using Component::Component;
void mount() {
container->setInnerHTML("<h1>Hello, World!</h1>");
container->append("<h2><small>This is being rendered via a C++ component!</h2></small>");
container->append("<div id=\"input-container\"></div>");
InputComponent* input = new InputComponent();
input->properties()
->set("label", "What is your name?")
->set("required", "true")
->set("placeholder", "John Doe");
this->mount_child("#input-container", input);
}
};
int main(int argc, char** argv) {
EM_ASM(InitWrappers());
printf("C++.js has initialized!\n");
Element* p_tag = new Element("#container");
GreeterComponent* cpt = new GreeterComponent(p_tag);
cpt->mount();
delete p_tag;
return 0;
}