Skip to content

Commit c4caad2

Browse files
authored
Merge pull request #72 from NuiCpp/devel
Inline Text Feature
2 parents 0396991 + bf22aaf commit c4caad2

File tree

14 files changed

+448
-89
lines changed

14 files changed

+448
-89
lines changed

nui/include/nui/frontend/attributes/impl/attribute.hpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,48 @@
66
#include <functional>
77
#include <memory>
88
#include <string>
9+
#include <string_view>
10+
#include <variant>
911

1012
namespace Nui
1113
{
1214
class Attribute
1315
{
1416
public:
15-
Attribute()
16-
: setter_{}
17-
, createEvent_{}
18-
{}
17+
struct RegularAttribute
18+
{
19+
std::function<void(Dom::ChildlessElement&)> setter;
20+
};
21+
struct StringDataAttribute
22+
{
23+
std::string data;
24+
};
25+
1926
Attribute(
2027
std::function<void(Dom::ChildlessElement&)> setter,
2128
std::function<EventContext::EventIdType(std::weak_ptr<Dom::ChildlessElement>&& element)> createEvent = {},
2229
std::function<void(EventContext::EventIdType const&)> clearEvent = {})
23-
: setter_{std::move(setter)}
30+
: attributeImpl_{RegularAttribute{.setter = std::move(setter)}}
31+
, createEvent_{std::move(createEvent)}
32+
, clearEvent_{std::move(clearEvent)}
33+
{}
34+
Attribute(
35+
std::string data,
36+
std::function<EventContext::EventIdType(std::weak_ptr<Dom::ChildlessElement>&& element)> createEvent,
37+
std::function<void(EventContext::EventIdType const&)> clearEvent)
38+
: attributeImpl_{StringDataAttribute{
39+
.data = std::move(data),
40+
}}
41+
, createEvent_{std::move(createEvent)}
42+
, clearEvent_{std::move(clearEvent)}
43+
{}
44+
Attribute(
45+
std::string_view data,
46+
std::function<EventContext::EventIdType(std::weak_ptr<Dom::ChildlessElement>&& element)> createEvent,
47+
std::function<void(EventContext::EventIdType const&)> clearEvent)
48+
: attributeImpl_{StringDataAttribute{
49+
.data = std::string{data},
50+
}}
2451
, createEvent_{std::move(createEvent)}
2552
, clearEvent_{std::move(clearEvent)}
2653
{}
@@ -34,8 +61,13 @@ namespace Nui
3461
EventContext::EventIdType createEvent(std::weak_ptr<Dom::ChildlessElement>&& element) const;
3562
std::function<void(EventContext::EventIdType const&)> getEventClear() const;
3663

64+
std::string const& stringData() const;
65+
66+
bool isRegular() const;
67+
bool isStringData() const;
68+
3769
private:
38-
std::function<void(Dom::ChildlessElement&)> setter_;
70+
std::variant<RegularAttribute, StringDataAttribute> attributeImpl_;
3971
std::function<EventContext::EventIdType(std::weak_ptr<Dom::ChildlessElement>&& element)> createEvent_;
4072
std::function<void(EventContext::EventIdType const&)> clearEvent_;
4173
};

nui/include/nui/frontend/attributes/impl/attribute_factory.hpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ namespace Nui::Attributes
5656
requires(!IsObserved<std::decay_t<U>> && !std::invocable<U, Nui::val> && !std::invocable<U>)
5757
Attribute operator=(U val) const
5858
{
59-
return Attribute{[name = name(), val = std::move(val)](Dom::ChildlessElement& element) {
60-
element.setAttribute(name, val);
61-
}};
59+
return Attribute{
60+
[name = name(), val = std::move(val)](Dom::ChildlessElement& element) {
61+
element.setAttribute(name, val);
62+
},
63+
};
6264
}
6365
template <typename U>
6466
requires(IsObserved<std::decay_t<U>>)
@@ -73,7 +75,8 @@ namespace Nui::Attributes
7375
},
7476
[&val](EventContext::EventIdType const& id) {
7577
val.unattachEvent(id);
76-
}};
78+
},
79+
};
7780
}
7881
template <typename RendererType, typename... ObservedValues>
7982
Attribute
@@ -88,27 +91,32 @@ namespace Nui::Attributes
8891
},
8992
[combinator](EventContext::EventIdType const& id) {
9093
combinator.unattachEvent(id);
91-
}};
94+
},
95+
};
9296
}
9397

