comet-cpp 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/comet-html +69 -0
- data/bin/comet-make +53 -0
- data/bin/comet-new +62 -0
- data/bin/comet-web +14 -0
- data/lib/comet-html/generator.rb +220 -0
- data/lib/comet-html/header-generator.rb +145 -0
- data/lib/comet-html/parser-binding.rb +42 -0
- data/lib/comet-html/parser-class.rb +168 -0
- data/lib/comet-html/parser-context.rb +61 -0
- data/lib/comet-html/parser-reference.rb +98 -0
- data/lib/comet-html/parser-repeater.rb +58 -0
- data/lib/comet-html/parser-slot.rb +108 -0
- data/lib/comet-html/source-generator.rb +285 -0
- data/lib/comet-html/utils.rb +88 -0
- data/lib/guard/comet-html.rb +32 -0
- data/lib/guard/comet.rb +36 -0
- data/vendor/project/Gemfile +4 -0
- data/vendor/project/Guardfile +5 -0
- data/vendor/project/app/application.hpp +29 -0
- data/vendor/project/app/collections/.gitkeep +0 -0
- data/vendor/project/app/controllers/.gitkeep +0 -0
- data/vendor/project/app/main.cpp +6 -0
- data/vendor/project/app/models/.gitkeep +0 -0
- data/vendor/project/app/routes.cpp +7 -0
- data/vendor/project/app/views/layouts/.gitkeep +0 -0
- data/vendor/project/public/index.html +7 -0
- data/vendor/src/anchorable_element.hpp +79 -0
- data/vendor/src/append_semantics.hpp +73 -0
- data/vendor/src/bindable.cpp +99 -0
- data/vendor/src/bindable.hpp +106 -0
- data/vendor/src/cheerp_parse_cookie_values.cpp +58 -0
- data/vendor/src/comment_element.cpp +11 -0
- data/vendor/src/comment_element.hpp +17 -0
- data/vendor/src/cookies.cpp +94 -0
- data/vendor/src/cookies.hpp +60 -0
- data/vendor/src/custom_element.hpp +61 -0
- data/vendor/src/datatree.cpp +198 -0
- data/vendor/src/datatree.hpp +233 -0
- data/vendor/src/document.cpp +62 -0
- data/vendor/src/document.hpp +31 -0
- data/vendor/src/element.cpp +358 -0
- data/vendor/src/element.hpp +138 -0
- data/vendor/src/events.hpp +76 -0
- data/vendor/src/exception.cpp +13 -0
- data/vendor/src/exception.hpp +11 -0
- data/vendor/src/from_string.cpp +99 -0
- data/vendor/src/from_string.hpp +37 -0
- data/vendor/src/globals.cpp +6 -0
- data/vendor/src/globals.hpp +15 -0
- data/vendor/src/http.cpp +93 -0
- data/vendor/src/http.hpp +72 -0
- data/vendor/src/lexical_cast.hpp +51 -0
- data/vendor/src/local_storage.cpp +75 -0
- data/vendor/src/local_storage.hpp +53 -0
- data/vendor/src/mvc/collection.hpp +154 -0
- data/vendor/src/mvc/controller.hpp +59 -0
- data/vendor/src/mvc/id_type.hpp +9 -0
- data/vendor/src/mvc/layout.hpp +44 -0
- data/vendor/src/mvc/model.cpp +89 -0
- data/vendor/src/mvc/model.hpp +50 -0
- data/vendor/src/object.cpp +71 -0
- data/vendor/src/object.hpp +298 -0
- data/vendor/src/parse_cookie_values.hpp +12 -0
- data/vendor/src/promise.cpp +50 -0
- data/vendor/src/promise.hpp +43 -0
- data/vendor/src/repeater.hpp +116 -0
- data/vendor/src/router.cpp +62 -0
- data/vendor/src/router.hpp +34 -0
- data/vendor/src/router_base.hpp +107 -0
- data/vendor/src/signal.hpp +150 -0
- data/vendor/src/slot_element.hpp +61 -0
- data/vendor/src/url.cpp +19 -0
- data/vendor/src/url.hpp +15 -0
- data/vendor/src/window.cpp +22 -0
- data/vendor/src/window.hpp +24 -0
- metadata +134 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
#include "bindable.hpp"
|
2
|
+
#include "globals.hpp"
|
3
|
+
#include "from_string.hpp"
|
4
|
+
|
5
|
+
using namespace Comet;
|
6
|
+
|
7
|
+
Bindable& Bindable::use_mode(BindMode mode, const std::string& parameter)
|
8
|
+
{
|
9
|
+
bind_mode = mode;
|
10
|
+
switch (mode)
|
11
|
+
{
|
12
|
+
case ThrottleBind:
|
13
|
+
throttle_refresh = Comet::from_string<unsigned long>(parameter);
|
14
|
+
break ;
|
15
|
+
case SignalBind:
|
16
|
+
signal_name = parameter;
|
17
|
+
break ;
|
18
|
+
case StaticBind:
|
19
|
+
break ;
|
20
|
+
}
|
21
|
+
return *this;
|
22
|
+
}
|
23
|
+
|
24
|
+
void Bindable::enable(Comet::Signal<std::string>& signal)
|
25
|
+
{
|
26
|
+
enabled = true;
|
27
|
+
switch (bind_mode)
|
28
|
+
{
|
29
|
+
case StaticBind:
|
30
|
+
break ;
|
31
|
+
case SignalBind:
|
32
|
+
listen_to(signal, [this](const std::string& name) {
|
33
|
+
if (name == signal_name)
|
34
|
+
update();
|
35
|
+
});
|
36
|
+
break ;
|
37
|
+
case ThrottleBind:
|
38
|
+
enabled_ptr = std::make_shared<bool>(true);
|
39
|
+
throttle_schedule();
|
40
|
+
break ;
|
41
|
+
}
|
42
|
+
update();
|
43
|
+
}
|
44
|
+
|
45
|
+
void Bindable::disable()
|
46
|
+
{
|
47
|
+
enabled = false;
|
48
|
+
switch (bind_mode)
|
49
|
+
{
|
50
|
+
case StaticBind:
|
51
|
+
case ThrottleBind:
|
52
|
+
(*enabled_ptr) = false;
|
53
|
+
break ;
|
54
|
+
case SignalBind:
|
55
|
+
stop_listening();
|
56
|
+
break ;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
void Bindable::update()
|
61
|
+
{
|
62
|
+
if (has_updater)
|
63
|
+
{
|
64
|
+
__asm__("try {");
|
65
|
+
updater();
|
66
|
+
__asm__("} catch(error) { console.error('[Comet] failed to update Bindable:', error); }");
|
67
|
+
}
|
68
|
+
else if (!element.is_undefined())
|
69
|
+
{
|
70
|
+
if (target == "text")
|
71
|
+
element.text(get_value());
|
72
|
+
else
|
73
|
+
element.attr(target, get_value());
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
std::string Bindable::get_value() const
|
78
|
+
{
|
79
|
+
std::string value;
|
80
|
+
|
81
|
+
__asm__("try {");
|
82
|
+
value = getter();
|
83
|
+
__asm__("} catch (err) { console.warn('failed to update attribute', err); }");
|
84
|
+
return value;
|
85
|
+
}
|
86
|
+
|
87
|
+
void Bindable::throttle_schedule()
|
88
|
+
{
|
89
|
+
std::shared_ptr<bool> _enabled_ptr = enabled_ptr;
|
90
|
+
|
91
|
+
Comet::window.set_timeout([this, _enabled_ptr]()
|
92
|
+
{
|
93
|
+
if (*_enabled_ptr)
|
94
|
+
{
|
95
|
+
update();
|
96
|
+
throttle_schedule();
|
97
|
+
}
|
98
|
+
}, throttle_refresh);
|
99
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#ifndef COMET_BINDABLE_HPP
|
2
|
+
# define COMET_BINDABLE_HPP
|
3
|
+
|
4
|
+
# include "signal.hpp"
|
5
|
+
# include "element.hpp"
|
6
|
+
|
7
|
+
namespace Comet
|
8
|
+
{
|
9
|
+
struct IBindableView : public Comet::Element
|
10
|
+
{
|
11
|
+
IBindableView() : Comet::Element("div") {}
|
12
|
+
IBindableView(const client::String& tagName) : Comet::Element(tagName) {}
|
13
|
+
|
14
|
+
virtual void bind_attributes() = 0;
|
15
|
+
virtual void trigger_binding_updates() = 0;
|
16
|
+
private:
|
17
|
+
IBindableView(const IBindableView&) {}
|
18
|
+
};
|
19
|
+
|
20
|
+
struct BindableUpdater
|
21
|
+
{
|
22
|
+
std::function<void()> func;
|
23
|
+
|
24
|
+
void execute()
|
25
|
+
{
|
26
|
+
if (func)
|
27
|
+
func();
|
28
|
+
else
|
29
|
+
el.attr(target, getter());
|
30
|
+
}
|
31
|
+
|
32
|
+
Comet::Element el;
|
33
|
+
const std::string target;
|
34
|
+
std::function<std::string (void)> getter;
|
35
|
+
};
|
36
|
+
|
37
|
+
class Bindable : public Comet::Listener
|
38
|
+
{
|
39
|
+
public:
|
40
|
+
typedef std::function<std::string (void)> Getter;
|
41
|
+
|
42
|
+
enum BindMode
|
43
|
+
{
|
44
|
+
StaticBind,
|
45
|
+
SignalBind,
|
46
|
+
ThrottleBind
|
47
|
+
};
|
48
|
+
|
49
|
+
private:
|
50
|
+
BindMode bind_mode = StaticBind;
|
51
|
+
Comet::Element element;
|
52
|
+
std::string target;
|
53
|
+
Getter getter;
|
54
|
+
bool has_updater = false;
|
55
|
+
std::function<void()> updater;
|
56
|
+
|
57
|
+
std::string signal_name;
|
58
|
+
unsigned long throttle_refresh;
|
59
|
+
bool enabled = false;
|
60
|
+
std::shared_ptr<bool> enabled_ptr;
|
61
|
+
|
62
|
+
public:
|
63
|
+
Bindable() {}
|
64
|
+
Bindable(Comet::Element el, const std::string& t, Getter g) : element(el), target(t), getter(g) {}
|
65
|
+
Bindable(std::function<void ()> func) : has_updater(true), updater(func) {}
|
66
|
+
|
67
|
+
~Bindable() { disable(); }
|
68
|
+
|
69
|
+
inline Bindable& bind_to(Comet::Element el) { element = el; return *this; }
|
70
|
+
inline Bindable& on_attribute(const std::string& t, Getter g) { target = t; getter = g; return *this; }
|
71
|
+
Bindable& use_mode(BindMode, const std::string& parameter);
|
72
|
+
|
73
|
+
void enable(Comet::Signal<std::string>& signal);
|
74
|
+
void disable();
|
75
|
+
void update();
|
76
|
+
|
77
|
+
private:
|
78
|
+
std::string get_value() const;
|
79
|
+
void throttle_schedule();
|
80
|
+
};
|
81
|
+
|
82
|
+
class BoundAttributes : public std::vector<Bindable>
|
83
|
+
{
|
84
|
+
public:
|
85
|
+
void update()
|
86
|
+
{
|
87
|
+
for (Bindable& bindable : *this)
|
88
|
+
bindable.update();
|
89
|
+
}
|
90
|
+
|
91
|
+
void enable(Comet::Signal<std::string>& signaler)
|
92
|
+
{
|
93
|
+
disable();
|
94
|
+
for (Bindable& bindable : *this)
|
95
|
+
bindable.enable(signaler);
|
96
|
+
}
|
97
|
+
|
98
|
+
void disable()
|
99
|
+
{
|
100
|
+
for (Bindable& bindable : *this)
|
101
|
+
bindable.disable();
|
102
|
+
}
|
103
|
+
};
|
104
|
+
}
|
105
|
+
|
106
|
+
#endif
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#include "parse_cookie_values.hpp"
|
2
|
+
#include "url.hpp"
|
3
|
+
#include <regex>
|
4
|
+
#include <iostream>
|
5
|
+
|
6
|
+
using namespace std;
|
7
|
+
|
8
|
+
static bool trigger_add_cookie_value(const string& str, std::function<bool (const string&, const string&)> callback, size_t key_start, size_t key_end, size_t val_start, size_t val_end)
|
9
|
+
{
|
10
|
+
string key = str.substr(key_start, key_end - key_start);
|
11
|
+
string val = str.substr(val_start, val_end - val_start);
|
12
|
+
key = Comet::Url::decode(key);
|
13
|
+
val = Comet::Url::decode(val);
|
14
|
+
return callback(key, val);
|
15
|
+
}
|
16
|
+
|
17
|
+
namespace Comet
|
18
|
+
{
|
19
|
+
void parse_cookie_values(const string& str, std::function<bool (const std::string&, const std::string&)> callback)
|
20
|
+
{
|
21
|
+
char state = 0;
|
22
|
+
size_t key_start = 0;
|
23
|
+
size_t key_end = 0;
|
24
|
+
size_t val_start = 0;
|
25
|
+
|
26
|
+
for (size_t i = 0 ; i < str.size() ; ++i)
|
27
|
+
{
|
28
|
+
switch (state)
|
29
|
+
{
|
30
|
+
case 0: // spaces
|
31
|
+
if (str[i] == ' ') continue ;
|
32
|
+
key_start = i;
|
33
|
+
state++;
|
34
|
+
case 1: // key
|
35
|
+
if (str[i] == '=')
|
36
|
+
{
|
37
|
+
key_end = i;
|
38
|
+
val_start = i + 1;
|
39
|
+
state++;
|
40
|
+
}
|
41
|
+
break ;
|
42
|
+
case 2: // value
|
43
|
+
if (str[i] == ';')
|
44
|
+
{
|
45
|
+
state = 0;
|
46
|
+
if (!(trigger_add_cookie_value(str, callback,
|
47
|
+
key_start, key_end, val_start, i)))
|
48
|
+
return ;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
if (state == 2)
|
53
|
+
{
|
54
|
+
trigger_add_cookie_value(str, callback,
|
55
|
+
key_start, key_end, val_start, str.size());
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#include "comment_element.hpp"
|
2
|
+
#include "globals.hpp"
|
3
|
+
|
4
|
+
using namespace Comet;
|
5
|
+
|
6
|
+
client::HTMLElement* CommentElement::makeCommentElement(const client::String& str)
|
7
|
+
{
|
8
|
+
client::Comment* comment = Comet::document->createComment(str);
|
9
|
+
|
10
|
+
return reinterpret_cast<client::HTMLElement*>(comment);
|
11
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef COMET_COMMENT_ELEMENT_HPP
|
2
|
+
# define COMET_COMMENT_ELEMENT_HPP
|
3
|
+
|
4
|
+
# include "element.hpp"
|
5
|
+
|
6
|
+
namespace Comet
|
7
|
+
{
|
8
|
+
class CommentElement : public Comet::Element
|
9
|
+
{
|
10
|
+
static client::HTMLElement* makeCommentElement(const client::String&);
|
11
|
+
public:
|
12
|
+
CommentElement(const client::String& str) : Element(makeCommentElement(str)) {}
|
13
|
+
CommentElement() : Element(makeCommentElement("")) {}
|
14
|
+
};
|
15
|
+
}
|
16
|
+
|
17
|
+
#endif
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#include "cookies.hpp"
|
2
|
+
#include "exception.hpp"
|
3
|
+
#include "object.hpp"
|
4
|
+
#include "url.hpp"
|
5
|
+
#include "parse_cookie_values.hpp"
|
6
|
+
#include <cheerp/client.h>
|
7
|
+
#include <cheerp/clientlib.h>
|
8
|
+
|
9
|
+
using namespace Comet;
|
10
|
+
using namespace std;
|
11
|
+
|
12
|
+
Comet::Cookies cookies;
|
13
|
+
|
14
|
+
bool Cookies::has(const string& key)
|
15
|
+
{
|
16
|
+
ensure_cookie_map_is_updated();
|
17
|
+
return cookie_store.find(key) != cookie_store.end();
|
18
|
+
}
|
19
|
+
|
20
|
+
template<>
|
21
|
+
string Cookies::get<string>(const string& key)
|
22
|
+
{
|
23
|
+
ensure_cookie_map_is_updated();
|
24
|
+
if (!has(key))
|
25
|
+
Comet::raise(std::runtime_error("cookie `" + key + "` does not exist"));
|
26
|
+
return cookie_store.at(key);
|
27
|
+
}
|
28
|
+
|
29
|
+
template<>
|
30
|
+
void Cookies::set<string>(const string& key, const string& val)
|
31
|
+
{
|
32
|
+
ensure_cookie_map_is_updated();
|
33
|
+
if (has(key))
|
34
|
+
cookie_store.at(key) = val;
|
35
|
+
else
|
36
|
+
cookie_store.insert(pair<string, string>(key, val));
|
37
|
+
set_cookie_string(
|
38
|
+
Url::encode(key) + '=' + Url::encode(val)
|
39
|
+
);
|
40
|
+
}
|
41
|
+
|
42
|
+
template<>
|
43
|
+
void Cookies::set<string>(const string& key, const string& val, time_t expires_in)
|
44
|
+
{
|
45
|
+
string time_string;
|
46
|
+
|
47
|
+
ensure_cookie_map_is_updated();
|
48
|
+
if (has(key))
|
49
|
+
cookie_store.at(key) = val;
|
50
|
+
else
|
51
|
+
cookie_store.insert(pair<string, string>(key, val));
|
52
|
+
if (expires_in > 0)
|
53
|
+
{
|
54
|
+
ObjectImpl<client::Date> date;
|
55
|
+
double expires_time = date->getTime() + expires_in * 1000;
|
56
|
+
|
57
|
+
date->setTime(expires_time);
|
58
|
+
time_string = "; expires=" + (string)date.apply("toGMTString");
|
59
|
+
}
|
60
|
+
set_cookie_string(
|
61
|
+
Url::encode(key) + '=' + Url::encode(val) + time_string
|
62
|
+
);
|
63
|
+
}
|
64
|
+
|
65
|
+
void Cookies::remove(const string& key)
|
66
|
+
{
|
67
|
+
ensure_cookie_map_is_updated();
|
68
|
+
cookie_store.erase(key);
|
69
|
+
set_cookie_string(
|
70
|
+
Url::encode(key) + "=null; expires=Sat, 05 Nov 2016 00:00:00 GMT"
|
71
|
+
);
|
72
|
+
last_cookie_string = get_cookie_string();
|
73
|
+
}
|
74
|
+
|
75
|
+
void Cookies::update_cookie_map()
|
76
|
+
{
|
77
|
+
last_cookie_string = get_cookie_string();
|
78
|
+
cookie_store.clear();
|
79
|
+
Comet::parse_cookie_values(last_cookie_string,
|
80
|
+
[this](const string& key, const string& value) {
|
81
|
+
cookie_store.emplace(key, value);
|
82
|
+
return true;
|
83
|
+
});
|
84
|
+
}
|
85
|
+
|
86
|
+
string Cookies::get_cookie_string() const
|
87
|
+
{
|
88
|
+
return (string)(*client::document.get_cookie());
|
89
|
+
}
|
90
|
+
|
91
|
+
void Cookies::set_cookie_string(const string& str) const
|
92
|
+
{
|
93
|
+
client::document.set_cookie(str.c_str());
|
94
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#ifndef CRAILS_FRONT_COOKIES_HPP
|
2
|
+
# define CRAILS_FRONT_COOKIES_HPP
|
3
|
+
|
4
|
+
# include "from_string.hpp"
|
5
|
+
# include <string>
|
6
|
+
# include <map>
|
7
|
+
# include <ctime>
|
8
|
+
|
9
|
+
namespace Comet
|
10
|
+
{
|
11
|
+
class Cookies
|
12
|
+
{
|
13
|
+
typedef std::map<std::string, std::string> CookieMap;
|
14
|
+
public:
|
15
|
+
bool has(const std::string& key);
|
16
|
+
void remove(const std::string& key);
|
17
|
+
|
18
|
+
template<typename TYPE>
|
19
|
+
TYPE get(const std::string& key)
|
20
|
+
{
|
21
|
+
std::string val = get<std::string>(key);
|
22
|
+
|
23
|
+
return Comet::from_string<TYPE>(val);
|
24
|
+
}
|
25
|
+
|
26
|
+
template<typename TYPE>
|
27
|
+
void set(const std::string& key, const TYPE& val)
|
28
|
+
{
|
29
|
+
set(key, std::to_string(val), 0);
|
30
|
+
}
|
31
|
+
|
32
|
+
template<typename TYPE>
|
33
|
+
void set(const std::string& key, const TYPE& val, std::time_t expires_in)
|
34
|
+
{
|
35
|
+
set(key, std::to_string(val), expires_in);
|
36
|
+
}
|
37
|
+
|
38
|
+
private:
|
39
|
+
std::string get_cookie_string() const;
|
40
|
+
void set_cookie_string(const std::string&) const;
|
41
|
+
|
42
|
+
inline void ensure_cookie_map_is_updated()
|
43
|
+
{
|
44
|
+
if (last_cookie_string != get_cookie_string())
|
45
|
+
update_cookie_map();
|
46
|
+
}
|
47
|
+
|
48
|
+
void update_cookie_map();
|
49
|
+
|
50
|
+
CookieMap cookie_store;
|
51
|
+
std::string last_cookie_string;
|
52
|
+
};
|
53
|
+
|
54
|
+
template<>
|
55
|
+
std::string Cookies::get<std::string>(const std::string& key);
|
56
|
+
template<>
|
57
|
+
void Cookies::set(const std::string& key, const std::string& val, std::time_t);
|
58
|
+
}
|
59
|
+
|
60
|
+
#endif
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#ifndef COMET_HTML_TEMPLATE_HPP
|
2
|
+
# define COMET_HTML_TEMPLATE_HPP
|
3
|
+
|
4
|
+
# include "bindable.hpp"
|
5
|
+
# include "element.hpp"
|
6
|
+
|
7
|
+
namespace Comet
|
8
|
+
{
|
9
|
+
class BindableEngineCommon : public IBindableView
|
10
|
+
{
|
11
|
+
protected:
|
12
|
+
Comet::BoundAttributes bound_attributes;
|
13
|
+
virtual Comet::Signal<std::string>& get_signaler() = 0;
|
14
|
+
|
15
|
+
public:
|
16
|
+
BindableEngineCommon(const client::String& tagName) : IBindableView(tagName) {}
|
17
|
+
BindableEngineCommon() {}
|
18
|
+
|
19
|
+
virtual void bind_attributes()
|
20
|
+
{
|
21
|
+
bound_attributes.enable(get_signaler());
|
22
|
+
}
|
23
|
+
|
24
|
+
virtual void trigger_binding_updates()
|
25
|
+
{
|
26
|
+
bound_attributes.update();
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
class BindableEngine : public BindableEngineCommon
|
31
|
+
{
|
32
|
+
public:
|
33
|
+
BindableEngine(const client::String& tagName) : BindableEngineCommon(tagName) {}
|
34
|
+
BindableEngine() {}
|
35
|
+
|
36
|
+
Comet::Signal<std::string> signaler;
|
37
|
+
protected:
|
38
|
+
Comet::Signal<std::string>& get_signaler() { return signaler; }
|
39
|
+
|
40
|
+
};
|
41
|
+
|
42
|
+
class BindableEngineClient : public BindableEngineCommon
|
43
|
+
{
|
44
|
+
public:
|
45
|
+
BindableEngineClient(const client::String& tagName, Comet::Signal<std::string>& s) : BindableEngineCommon(tagName), signaler(s) {}
|
46
|
+
BindableEngineClient(Comet::Signal<std::string>& s) : signaler(s) {}
|
47
|
+
|
48
|
+
Comet::Signal<std::string>& signaler;
|
49
|
+
protected:
|
50
|
+
Comet::Signal<std::string>& get_signaler() { return signaler; }
|
51
|
+
};
|
52
|
+
|
53
|
+
class CustomElement : public BindableEngine
|
54
|
+
{
|
55
|
+
public:
|
56
|
+
CustomElement(const client::String& tagName) : BindableEngine(tagName) {}
|
57
|
+
CustomElement() {}
|
58
|
+
};
|
59
|
+
}
|
60
|
+
|
61
|
+
#endif
|
@@ -0,0 +1,198 @@
|
|
1
|
+
#include "datatree.hpp"
|
2
|
+
#include "globals.hpp"
|
3
|
+
#include "exception.hpp"
|
4
|
+
#include <iostream>
|
5
|
+
|
6
|
+
using namespace std;
|
7
|
+
|
8
|
+
DataTree& DataTree::from_json(stringstream& stream)
|
9
|
+
{
|
10
|
+
return from_json(stream.str());
|
11
|
+
}
|
12
|
+
|
13
|
+
DataTree& DataTree::from_json(const string& str)
|
14
|
+
{
|
15
|
+
Comet::String js_str(str);
|
16
|
+
|
17
|
+
tree = Comet::Object::from_json(*js_str);
|
18
|
+
return *this;
|
19
|
+
}
|
20
|
+
|
21
|
+
DataTree& DataTree::from_json_file(const string&)
|
22
|
+
{
|
23
|
+
Comet::raise(std::logic_error("DataTree::from_json_file not available from Comet.cpp"));
|
24
|
+
return *this;
|
25
|
+
}
|
26
|
+
|
27
|
+
string DataTree::to_json() const
|
28
|
+
{
|
29
|
+
return tree.to_json();
|
30
|
+
}
|
31
|
+
|
32
|
+
void Data::each(function<bool (Data)> functor)
|
33
|
+
{
|
34
|
+
for (auto _key : get_keys())
|
35
|
+
{
|
36
|
+
Data data(as_object(), _key);
|
37
|
+
|
38
|
+
if (!(functor(data)))
|
39
|
+
break ;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
void Data::each(function<bool (const Data)> functor) const
|
44
|
+
{
|
45
|
+
for (auto _key : get_keys())
|
46
|
+
{
|
47
|
+
const Data data(as_object(), _key);
|
48
|
+
|
49
|
+
if (!(functor(data)))
|
50
|
+
break ;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
Data Data::at(unsigned int i) const
|
55
|
+
{
|
56
|
+
std::stringstream stream;
|
57
|
+
std::string stringified;
|
58
|
+
|
59
|
+
stream << i;
|
60
|
+
stream >> stringified;
|
61
|
+
return Data(as_object(), stringified);
|
62
|
+
}
|
63
|
+
|
64
|
+
bool Data::exists() const
|
65
|
+
{
|
66
|
+
if (key.length())
|
67
|
+
{
|
68
|
+
Comet::String js_key(key);
|
69
|
+
|
70
|
+
return object->hasOwnProperty(*js_key);
|
71
|
+
}
|
72
|
+
return true;
|
73
|
+
}
|
74
|
+
|
75
|
+
bool Data::is_blank() const
|
76
|
+
{
|
77
|
+
return !exists() || as<string>() == "";
|
78
|
+
}
|
79
|
+
|
80
|
+
bool Data::is_null() const
|
81
|
+
{
|
82
|
+
return !exists() || as<string>() == "null";
|
83
|
+
}
|
84
|
+
|
85
|
+
vector<string> Data::get_keys() const
|
86
|
+
{
|
87
|
+
return Comet::window["Object"].apply("keys", as_object());
|
88
|
+
}
|
89
|
+
|
90
|
+
vector<string> Data::find_missing_keys(const vector<string>& keys) const
|
91
|
+
{
|
92
|
+
vector<string> missing_keys;
|
93
|
+
string path_prefix;
|
94
|
+
|
95
|
+
for (string key : keys)
|
96
|
+
{
|
97
|
+
Comet::String js_key(key);
|
98
|
+
|
99
|
+
if (!(as_object()->hasOwnProperty(*js_key)))
|
100
|
+
missing_keys.push_back(key);
|
101
|
+
}
|
102
|
+
return missing_keys;
|
103
|
+
}
|
104
|
+
|
105
|
+
bool Data::require(const vector<string>& keys) const
|
106
|
+
{
|
107
|
+
return find_missing_keys(keys).size() == 0;
|
108
|
+
}
|
109
|
+
|
110
|
+
bool Data::is_array() const
|
111
|
+
{
|
112
|
+
return *(as_object()["constructor"]) == *(Comet::window["Array"]);
|
113
|
+
}
|
114
|
+
|
115
|
+
void Data::merge(Data data)
|
116
|
+
{
|
117
|
+
if (data.exists())
|
118
|
+
{
|
119
|
+
if (key.length() > 0)
|
120
|
+
{
|
121
|
+
if (data.is_array())
|
122
|
+
object.set(key, data.as_object().apply("slice", 0));
|
123
|
+
else
|
124
|
+
object.set(key, Comet::Object::from_json(data.as_object().to_json()));
|
125
|
+
}
|
126
|
+
else
|
127
|
+
{
|
128
|
+
for (const auto& key : data.get_keys())
|
129
|
+
(*this)[key].merge(data[key]);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
void Data::merge(DataTree datatree)
|
135
|
+
{
|
136
|
+
merge(datatree.as_data());
|
137
|
+
}
|
138
|
+
|
139
|
+
void Data::output(ostream& out) const
|
140
|
+
{
|
141
|
+
out << to_json();
|
142
|
+
}
|
143
|
+
|
144
|
+
string Data::to_json() const
|
145
|
+
{
|
146
|
+
return as_object().to_json();
|
147
|
+
}
|
148
|
+
|
149
|
+
string Data::to_xml() const
|
150
|
+
{
|
151
|
+
Comet::raise(std::logic_error("Data::to_xml not available from Comet.cpp"));
|
152
|
+
return "";
|
153
|
+
}
|
154
|
+
|
155
|
+
size_t Data::count() const
|
156
|
+
{
|
157
|
+
if (is_array())
|
158
|
+
return as_object()["length"];
|
159
|
+
return get_keys().size();
|
160
|
+
}
|
161
|
+
|
162
|
+
void Data::destroy()
|
163
|
+
{
|
164
|
+
if (key.length() > 0)
|
165
|
+
object.unset(key);
|
166
|
+
else
|
167
|
+
{
|
168
|
+
for (auto subkey : get_keys())
|
169
|
+
object.unset(subkey);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
template<>
|
174
|
+
bool Data::as<bool>() const
|
175
|
+
{
|
176
|
+
std::string as_string = as_object().apply("toString");
|
177
|
+
std::stringstream stream;
|
178
|
+
int numerical_value;
|
179
|
+
|
180
|
+
if (as_string == "true" || as_string == "false")
|
181
|
+
return as_string == "true";
|
182
|
+
stream << as_string;
|
183
|
+
stream >> numerical_value;
|
184
|
+
return numerical_value != 0;
|
185
|
+
}
|
186
|
+
|
187
|
+
template<>
|
188
|
+
string Data::as<string>() const
|
189
|
+
{
|
190
|
+
return as_object().apply("toString");
|
191
|
+
}
|
192
|
+
|
193
|
+
|
194
|
+
template<>
|
195
|
+
wstring Data::as<wstring>() const
|
196
|
+
{
|
197
|
+
return as_object().apply("toString");
|
198
|
+
}
|