25 #include <initializer_list>
34 template <
typename HtmlElem>
40 std::vector<std::function<std::shared_ptr<Dom::Element>(
Dom::Element&,
Renderer const&)>> children);
45 HtmlElem htmlElement_;
46 std::vector<std::function<std::shared_ptr<Dom::Element>(
Dom::Element&,
Renderer const&)>> children_;
48 template <
typename HtmlElem>
56 HtmlElem htmlElement_;
77 template <
typename... T>
86 return {name_, bridge_, attributes_};
90 template <
typename... ObservedValues, std::invocable GeneratorT>
93 return [
self = this->
clone(),
94 observedValues = std::move(observedValues),
96 std::forward<GeneratorT>(elementRenderer)](
auto& parentElement,
Renderer const& gen) {
97 using ElementType = std::decay_t<decltype(parentElement)>;
100 auto childrenRefabricator = std::make_shared<std::function<void()>>();
102 auto&& createdSelf =
renderElement(gen, parentElement,
self);
106 *childrenRefabricator = [observedValues,
109 createdSelfWeak = std::weak_ptr<ElementType>(createdSelf),
110 childrenRefabricator]()
mutable {
111 fragmentContext.clear();
113 auto parent = createdSelfWeak.lock();
114 if (!parent || observedValues.isAnyExpired())
116 childrenRefabricator.reset();
123 if constexpr ((std::is_same_v<decltype(elementRenderer()), std::string>))
124 parent->setTextContent(elementRenderer());
131 *childrenRefabricator = [observedValues,
133 createdSelfWeak = std::weak_ptr<ElementType>(createdSelf),
134 childrenRefabricator]()
mutable {
135 auto parent = createdSelfWeak.lock();
136 if (!parent || observedValues.isAnyExpired())
138 childrenRefabricator.reset();
143 parent->clearChildren();
148 if constexpr ((std::is_same_v<decltype(elementRenderer()), std::string>))
149 parent->setTextContent(elementRenderer());
155 (*childrenRefabricator)();
160 template <
typename RangeType,
typename GeneratorT>
161 auto rangeRender(RangeType&& valueRange, GeneratorT&& elementRenderer) &&
163 return [
self = this->
clone(),
164 rangeRenderer = std::make_shared<
165 Detail::RangeRenderer<std::decay_t<RangeType>, GeneratorT, RangeType::isRandomAccess>>(
166 std::move(valueRange).underlying(), std::forward<GeneratorT>(elementRenderer))](
167 auto& parentElement, Renderer
const& gen)
mutable {
169 throw std::runtime_error(
"fragments are not supported for range generators");
171 auto&& materialized =
renderElement(gen, parentElement,
self);
172 (*rangeRenderer)(materialized);
179 template <
typename... ElementT>
182 std::forward<ElementT>(elements)...};
190 std::forward<ElementT>(elements)...}}};
217 template <
typename T>
218 requires std::same_as<std::decay_t<T>, std::string>
221 return [
self = this->
clone(), text = std::forward<T>(text)](
auto& parentElement,
Renderer const& gen) {
223 materialized->setTextContent(text);
229 return [
self = this->
clone(), view](
auto& parentElement,
Renderer const& gen) {
231 materialized->setTextContent(view);
237 return [
self = this->
clone(), text](
auto& parentElement,
Renderer const& gen) {
239 materialized->setTextContent(text);
243 template <
typename T>
247 return [
self = this->
clone(), fundamental](
auto& parentElement,
Renderer const& gen) {
249 materialized->setTextContent(std::to_string(fundamental));
255 template <
typename GeneratorT>
256 requires InvocableReturns<GeneratorT, std::string>
259 return [
self = this->
clone(),
260 textGenerator = std::forward<GeneratorT>(textGenerator)](
auto& parentElement,
Renderer const& gen) {
262 materialized->setTextContent(textGenerator());
266 template <std::invocable GeneratorT>
267 requires(!InvocableReturns<GeneratorT, std::string>)
268 auto operator()(GeneratorT&& elementRenderer) &&
270 return [
self = this->
clone(), elementRenderer = std::forward<GeneratorT>(elementRenderer)](
271 auto& parentElement,
Renderer const& gen) {
277 template <
typename T, std::invocable<T&, Renderer const&> GeneratorT>
278 requires InvocableReturns<GeneratorT, std::string>
281 return [
self = this->
clone(), elementRenderer = std::forward<GeneratorT>(elementRenderer)](
282 auto& parentElement,
Renderer const& gen) {
290 template <
typename... ObservedValues, std::invocable GeneratorT>
293 return std::move(*this).operator()(std::move(combinator).split(), std::move(combinator).generator());
295 template <
typename... ObservedValues, std::invocable GeneratorT>
298 return std::move(*this).reactiveRender(
299 std::move(observedValues), std::forward<GeneratorT>(elementRenderer));
303 template <
typename ObservedValue,
typename GeneratorT>
306 return std::move(*this).rangeRender(std::move(observedRange), std::forward<GeneratorT>(elementRenderer));
308 template <
typename ObservedValue,
typename GeneratorT>
311 return std::move(*this).rangeRender(std::move(mapPair.first), std::move(mapPair.second));
313 template <
typename IteratorT,
typename GeneratorT,
typename... ObservedT>
316 return [
self = this->
clone(),
319 std::move(unoptimizedRange), std::forward<GeneratorT>(elementRenderer))](
320 auto& parentElement,
Renderer const& gen) {
322 throw std::runtime_error(
"fragments are not supported for range generators");
324 auto&& materialized =
renderElement(gen, parentElement,
self);
325 (*rangeRenderer)(materialized);
333 return std::move(*this).operator()(observe(observedString), [&observedString]() -> std::string {
334 return observedString.value();
337 template <
typename T>
341 return std::move(*this).operator()(observe(observedNumber), [&observedNumber]() -> std::string {
342 return std::to_string(observedNumber.value());
351 inline char const*
name()
const
364 std::vector<Attribute> attributes_;
Definition: fragment_context.hpp:7
Definition: range_renderer.hpp:19
Definition: element.hpp:42
Definition: html_element.hpp:60
requires InvocableReturns< GeneratorT, std::string > auto operator()(GeneratorT &&textGenerator) &&
Definition: html_element.hpp:257
requires InvocableReturns< GeneratorT, std::string > auto operator()(GeneratorT &&elementRenderer) &&
Definition: html_element.hpp:279
std::vector< Attribute > const & attributes() const
Definition: html_element.hpp:346
requires(!InvocableReturns< GeneratorT, std::string >) auto operator()(GeneratorT &&elementRenderer) &&
Definition: html_element.hpp:267
HtmlElement clone() const
Definition: html_element.hpp:84
HtmlElement(char const *name, HtmlElementBridge const *bridge, std::vector< Attribute > const &attributes)
Definition: html_element.hpp:67
auto operator()(std::string_view view) &&
Definition: html_element.hpp:227
auto operator()(std::pair< ObservedRange< ObservedValue >, GeneratorT > &&mapPair) &&
Definition: html_element.hpp:309
requires Fundamental< T > auto operator()(T fundamental) &&
Definition: html_element.hpp:245
auto operator()() &&
Definition: html_element.hpp:205
HtmlElement(HtmlElement &&)=default
requires Fundamental< T > auto operator()(Observed< T > const &observedNumber) &&
Definition: html_element.hpp:339
friend class DomElement
Definition: html_element.hpp:62
requires std::same_as< std::decay_t< T >, std::string > auto operator()(T &&text) &&
Definition: html_element.hpp:219
char const * name() const
Definition: html_element.hpp:351
auto operator()(ObservedValueCombinatorWithGenerator< GeneratorT, ObservedValues... > combinator) &&
Definition: html_element.hpp:291
HtmlElement(char const *name, HtmlElementBridge const *bridge, T &&... attributes)
Definition: html_element.hpp:78
auto operator()(Observed< std::string > const &observedString) &&
Definition: html_element.hpp:331
HtmlElement(char const *name, HtmlElementBridge const *bridge, std::vector< Attribute > &&attributes)
Definition: html_element.hpp:72
HtmlElementBridge const * bridge() const
Definition: html_element.hpp:356
virtual ~HtmlElement()=default
auto operator()(ElementT &&... elements) &&
Definition: html_element.hpp:184
auto operator()(char const *text) &&
Definition: html_element.hpp:235
requires requires(ElementT &&... elements)
Definition: html_element.hpp:180
HtmlElement(HtmlElement const &)=default
auto operator()(ObservedValueCombinator< ObservedValues... > observedValues, GeneratorT &&elementRenderer) &&
Definition: html_element.hpp:296
auto operator()(UnoptimizedRange< IteratorT, ObservedT... > &&unoptimizedRange, GeneratorT &&elementRenderer) &&
Definition: html_element.hpp:314
auto operator()(ObservedRange< ObservedValue > observedRange, GeneratorT &&elementRenderer) &&
Definition: html_element.hpp:304
Definition: observed_value_combinator.hpp:109
Definition: observed_value_combinator.hpp:160
void makeChildrenUpdateEvent(auto &observedValues, auto &childrenRefabricator, auto &createdSelfWeak)
Definition: make_children_update_event.hpp:7
Definition: file_dialog.hpp:6
auto renderElement(Renderer const &gen, auto &element, auto const &htmlElement)
Definition: materialize.hpp:56
Definition: html_element.hpp:36
std::shared_ptr< Dom::Element > operator()(Dom::Element &parentElement, Renderer const &gen) const
ChildrenRenderer(HtmlElem htmlElement, std::vector< std::function< std::shared_ptr< Dom::Element >(Dom::Element &, Renderer const &)>> children)
Definition: html_element_bridge.hpp:14
Definition: materialize.hpp:52
RendererType type
Definition: materialize.hpp:53
Definition: html_element.hpp:50
TrivialRenderer(HtmlElem htmlElement)
std::shared_ptr< Dom::Element > operator()(Dom::Element &parentElement, Renderer const &gen) const