9498
Attribute operator=(std::function<void(Nui::val)> func) const
9599
{
96-
return Attribute{[name = name(), func = std::move(func)](Dom::ChildlessElement& element) {
97-
element.setAttribute(name, [func](Nui::val val) {
98-
func(val);
99-
globalEventContext.executeActiveEventsImmediately();
100-
});
101-
}};
100+
return Attribute{
101+
[name = name(), func = std::move(func)](Dom::ChildlessElement& element) {
102+
element.setAttribute(name, [func](Nui::val val) {
103+
func(val);
104+
globalEventContext.executeActiveEventsImmediately();
105+
});
106+
},
107+
};
102108
}
103109

104110
Attribute operator=(std::function<void()> func) const
105111
{
106-
return Attribute{[name = name(), func = std::move(func)](Dom::ChildlessElement& element) {
107-
element.setAttribute(name, [func](Nui::val) {
108-
func();
109-
globalEventContext.executeActiveEventsImmediately();
110-
});
111-
}};
112+
return Attribute{
113+
[name = name(), func = std::move(func)](Dom::ChildlessElement& element) {
114+
element.setAttribute(name, [func](Nui::val) {
115+
func();
116+
globalEventContext.executeActiveEventsImmediately();
117+
});
118+
},
119+
};
112120
}
113121

114122
private:

nui/include/nui/frontend/dom/childless_element.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Nui::Dom
1414
{
1515
public:
1616
ChildlessElement(HtmlElement const& elem)
17-
: BasicElement{ChildlessElement::createElement(elem).val()}
17+
: BasicElement{ChildlessElement::createElement(elem)}
1818
{}
1919
ChildlessElement(Nui::val val)
2020
: BasicElement{std::move(val)}
@@ -71,9 +71,13 @@ namespace Nui::Dom
7171
if (value)
7272
setAttribute(key, *value);
7373
}
74+
void setNodeValue(std::string_view value)
75+
{
76+
element_.set("nodeValue", Nui::val{std::string{value}});
77+
}
7478

7579
protected:
76-
static ChildlessElement createElement(HtmlElement const& element)
80+
static Nui::val createElement(HtmlElement const& element)
7781
{
7882
return element.bridge()->createElement(element);
7983
}

nui/include/nui/frontend/dom/element.hpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,30 @@ namespace Nui::Dom
164164
eventClearers.reserve(element.attributes().size());
165165
for (auto const& attribute : element.attributes())
166166
{
167-
attribute.setOn(*this);
168-
eventClearers.push_back(
169-
[clear = attribute.getEventClear(), id = attribute.createEvent(weak_from_base<Element>())]() {
170-
if (clear)
167+
if (attribute.isRegular())
168+
attribute.setOn(*this);
169+
170+
auto clear = attribute.getEventClear();
171+
if (clear)
172+
{
173+
eventClearers.push_back(
174+
[clear = std::move(clear), id = attribute.createEvent(weak_from_base<Element>())]() {
171175
clear(id);
172-
});
176+
});
177+
}
178+
}
179+
if (!eventClearers.empty())
180+
{
181+
eventClearers.shrink_to_fit();
182+
unsetup_ = [eventClearers = std::move(eventClearers)]() {
183+
for (auto const& clear : eventClearers)
184+
clear();
185+
};
186+
}
187+
else
188+
{
189+
unsetup_ = []() {};
173190
}
174-
unsetup_ = [eventClearers = std::move(eventClearers)]() {
175-
for (auto const& clear : eventClearers)
176-
clear();
177-
};
178191
}
179192

180193
auto insert(std::size_t where, HtmlElement const& element)
@@ -222,7 +235,7 @@ namespace Nui::Dom
222235
unsetup_();
223236
unsetup_ = {};
224237

225-
auto replacement = createElement(element).val();
238+
auto replacement = createElement(element);
226239
element_.call<Nui::val>("replaceWith", replacement);
227240
element_ = std::move(replacement);
228241
setup(element);

