Webdar 1.0.0
Web user interface to libdar
body_builder.hpp
1/*********************************************************************/
2// webdar - a web server and interface program to libdar
3// Copyright (C) 2013-2025 Denis Corbin
4//
5// This file is part of Webdar
6//
7// Webdar is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// Webdar is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Webdar. If not, see <http://www.gnu.org/licenses/>
19//
20//----
21// to contact the author: dar.linux@free.fr
22/*********************************************************************/
23
24#ifndef BODY_BUILDER_HPP
25#define BODY_BUILDER_HPP
26
27 // C system header files
28#include "my_config.h"
29extern "C"
30{
31
32}
33
34 // C++ system header files
35#include <string>
36#include <map>
37#include <vector>
38
39 // webdar headers
40#include "request.hpp"
41#include "chemin.hpp"
42#include "css_library.hpp"
43#include "css_class_group.hpp"
44
45
47
97
99{
100public:
102 body_builder() { clear(); };
103
105
113 body_builder(const body_builder & ref);
114
116
125 body_builder(body_builder && ref) noexcept = delete;
126
128
131
133
135 body_builder & operator = (body_builder && ref) noexcept = delete;
136
138 virtual ~body_builder();
139
140
141
142
146 void set_prefix(const chemin & prefix);
147
148
159 void adopt(body_builder* obj);
160
162 bool is_adopted() const { return parent != nullptr; };
163
169 void foresake(body_builder* obj);
170
172
177 void set_visible(bool mode);
178
180
184 bool get_visible() const { return visible; };
185
187 bool get_visible_recursively() const;
188
190 void add_css_class(const std::string & name);
191
193 void add_css_class(const css_class_group & cg);
194
196 bool has_css_class(const std::string & name) const;
197
199 void remove_css_class(const std::string & name);
200
202 void remove_css_class(const css_class_group & cg);
203
205 void clear_css_classes() { css_class_names.clear(); css_classes_have_changed(); };
206
208 const std::set<std::string> & get_css_classes_as_a_set() const { return css_class_names; };
209
212
213
215
220 std::string get_css_classes(const std::string & extra = "") const;
221
225 void define_css_class_in_library(const css_class & csscl);
226 void define_css_class_in_library(const std::string & name, const css & cssdef);
227
229 bool is_css_class_defined_in_library(const std::string & name) const;
230
244 std::string get_body_part(const chemin & path,
245 const request & req);
246
248
254 void ignore_body_changed_from_my_children(bool mode) { ignore_children_body_changed = mode; if(mode) body_changed = false; };
255
257 bool get_ignore_body_changed_from_my_children() const { return ignore_children_body_changed; };
258
260
265 void set_no_CR(bool no_cr = true);
266
268
275 void assign_anchor(bool mode);
276
278
280 std::string get_assigned_anchor() const { return anchor; };
281
283 virtual void bind_to_anchor(const std::string & val) {};
284
285protected:
286
288
297 virtual std::string inherited_get_body_part(const chemin & path,
298 const request & req) = 0;
299
301
311
312
314 virtual void my_visibility_has_changed() {};
315
317
319 bool has_my_body_part_changed() const { return body_changed; };
320
322 chemin get_path() const;
323
327 std::string get_recorded_name() const;
328
329
331
336 void store_css_library() { library_asked = true; };
337
339 bool has_local_css_library() const { return library_asked || bool(library); };
340
342
345 std::unique_ptr<css_library> & lookup_css_library() const;
346
358 std::string get_body_part_from_target_child(const chemin & path,
359 const request & req);
360
367 std::string get_body_part_from_all_children(const chemin & path,
368 const request & req);
369
371
373 virtual void path_has_changed() {};
374
376 virtual void has_adopted(body_builder *obj) {};
377
379 virtual void will_foresake(body_builder *obj) {};
380
382 virtual void has_been_adopted_by(body_builder *obj) {};
383
385 virtual void will_be_foresaken_by(body_builder *obj) {};
386
388 virtual void css_classes_have_changed() {};
389
392 virtual void new_css_library_available() {};
393
395 unsigned int size() const { return order.size(); };
396
398 body_builder *operator[] (unsigned int i) { return order[i]; };
399
401 body_builder* get_parent() const { return parent; };
402
404
406 template <class T> void closest_ancestor_of_type(T* & ancestor)
407 {
408 body_builder* ptr = parent;
409
410 do
411 {
412 if(ptr != nullptr)
413 {
414 ancestor = dynamic_cast<T*>(ptr);
415 ptr = ptr->parent;
416 }
417 else
418 ancestor = nullptr;
419 }
420 while(ptr != nullptr && ancestor == nullptr);
421 }
422
423
425 void orphan_all_children();
426
428 bool get_no_CR() const { return no_CR; };
429
430private:
431 bool visible;
432 chemin x_prefix;
433 bool no_CR;
434 body_builder* parent;
435 std::vector<body_builder*> order;
436 std::map<std::string, body_builder*> children;
437 std::map<body_builder*, std::string> revert_child;
438 chemin last_body_path;
439 uri last_body_req_uri;
440 std::string last_body_req_body;
441 std::string last_body_part;
442 bool body_changed;
443 bool ignore_children_body_changed;
444 bool library_asked;
447 std::unique_ptr<css_library> library;
448 std::set<std::string> css_class_names;
449 std::string anchor;
450
452 void unrecord_from_parent();
453
455 void recursive_path_has_changed();
456
458 void recursive_new_css_library_available();
459
461 void clear();
462
464 void create_css_lib_if_needed();
465
467 void flush_all_cached_body_part();
468
470
479 std::string get_body_part_or_cache(const chemin & path,
480 const request & req);
481
482
483 static libthreadar::mutex assigned_anchors_ctrl;
484 static std::set<unsigned int> assigned_anchors;
485
486 static std::string get_available_anchor();
487 static void release_anchor(std::string & val);
488};
489
490#endif
class body_builder is the root class of object generating HTML body
Definition: body_builder.hpp:99
void closest_ancestor_of_type(T *&ancestor)
access to the closest ancestor (parent) matching (dynamic_cast) the provided type
Definition: body_builder.hpp:406
void clear_css_classes()
clear the whole list of css_class names
Definition: body_builder.hpp:205
body_builder * get_parent() const
return the parent object or nullptr if no object has adopted this object
Definition: body_builder.hpp:401
void adopt(body_builder *obj)
Definition: body_builder.cpp:117
virtual std::string inherited_get_body_part(const chemin &path, const request &req)=0
implementation of get_body_part() method for inherited classes
std::string get_body_part_from_target_child(const chemin &path, const request &req)
Definition: body_builder.cpp:479
virtual void my_visibility_has_changed()
available for inherited class to be informed when their visibility changes
Definition: body_builder.hpp:314
bool is_css_class_defined_in_library(const std::string &name) const
check whether a css_class of given name already exists in a reachable css_library
Definition: body_builder.cpp:344
std::string get_css_classes(const std::string &extra="") const
return the class_name as inlined css, suitable to be added in a html marker
Definition: body_builder.cpp:308
void define_css_class_in_library(const css_class &csscl)
Definition: body_builder.cpp:328
virtual void bind_to_anchor(const std::string &val)
ask inherited components to use this anchor in case they redirect to an new URL or generate new URLs ...
Definition: body_builder.hpp:283
body_builder()
constructor
Definition: body_builder.hpp:102
std::string get_assigned_anchor() const
return the anchor value that has been assiged to this object (without the leading #)
Definition: body_builder.hpp:280
void ignore_body_changed_from_my_children(bool mode)
ignore my_body_part_has_changed() invoked from adopted children and myself
Definition: body_builder.hpp:254
void my_body_part_has_changed()
let a class record a change in what inherited_get_body_part() would return if it was called again wit...
Definition: body_builder.cpp:420
body_builder(body_builder &&ref) noexcept=delete
move constructor
bool get_visible() const
returns the current visible status of the object
Definition: body_builder.hpp:184
css_class_group get_css_class_group() const
provide the list of css_class names as a css_class_group
Definition: body_builder.cpp:294
std::string get_body_part_from_all_children(const chemin &path, const request &req)
Definition: body_builder.cpp:507
bool get_ignore_body_changed_from_my_children() const
get the current status of ignore_body_changed_from_my_children()
Definition: body_builder.hpp:257
std::string get_recorded_name() const
Definition: body_builder.cpp:457
body_builder & operator=(const body_builder &ref)
assignment operator drops all existing children
Definition: body_builder.cpp:78
bool get_no_CR() const
true if it has been requested no to add Carriage Return after the HTML object
Definition: body_builder.hpp:428
virtual void will_be_foresaken_by(body_builder *obj)
Be informed that we are about to be foresaken by obj, our soon former parent.
Definition: body_builder.hpp:385
bool has_local_css_library() const
return true if this object has a css_library locally stored (not from a adopter object)
Definition: body_builder.hpp:339
const std::set< std::string > & get_css_classes_as_a_set() const
provide the list of css_class names that this object has been set with
Definition: body_builder.hpp:208
std::unique_ptr< css_library > & lookup_css_library() const
lookup toward registered parent body_builder object for the closest stored css_library
Definition: body_builder.cpp:470
virtual void has_adopted(body_builder *obj)
Be informed that a new child has been adopted.
Definition: body_builder.hpp:376
void set_visible(bool mode)
ask for the object to become visible in HTML page or temporarily hidden
Definition: body_builder.cpp:211
virtual void has_been_adopted_by(body_builder *obj)
Be informed that we have been adopted by obj, our new parent.
Definition: body_builder.hpp:382
void remove_css_class(const std::string &name)
remove the provided css_class name from the list of css_class names this object has been assigned to
Definition: body_builder.cpp:273
body_builder * operator[](unsigned int i)
access to adopted childs
Definition: body_builder.hpp:398
void assign_anchor(bool mode)
assign an anchor to this object (the object's inherited_get_body_part() will be wrapped into an HTML ...
Definition: body_builder.cpp:402
virtual ~body_builder()
the (virtual) destructor
Definition: body_builder.cpp:69
virtual void css_classes_have_changed()
Be informed about css class modification.
Definition: body_builder.hpp:388
void orphan_all_children()
orphan all adopted children
Definition: body_builder.cpp:552
unsigned int size() const
access to adopted childs
Definition: body_builder.hpp:395
bool has_css_class(const std::string &name) const
check the presence of the given class name
Definition: body_builder.cpp:268
void store_css_library()
this creates a css_library accessible from adopted objects to hold html class definitions
Definition: body_builder.hpp:336
void add_css_class(const std::string &name)
set this object with a additional css_class (assuming it is defined in a css_library available for th...
Definition: body_builder.cpp:247
chemin get_path() const
return the path of 'this' according to its descent in the body_builder tree of adopted children
Definition: body_builder.cpp:437
virtual void new_css_library_available()
Definition: body_builder.hpp:392
virtual void will_foresake(body_builder *obj)
Be informed that a child is about to be foresaken.
Definition: body_builder.hpp:379
std::string get_body_part(const chemin &path, const request &req)
Definition: body_builder.cpp:354
void set_prefix(const chemin &prefix)
Definition: body_builder.cpp:108
bool has_my_body_part_changed() const
obtain the body_part changed status
Definition: body_builder.hpp:319
void set_no_CR(bool no_cr=true)
ask for the implementation not to add a new line after this control
Definition: body_builder.cpp:393
virtual void path_has_changed()
For inherited classes, called when the path has changed,.
Definition: body_builder.hpp:373
bool get_visible_recursively() const
return the effective visible status of an object taking into account all of ancestors that adopted it
Definition: body_builder.cpp:236
bool is_adopted() const
whether the object has currently a parent (= is adopted)
Definition: body_builder.hpp:162
void foresake(body_builder *obj)
Definition: body_builder.cpp:167
class chemin definition
Definition: chemin.hpp:51
manages a set of css class names
Definition: css_class_group.hpp:46
class css_class gather css attributed under a given label
Definition: css_class.hpp:51
class managing Cascading Style Sheets attributes
Definition: css.hpp:48
class holding fields of an HTTP request (method, URI, header, cookies, and so on)
Definition: request.hpp:45
uri type holds the splitted list of the scheme / hostname / path # anchor
Definition: uri.hpp:44