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
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;
|
|
}
|