nui/include/nui/frontend/elements.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include <nui/frontend/elements/tbody.hpp>
8989
#include <nui/frontend/elements/td.hpp>
9090
#include <nui/frontend/elements/template.hpp>
91+
#include <nui/frontend/elements/text.hpp>
9192
#include <nui/frontend/elements/textarea.hpp>
9293
#include <nui/frontend/elements/tfoot.hpp>
9394
#include <nui/frontend/elements/th.hpp>

nui/include/nui/frontend/elements/impl/html_element.hpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,41 +131,32 @@ namespace Nui
131131
HtmlElem htmlElement_;
132132
};
133133
//----------------------------------------------------------------------------------------------
134-
135-
#ifdef __cpp_lib_constexpr_vector
136-
# define HTML_ELEMENT_CONSTEXPR constexpr
137-
#else
138-
# define HTML_ELEMENT_CONSTEXPR
139-
#endif
140-
141134
class HtmlElement
142135
{
143136
public:
144137
friend class DomElement;
145138

146-
HTML_ELEMENT_CONSTEXPR HtmlElement(HtmlElement const&) = default;
147-
HTML_ELEMENT_CONSTEXPR HtmlElement(HtmlElement&&) = default;
139+
HtmlElement(HtmlElement const&) = default;
140+
HtmlElement(HtmlElement&&) = default;
148141
virtual ~HtmlElement() = default;
149-
HTML_ELEMENT_CONSTEXPR
150142
HtmlElement(char const* name, HtmlElementBridge const* bridge, std::vector<Attribute> const& attributes)
151143
: name_{name}
152144
, bridge_{bridge}
153145
, attributes_{attributes}
154146
{}
155-
HTML_ELEMENT_CONSTEXPR
156147
HtmlElement(char const* name, HtmlElementBridge const* bridge, std::vector<Attribute>&& attributes)
157148
: name_{name}
158149
, bridge_{bridge}
159150
, attributes_{std::move(attributes)}
160151
{}
161152
template <typename... T>
162-
HTML_ELEMENT_CONSTEXPR HtmlElement(char const* name, HtmlElementBridge const* bridge, T&&... attributes)
153+
HtmlElement(char const* name, HtmlElementBridge const* bridge, T&&... attributes)
163154
: name_{name}
164155
, bridge_{bridge}
165156
, attributes_{std::forward<T>(attributes)...}
166157
{}
167158

168-
HTML_ELEMENT_CONSTEXPR HtmlElement clone() const
159+
HtmlElement clone() const
169160
{
170161
return {name_, bridge_, attributes_};
171162
}
@@ -345,9 +336,9 @@ namespace Nui
345336
// Children functions:
346337
template <typename... ElementT>
347338
requires requires(ElementT&&... elements) {
348-
std::vector<std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer const&)>>{
349-
std::forward<ElementT>(elements)...};
350-
}
339+
std::vector<std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer const&)>>{
340+
std::forward<ElementT>(elements)...};
341+
}
351342
auto operator()(ElementT&&... elements) &&
352343
{
353344
return std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer const&)>{
@@ -356,7 +347,7 @@ namespace Nui
356347
std::vector<std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer const&)>>{
357348
std::forward<ElementT>(elements)...}}};
358349

359-
// Unknown Linkage BUG in clang 16 :(
350+
// Unknown Linkage BUG in wasm-ld :(
360351
// return
361352
// [self = this->clone(),
362353
// children = std::vector<std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer
@@ -374,7 +365,7 @@ namespace Nui
374365
return std::function<std::shared_ptr<Dom::Element>(Dom::Element&, Renderer const&)>{
375366
TrivialRenderer<HtmlElement>{this->clone()}};
376367

377-
// Unknown Linkage BUG in clang 16 :(
368+
// Unknown Linkage BUG in wasm-ld :(
378369
// return [self = this->clone()](auto& parentElement, Renderer const& gen) {
379370
// return renderElement(gen, parentElement, self);
380371
// };

