Open ildar-ceo opened 2 months ago
Класс VirtualDom
class VirtualDom extends BaseStruct
{
string name = "";
Dict<var> attrs = {};
Collection<var> items = [];
/**
* Create
*/
VirtualDom create(string name, Dict<var> attrs = {}, Collection<var> items) =>
new VirtualDom{
"name": name,
"attrs": attrs,
"items": items,
}
;
}
Интерфейс BuilderInterface
interface BuilderInterface
{
/**
* Create virtual node
*/
BuilderInterface h(string name, Dict<var> attrs = {}, Collection<var> items);
}
Класс DocumentBuilder
class DocumentBuilder implements BuilderInterface
{
VirtualDom node;
/**
* Create virtual node
*/
DocumentBuilder h(string name, Dict<var> attrs = {}, Collection<var> items)
{
DocumentBuilder item = new DocumentBuilder();
item.node = new VirtualDom{
"name": name,
"attrs": attrs,
"items": items,
};
this.node.items.push(item.node);
return item;
}
/**
* Create element
*/
var create()
{
if (this.node instanceof string) return this.createText(this.node);
if (this.node instanceof VirtualDom) return this.createElement(this.node);
return null;
}
/**
* Create text element
*/
var createText(string content)
{
return document.createTextNode(content);
}
/**
* Create element
*/
var createElement()
{
var elem = document.createElement(this.node.name);
/* Set attributes */
this.setAttrs(elem);
/* Create items */
this.createItems(elem);
return elem;
}
/**
* Set attributes
*/
void setAttrs(var elem)
{
if (not this.node.attrs) return;
this.node.attrs.each(void (var value, string key) use (elem){
if (value instanceof primitive)
{
elem.setAttribute(key, value);
}
});
}
/**
* Create items
*/
void createItems(var elem)
{
if (not this.node.items) return;
for (int i=0; i<this.node.items.count(); i++)
{
elem.appendChild(this.create(this.node.items.get(i)));
}
}
/**
* Patch HTML Element
*/
var patchElement(var element)
{
element.replaceWith(this.create());
}
}
Рендер функция
void render(BuilderInterface root)
{
BuilderInterface container = root.h("div", {"class": "container"});
container.h("h1", {"class": "title"}, ["Hello, World!"]);
container.h("p", {}, ["Text content"]);
}
Создание HTML элементов
DocumentBuilder builder = new DocumentBuilder();
builder.node = new VirtualDom::create("div", {"class": "root"});
/* Patch VirtualDom by builder */
render(builder);
/* Create HTML Element root */
var root_elem = builder.create();
Патч HTML элементов
render(builder);
builder.patch(root_elem);
Преобразование VirtualDom в строку
StringBuilder string_builder = new StringBuilder();
string_builder.node = new VirtualDom::create("div", {"class": "root"});
/* Patch VirtualDom */
render(string_builder);
/* Generate HTML String */
Collection items = [];
string_builder.createItems(items);
print(string_builder.join(items));
Необходимо поменять шаблонизатор. Шаблонизатор должен генерировать псевдокод HTML кода с параметром builder. Это нужно чтобы использовать один и тот же скомпилированный код шаблона в разных целях не меняя при этом транслятор.
Builder бывают разных типов:
VirtualDom может быть использован:
Пример:
Это открывает путь для использования в разных целей. В том числе использовать HTML шаблоны вне компонентах, а например в моделях, когда нужно сделать генерацию кастомных полей в таблице.