nui/include/nui/frontend/elements/impl/html_element.tpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ namespace Nui
4141
{ \
4242
struct NAME : HtmlElement \
4343
{ \
44-
HTML_ELEMENT_CONSTEXPR NAME(NAME const&) = default; \
45-
HTML_ELEMENT_CONSTEXPR NAME(NAME&&) = default; \
46-
HTML_ELEMENT_CONSTEXPR NAME(std::vector<Attribute> const& attributes) \
44+
NAME(NAME const&) = default; \
45+
NAME(NAME&&) = default; \
46+
NAME(std::vector<Attribute> const& attributes) \
4747
: HtmlElement{HTML_ACTUAL, &RegularHtmlElementBridge, attributes} \
4848
{} \
49-
HTML_ELEMENT_CONSTEXPR NAME(std::vector<Attribute>&& attributes) \
49+
NAME(std::vector<Attribute>&& attributes) \
5050
: HtmlElement{HTML_ACTUAL, &RegularHtmlElementBridge, std::move(attributes)} \
5151
{} \
5252
template <typename... T> \
53-
HTML_ELEMENT_CONSTEXPR NAME(T&&... attributes) \
53+
NAME(T&&... attributes) \
5454
: HtmlElement{HTML_ACTUAL, &RegularHtmlElementBridge, std::forward<T>(attributes)...} \
5555
{} \
5656
}; \

nui/include/nui/frontend/elements/impl/html_element_bridge.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <nui/frontend/val.hpp>
4+
35
namespace Nui
46
{
57
namespace Dom
@@ -10,6 +12,6 @@ namespace Nui
1012

1113
struct HtmlElementBridge
1214
{
13-
Dom::ChildlessElement (*createElement)(HtmlElement const& element);
15+
Nui::val (*createElement)(HtmlElement const& element);
1416
};
1517
}

nui/include/nui/frontend/elements/impl/html_element_bridges.hpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,28 @@
66
namespace Nui
77
{
88
constexpr auto RegularHtmlElementBridge = HtmlElementBridge{
9-
.createElement = +[](HtmlElement const& element) -> Dom::ChildlessElement {
10-
return {Nui::val::global("document").call<Nui::val>("createElement", Nui::val{element.name()})};
11-
},
9+
.createElement =
10+
+[](HtmlElement const& element) {
11+
return Nui::val::global("document").call<Nui::val>("createElement", Nui::val{element.name()});
12+
},
1213
};
1314

1415
constexpr auto SvgElementBridge = HtmlElementBridge{
15-
.createElement = +[](HtmlElement const& element) -> Dom::ChildlessElement {
16-
return {Nui::val::global("document")
17-
.call<Nui::val>(
18-
"createElementNS",
19-
Nui::val{std::string{"http://www.w3.org/2000/svg"}},
20-
Nui::val{element.name()})};
21-
},
16+
.createElement =
17+
+[](HtmlElement const& element) {
18+
return Nui::val::global("document")
19+
.call<Nui::val>(
20+
"createElementNS",
21+
Nui::val{std::string{"http://www.w3.org/2000/svg"}},
22+
Nui::val{element.name()});
23+
},
24+
};
25+
26+
constexpr auto TextElementBridge = HtmlElementBridge{
27+
.createElement =
28+
+[](HtmlElement const& element) {
29+
return Nui::val::global("document")
30+
.call<Nui::val>("createTextNode", Nui::val{element.attributes()[0].stringData()});
31+
},
2232
};
2333
}

nui/include/nui/frontend/elements/svg/impl/svg_element.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
{ \
88
struct NAME : HtmlElement \
99
{ \
10-
HTML_ELEMENT_CONSTEXPR NAME(NAME const&) = default; \
11-
HTML_ELEMENT_CONSTEXPR NAME(NAME&&) = default; \
12-
HTML_ELEMENT_CONSTEXPR NAME(std::vector<Attribute> const& attributes) \
10+
NAME(NAME const&) = default; \
11+
NAME(NAME&&) = default; \
12+
NAME(std::vector<Attribute> const& attributes) \
1313
: HtmlElement{HTML_ACTUAL, &SvgElementBridge, attributes} \
1414
{} \
15-
HTML_ELEMENT_CONSTEXPR NAME(std::vector<Attribute>&& attributes) \
15+
NAME(std::vector<Attribute>&& attributes) \
1616
: HtmlElement{HTML_ACTUAL, &SvgElementBridge, std::move(attributes)} \
1717
{} \
1818
template <typename... T> \
19-
HTML_ELEMENT_CONSTEXPR NAME(T&&... attributes) \
19+
NAME(T&&... attributes) \
2020
: HtmlElement{HTML_ACTUAL, &SvgElementBridge, std::forward<T>(attributes)...} \
2121
{} \
2222
}; \

0 commit comments

Comments
 (0)