@reidelsaltres/pureper 0.1.157 → 0.1.160
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.
- package/out/foundation/api/Observer.d.ts +30 -0
- package/out/foundation/api/Observer.d.ts.map +1 -1
- package/out/foundation/api/Observer.js +48 -0
- package/out/foundation/api/Observer.js.map +1 -1
- package/out/foundation/engine/BalancedParser.d.ts +58 -0
- package/out/foundation/engine/BalancedParser.d.ts.map +1 -0
- package/out/foundation/engine/BalancedParser.js +301 -0
- package/out/foundation/engine/BalancedParser.js.map +1 -0
- package/out/foundation/engine/EscapeHandler.d.ts +27 -0
- package/out/foundation/engine/EscapeHandler.d.ts.map +1 -0
- package/out/foundation/engine/EscapeHandler.js +47 -0
- package/out/foundation/engine/EscapeHandler.js.map +1 -0
- package/out/foundation/engine/Expression.d.ts +83 -0
- package/out/foundation/engine/Expression.d.ts.map +1 -0
- package/out/foundation/engine/Expression.js +256 -0
- package/out/foundation/engine/Expression.js.map +1 -0
- package/out/foundation/engine/Rule.d.ts +83 -0
- package/out/foundation/engine/Rule.d.ts.map +1 -0
- package/out/foundation/engine/Rule.js +69 -0
- package/out/foundation/engine/Rule.js.map +1 -0
- package/out/foundation/engine/Scope.d.ts +57 -0
- package/out/foundation/engine/Scope.d.ts.map +1 -0
- package/out/foundation/engine/Scope.js +147 -0
- package/out/foundation/engine/Scope.js.map +1 -0
- package/out/foundation/engine/TemplateEngine.d.ts +79 -0
- package/out/foundation/engine/TemplateEngine.d.ts.map +1 -0
- package/out/foundation/engine/TemplateEngine.js +187 -0
- package/out/foundation/engine/TemplateEngine.js.map +1 -0
- package/out/foundation/engine/TemplateInstance.d.ts +121 -0
- package/out/foundation/engine/TemplateInstance.d.ts.map +1 -0
- package/out/foundation/engine/TemplateInstance.js +255 -0
- package/out/foundation/engine/TemplateInstance.js.map +1 -0
- package/out/foundation/engine/exceptions/TemplateExceptions.d.ts +21 -0
- package/out/foundation/engine/exceptions/TemplateExceptions.d.ts.map +1 -0
- package/out/foundation/engine/exceptions/TemplateExceptions.js +26 -0
- package/out/foundation/engine/exceptions/TemplateExceptions.js.map +1 -0
- package/out/foundation/engine/index.d.ts +18 -0
- package/out/foundation/engine/index.d.ts.map +1 -0
- package/out/foundation/engine/index.js +19 -0
- package/out/foundation/engine/index.js.map +1 -0
- package/out/foundation/engine/rules/attribute/EventRule.d.ts +22 -0
- package/out/foundation/engine/rules/attribute/EventRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/attribute/EventRule.js +129 -0
- package/out/foundation/engine/rules/attribute/EventRule.js.map +1 -0
- package/out/foundation/engine/rules/attribute/InjectionRule.d.ts +20 -0
- package/out/foundation/engine/rules/attribute/InjectionRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/attribute/InjectionRule.js +108 -0
- package/out/foundation/engine/rules/attribute/InjectionRule.js.map +1 -0
- package/out/foundation/engine/rules/attribute/RefRule.d.ts +23 -0
- package/out/foundation/engine/rules/attribute/RefRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/attribute/RefRule.js +98 -0
- package/out/foundation/engine/rules/attribute/RefRule.js.map +1 -0
- package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts +19 -0
- package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/syntax/ExpressionRule.js +82 -0
- package/out/foundation/engine/rules/syntax/ExpressionRule.js.map +1 -0
- package/out/foundation/engine/rules/syntax/ForRule.d.ts +19 -0
- package/out/foundation/engine/rules/syntax/ForRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/syntax/ForRule.js +226 -0
- package/out/foundation/engine/rules/syntax/ForRule.js.map +1 -0
- package/out/foundation/engine/rules/syntax/IfRule.d.ts +17 -0
- package/out/foundation/engine/rules/syntax/IfRule.d.ts.map +1 -0
- package/out/foundation/engine/rules/syntax/IfRule.js +220 -0
- package/out/foundation/engine/rules/syntax/IfRule.js.map +1 -0
- package/out/foundation/worker/Router.d.ts.map +1 -1
- package/out/foundation/worker/Router.js.map +1 -1
- package/out/index.d.ts +3 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +3 -0
- package/out/index.js.map +1 -1
- package/package.json +1 -1
- package/src/foundation/api/Observer.ts +60 -0
- package/src/foundation/engine/BalancedParser.ts +353 -0
- package/src/foundation/engine/EscapeHandler.ts +54 -0
- package/src/foundation/engine/Expression.ts +285 -0
- package/src/foundation/engine/Rule.ts +136 -0
- package/src/foundation/engine/Scope.ts +166 -0
- package/src/foundation/engine/TemplateEngine.ts +243 -0
- package/src/foundation/engine/TemplateInstance.ts +355 -0
- package/src/foundation/engine/exceptions/TemplateExceptions.ts +27 -0
- package/src/foundation/engine/rules/attribute/EventRule.ts +171 -0
- package/src/foundation/engine/rules/attribute/InjectionRule.ts +140 -0
- package/src/foundation/engine/rules/attribute/RefRule.ts +119 -0
- package/src/foundation/engine/rules/syntax/ExpressionRule.ts +102 -0
- package/src/foundation/engine/rules/syntax/ForRule.ts +267 -0
- package/src/foundation/engine/rules/syntax/IfRule.ts +261 -0
- package/src/foundation/worker/Router.ts +1 -1
- package/src/index.ts +9 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { MutationObserver } from '../api/Observer.js';
|
|
2
|
+
/**
|
|
3
|
+
* PageTemplate - динамический шаблон страницы.
|
|
4
|
+
* Хранит обработанные Rule и поддерживает реактивное обновление.
|
|
5
|
+
*
|
|
6
|
+
* При изменении Observable все зависимые секции обновляются
|
|
7
|
+
* одновременно в одном событии onTemplateChange.
|
|
8
|
+
*/
|
|
9
|
+
export default class TemplateInstance {
|
|
10
|
+
template;
|
|
11
|
+
scope;
|
|
12
|
+
sections = [];
|
|
13
|
+
fragment = null;
|
|
14
|
+
/** Observers for template changes */
|
|
15
|
+
changeObserver = new MutationObserver();
|
|
16
|
+
/** Группировка секций по Observable */
|
|
17
|
+
observableTrackings = new Map();
|
|
18
|
+
constructor(template, scope) {
|
|
19
|
+
this.template = template;
|
|
20
|
+
this.scope = scope;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Получить текущий шаблон
|
|
24
|
+
*/
|
|
25
|
+
getTemplate() {
|
|
26
|
+
return this.template;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Установить новый шаблон (вызывает событие изменения)
|
|
30
|
+
*/
|
|
31
|
+
setTemplate(newTemplate) {
|
|
32
|
+
const oldTemplate = this.template;
|
|
33
|
+
this.template = newTemplate;
|
|
34
|
+
this.changeObserver.notify({ oldValue: null, newValue: null, oldTemplate, newTemplate }, { oldValue: null, newValue: null, oldTemplate, newTemplate });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Получить Scope
|
|
38
|
+
*/
|
|
39
|
+
getScope() {
|
|
40
|
+
return this.scope;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Подписаться на изменения шаблона
|
|
44
|
+
*/
|
|
45
|
+
onTemplateChange(listener) {
|
|
46
|
+
const wrapper = (oldEvent, newEvent) => {
|
|
47
|
+
listener(newEvent.oldValue, newEvent.newValue, newEvent.oldTemplate, newEvent.newTemplate);
|
|
48
|
+
};
|
|
49
|
+
this.changeObserver.subscribe(wrapper);
|
|
50
|
+
return () => this.changeObserver.unsubscribe(wrapper);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Добавить секцию шаблона
|
|
54
|
+
*/
|
|
55
|
+
addSection(section) {
|
|
56
|
+
this.sections.push(section);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Получить все секции
|
|
60
|
+
*/
|
|
61
|
+
getSections() {
|
|
62
|
+
return this.sections;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Подписаться на Observable и автоматически пересоздавать секцию.
|
|
66
|
+
* Все секции, зависящие от одного Observable, обновляются разом.
|
|
67
|
+
*/
|
|
68
|
+
trackObservable(observable, section, rebuild) {
|
|
69
|
+
// Проверяем, есть ли уже отслеживание для этого Observable
|
|
70
|
+
let tracking = this.observableTrackings.get(observable);
|
|
71
|
+
if (!tracking) {
|
|
72
|
+
// Создаём новое отслеживание
|
|
73
|
+
const listener = (newValue) => {
|
|
74
|
+
this.rebuildAllSectionsForObservable(observable, newValue);
|
|
75
|
+
};
|
|
76
|
+
observable.subscribe(listener);
|
|
77
|
+
tracking = {
|
|
78
|
+
observable,
|
|
79
|
+
sections: [],
|
|
80
|
+
unsubscribe: () => observable.unsubscribe(listener)
|
|
81
|
+
};
|
|
82
|
+
this.observableTrackings.set(observable, tracking);
|
|
83
|
+
}
|
|
84
|
+
// Добавляем секцию в отслеживание
|
|
85
|
+
tracking.sections.push({ section, rebuild });
|
|
86
|
+
// Возвращаем функцию отписки для этой конкретной секции
|
|
87
|
+
return () => {
|
|
88
|
+
if (tracking) {
|
|
89
|
+
tracking.sections = tracking.sections.filter(s => s.section !== section);
|
|
90
|
+
// Если больше нет секций, отписываемся от Observable
|
|
91
|
+
if (tracking.sections.length === 0) {
|
|
92
|
+
tracking.unsubscribe();
|
|
93
|
+
this.observableTrackings.delete(observable);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Перестроить все секции, зависящие от Observable, за один раз
|
|
100
|
+
*/
|
|
101
|
+
rebuildAllSectionsForObservable(observable, newValue) {
|
|
102
|
+
const tracking = this.observableTrackings.get(observable);
|
|
103
|
+
if (!tracking || tracking.sections.length === 0)
|
|
104
|
+
return;
|
|
105
|
+
const oldTemplate = this.template;
|
|
106
|
+
let currentTemplate = this.template;
|
|
107
|
+
// Собираем все замены: старый output -> новый output
|
|
108
|
+
// Сортируем по позиции в шаблоне (с конца), чтобы замены не сбивали индексы
|
|
109
|
+
const replacements = [];
|
|
110
|
+
for (const { section, rebuild } of tracking.sections) {
|
|
111
|
+
// Unsubscribe old nested observables
|
|
112
|
+
this.unsubscribeSectionNested(section);
|
|
113
|
+
// Rebuild section
|
|
114
|
+
const newResult = rebuild(section);
|
|
115
|
+
const oldOutput = section.result.output;
|
|
116
|
+
replacements.push({
|
|
117
|
+
oldOutput,
|
|
118
|
+
newOutput: newResult.output,
|
|
119
|
+
section
|
|
120
|
+
});
|
|
121
|
+
section.result = newResult;
|
|
122
|
+
}
|
|
123
|
+
// Применяем все замены
|
|
124
|
+
for (const { oldOutput, newOutput } of replacements) {
|
|
125
|
+
currentTemplate = currentTemplate.replace(oldOutput, newOutput);
|
|
126
|
+
}
|
|
127
|
+
this.template = currentTemplate;
|
|
128
|
+
// Одно событие для всех изменений
|
|
129
|
+
this.changeObserver.notify({ oldValue: null, newValue, oldTemplate, newTemplate: this.template }, { oldValue: null, newValue, oldTemplate, newTemplate: this.template });
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Отписаться от вложенных Observable в секции (но не от главного)
|
|
133
|
+
*/
|
|
134
|
+
unsubscribeSectionNested(section) {
|
|
135
|
+
// Отписываемся только от подписок, сохранённых непосредственно в секции
|
|
136
|
+
for (const sub of section.subscriptions) {
|
|
137
|
+
sub.unsubscribe();
|
|
138
|
+
}
|
|
139
|
+
section.subscriptions = [];
|
|
140
|
+
// Recursively unsubscribe children
|
|
141
|
+
for (const child of section.children) {
|
|
142
|
+
this.unsubscribeSectionNested(child);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Отписаться от всех Observable в секции
|
|
147
|
+
*/
|
|
148
|
+
unsubscribeSection(section) {
|
|
149
|
+
for (const sub of section.subscriptions) {
|
|
150
|
+
sub.unsubscribe();
|
|
151
|
+
}
|
|
152
|
+
section.subscriptions = [];
|
|
153
|
+
// Recursively unsubscribe children
|
|
154
|
+
for (const child of section.children) {
|
|
155
|
+
this.unsubscribeSection(child);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Создать DocumentFragment из текущего шаблона
|
|
160
|
+
*/
|
|
161
|
+
createFragment() {
|
|
162
|
+
if (typeof document === 'undefined') {
|
|
163
|
+
throw new Error('PageTemplate.createFragment() requires DOM environment');
|
|
164
|
+
}
|
|
165
|
+
const template = document.createElement('template');
|
|
166
|
+
template.innerHTML = this.template;
|
|
167
|
+
this.fragment = template.content.cloneNode(true);
|
|
168
|
+
return this.fragment;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Получить кэшированный DocumentFragment
|
|
172
|
+
*/
|
|
173
|
+
getFragment() {
|
|
174
|
+
return this.fragment;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Пересоздать fragment
|
|
178
|
+
*/
|
|
179
|
+
rebuildFragment() {
|
|
180
|
+
this.fragment = null;
|
|
181
|
+
return this.createFragment();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Очистить все подписки
|
|
185
|
+
*/
|
|
186
|
+
dispose() {
|
|
187
|
+
// Отписываемся от всех Observable
|
|
188
|
+
for (const tracking of this.observableTrackings.values()) {
|
|
189
|
+
tracking.unsubscribe();
|
|
190
|
+
}
|
|
191
|
+
this.observableTrackings.clear();
|
|
192
|
+
// Очищаем секции
|
|
193
|
+
for (const section of this.sections) {
|
|
194
|
+
this.unsubscribeSection(section);
|
|
195
|
+
}
|
|
196
|
+
this.sections = [];
|
|
197
|
+
this.fragment = null;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Привязать refs после вставки в DOM
|
|
201
|
+
*/
|
|
202
|
+
bindRefs(root) {
|
|
203
|
+
const refElements = root.querySelectorAll('[data-ref]');
|
|
204
|
+
for (const element of Array.from(refElements)) {
|
|
205
|
+
const refName = element.getAttribute('data-ref');
|
|
206
|
+
if (refName) {
|
|
207
|
+
this.scope.set(refName, element);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Обработать инжекции (@injection[head/tail])
|
|
213
|
+
* Должен вызываться после bindRefs
|
|
214
|
+
*/
|
|
215
|
+
processInjections(root) {
|
|
216
|
+
// Find all elements with injection attributes
|
|
217
|
+
const injectElements = root.querySelectorAll('[data-injection-type][data-injection-target]');
|
|
218
|
+
for (const element of Array.from(injectElements)) {
|
|
219
|
+
const type = element.getAttribute('data-injection-type');
|
|
220
|
+
const targetRefName = decodeURIComponent(element.getAttribute('data-injection-target') || '');
|
|
221
|
+
if (!targetRefName)
|
|
222
|
+
continue;
|
|
223
|
+
// Get target element from scope
|
|
224
|
+
const targetElement = this.scope.get(targetRefName);
|
|
225
|
+
if (!targetElement || !(targetElement instanceof Element)) {
|
|
226
|
+
console.warn(`[PageTemplate] Injection target "${targetRefName}" not found in scope or is not an Element`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
// Remove injection attributes
|
|
230
|
+
element.removeAttribute('data-injection-type');
|
|
231
|
+
element.removeAttribute('data-injection-target');
|
|
232
|
+
// Perform injection
|
|
233
|
+
if (type === 'head') {
|
|
234
|
+
targetElement.prepend(element);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
targetElement.append(element);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Отвязать refs (установить null)
|
|
243
|
+
*/
|
|
244
|
+
unbindRefs() {
|
|
245
|
+
for (const section of this.sections) {
|
|
246
|
+
if (section.rule.name === 'ref' && section.match.data?.expression) {
|
|
247
|
+
const refName = section.match.data.expression;
|
|
248
|
+
if (this.scope.has(refName)) {
|
|
249
|
+
this.scope.set(refName, null);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=TemplateInstance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateInstance.js","sourceRoot":"","sources":["../../../src/foundation/engine/TemplateInstance.ts"],"names":[],"mappings":"AACA,OAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA2ClE;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACzB,QAAQ,CAAS;IACjB,KAAK,CAAQ;IACb,QAAQ,GAAsB,EAAE,CAAC;IACjC,QAAQ,GAA4B,IAAI,CAAC;IAEjD,qCAAqC;IAC7B,cAAc,GAAG,IAAI,gBAAgB,EAAuB,CAAC;IAErE,uCAAuC;IAC/B,mBAAmB,GAAG,IAAI,GAAG,EAAuC,CAAC;IAE7E,YAAY,QAAgB,EAAE,KAAY;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAED;;OAEG;IACI,WAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,WAAmB;QAClC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC;QAE5B,IAAI,CAAC,cAAc,CAAC,MAAM,CACtB,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,EAC5D,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAC/D,CAAC;IACN,CAAC;IAED;;OAEG;IACI,QAAQ;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED;;OAEG;IACI,gBAAgB,CACnB,QAA0F;QAE1F,MAAM,OAAO,GAAG,CAAC,QAA6B,EAAE,QAA6B,EAAE,EAAE;YAC7E,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC/F,CAAC,CAAC;QACF,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,OAAwB;QACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,WAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,eAAe,CAClB,UAA2B,EAC3B,OAAwB,EACxB,OAAiD;QAEjD,2DAA2D;QAC3D,IAAI,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,6BAA6B;YAC7B,MAAM,QAAQ,GAAG,CAAC,QAAa,EAAE,EAAE;gBAC/B,IAAI,CAAC,+BAA+B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC/D,CAAC,CAAC;YAEF,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAE/B,QAAQ,GAAG;gBACP,UAAU;gBACV,QAAQ,EAAE,EAAE;gBACZ,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC;aACtD,CAAC;YAEF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvD,CAAC;QAED,kCAAkC;QAClC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAE7C,wDAAwD;QACxD,OAAO,GAAG,EAAE;YACR,IAAI,QAAQ,EAAE,CAAC;gBACX,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;gBAEzE,qDAAqD;gBACrD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACvB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAChD,CAAC;YACL,CAAC;QACL,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACK,+BAA+B,CAAC,UAA2B,EAAE,QAAa;QAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAExD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC;QAClC,IAAI,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEpC,qDAAqD;QACrD,4EAA4E;QAC5E,MAAM,YAAY,GAA8E,EAAE,CAAC;QAEnG,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACnD,qCAAqC;YACrC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;YAEvC,kBAAkB;YAClB,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YACnC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAExC,YAAY,CAAC,IAAI,CAAC;gBACd,SAAS;gBACT,SAAS,EAAE,SAAS,CAAC,MAAM;gBAC3B,OAAO;aACV,CAAC,CAAC;YAEH,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;QAC/B,CAAC;QAED,uBAAuB;QACvB,KAAK,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,YAAY,EAAE,CAAC;YAClD,eAAe,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC;QAEhC,kCAAkC;QAClC,IAAI,CAAC,cAAc,CAAC,MAAM,CACtB,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,EACrE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,CACxE,CAAC;IACN,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,OAAwB;QACrD,wEAAwE;QACxE,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACtC,GAAG,CAAC,WAAW,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,aAAa,GAAG,EAAE,CAAC;QAE3B,mCAAmC;QACnC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,OAAwB;QAC/C,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACtC,GAAG,CAAC,WAAW,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,aAAa,GAAG,EAAE,CAAC;QAE3B,mCAAmC;QACnC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,cAAc;QACjB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACpD,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAqB,CAAC;QAErE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,WAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,eAAe;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACI,OAAO;QACV,kCAAkC;QAClC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC;YACvD,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAEjC,iBAAiB;QACjB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,IAAgC;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAExD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,iBAAiB,CAAC,IAAgC;QACrD,8CAA8C;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC,8CAA8C,CAAC,CAAC;QAE7F,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAoB,CAAC;YAC5E,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAC,CAAC;YAE9F,IAAI,CAAC,aAAa;gBAAE,SAAS;YAE7B,gCAAgC;YAChC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAEpD,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,YAAY,OAAO,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,oCAAoC,aAAa,2CAA2C,CAAC,CAAC;gBAC3G,SAAS;YACb,CAAC;YAED,8BAA8B;YAC9B,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC;YAC/C,OAAO,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;YAEjD,oBAAoB;YACpB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAClB,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACI,UAAU;QACb,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;gBAChE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;gBAC9C,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InvalidDynamicRuleUsage - исключение при использовании Observable
|
|
3
|
+
* в правилах, которые не поддерживают динамическое обновление.
|
|
4
|
+
* Например: @[ref], @injection
|
|
5
|
+
*/
|
|
6
|
+
export declare class InvalidDynamicRuleUsage extends Error {
|
|
7
|
+
constructor(ruleName: string, message?: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* InvalidTemplateEngineSyntaxException - исключение при синтаксических ошибках
|
|
11
|
+
* в шаблоне. Например: @if без boolean, @for с неверным типом.
|
|
12
|
+
*/
|
|
13
|
+
export declare class InvalidTemplateEngineSyntaxException extends Error {
|
|
14
|
+
readonly line?: number;
|
|
15
|
+
readonly column?: number;
|
|
16
|
+
constructor(message: string, options?: {
|
|
17
|
+
line?: number;
|
|
18
|
+
column?: number;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=TemplateExceptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateExceptions.d.ts","sourceRoot":"","sources":["../../../../src/foundation/engine/exceptions/TemplateExceptions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBAClC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAIjD;AAED;;;GAGG;AACH,qBAAa,oCAAqC,SAAQ,KAAK;IAC3D,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAM5E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InvalidDynamicRuleUsage - исключение при использовании Observable
|
|
3
|
+
* в правилах, которые не поддерживают динамическое обновление.
|
|
4
|
+
* Например: @[ref], @injection
|
|
5
|
+
*/
|
|
6
|
+
export class InvalidDynamicRuleUsage extends Error {
|
|
7
|
+
constructor(ruleName, message) {
|
|
8
|
+
super(message ?? `Rule "${ruleName}" does not support Observable values. Use a static value instead.`);
|
|
9
|
+
this.name = 'InvalidDynamicRuleUsage';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* InvalidTemplateEngineSyntaxException - исключение при синтаксических ошибках
|
|
14
|
+
* в шаблоне. Например: @if без boolean, @for с неверным типом.
|
|
15
|
+
*/
|
|
16
|
+
export class InvalidTemplateEngineSyntaxException extends Error {
|
|
17
|
+
line;
|
|
18
|
+
column;
|
|
19
|
+
constructor(message, options) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = 'InvalidTemplateEngineSyntaxException';
|
|
22
|
+
this.line = options?.line;
|
|
23
|
+
this.column = options?.column;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=TemplateExceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateExceptions.js","sourceRoot":"","sources":["../../../../src/foundation/engine/exceptions/TemplateExceptions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC9C,YAAY,QAAgB,EAAE,OAAgB;QAC1C,KAAK,CAAC,OAAO,IAAI,SAAS,QAAQ,mEAAmE,CAAC,CAAC;QACvG,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IAC1C,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,OAAO,oCAAqC,SAAQ,KAAK;IAC3C,IAAI,CAAU;IACd,MAAM,CAAU;IAEhC,YAAY,OAAe,EAAE,OAA4C;QACrE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sCAAsC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAClC,CAAC;CACJ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { default as TemplateEngine } from './TemplateEngine.js';
|
|
2
|
+
export { default as Scope } from './Scope.js';
|
|
3
|
+
export { default as Expression } from './Expression.js';
|
|
4
|
+
export { default as PageTemplate } from './PageTemplate.js';
|
|
5
|
+
export { default as BalancedParser } from './BalancedParser.js';
|
|
6
|
+
export { default as EscapeHandler } from './EscapeHandler.js';
|
|
7
|
+
export { default as Rule, SyntaxRule, AttributeRule } from './Rule.js';
|
|
8
|
+
export type { RuleMatch, RuleResult, RuleType } from './Rule.js';
|
|
9
|
+
export { default as ExpressionRule } from './rules/syntax/ExpressionRule.js';
|
|
10
|
+
export { default as IfRule } from './rules/syntax/IfRule.js';
|
|
11
|
+
export { default as ForRule } from './rules/syntax/ForRule.js';
|
|
12
|
+
export { default as RefRule } from './rules/attribute/RefRule.js';
|
|
13
|
+
export { default as EventRule } from './rules/attribute/EventRule.js';
|
|
14
|
+
export { default as InjectionRule } from './rules/attribute/InjectionRule.js';
|
|
15
|
+
export { InvalidDynamicRuleUsage, InvalidTemplateEngineSyntaxException } from './exceptions/TemplateExceptions.js';
|
|
16
|
+
export type { TemplateEngineOptions, ProcessResult } from './TemplateEngine.js';
|
|
17
|
+
export type { TemplateSection, TemplateChangeEvent } from './PageTemplate.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/foundation/engine/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAG9E,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACvC,MAAM,oCAAoC,CAAC;AAG5C,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChF,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Export all engine components
|
|
2
|
+
export { default as TemplateEngine } from './TemplateEngine.js';
|
|
3
|
+
export { default as Scope } from './Scope.js';
|
|
4
|
+
export { default as Expression } from './Expression.js';
|
|
5
|
+
export { default as PageTemplate } from './PageTemplate.js';
|
|
6
|
+
export { default as BalancedParser } from './BalancedParser.js';
|
|
7
|
+
export { default as EscapeHandler } from './EscapeHandler.js';
|
|
8
|
+
// Export Rule system
|
|
9
|
+
export { default as Rule, SyntaxRule, AttributeRule } from './Rule.js';
|
|
10
|
+
// Export concrete rules
|
|
11
|
+
export { default as ExpressionRule } from './rules/syntax/ExpressionRule.js';
|
|
12
|
+
export { default as IfRule } from './rules/syntax/IfRule.js';
|
|
13
|
+
export { default as ForRule } from './rules/syntax/ForRule.js';
|
|
14
|
+
export { default as RefRule } from './rules/attribute/RefRule.js';
|
|
15
|
+
export { default as EventRule } from './rules/attribute/EventRule.js';
|
|
16
|
+
export { default as InjectionRule } from './rules/attribute/InjectionRule.js';
|
|
17
|
+
// Export exceptions
|
|
18
|
+
export { InvalidDynamicRuleUsage, InvalidTemplateEngineSyntaxException } from './exceptions/TemplateExceptions.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/foundation/engine/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE9D,qBAAqB;AACrB,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAGvE,wBAAwB;AACxB,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAE9E,oBAAoB;AACpB,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACvC,MAAM,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AttributeRule } from '../../Rule.js';
|
|
2
|
+
import type { RuleMatch, RuleResult } from '../../Rule.js';
|
|
3
|
+
import Scope from '../../Scope.js';
|
|
4
|
+
/**
|
|
5
|
+
* EventRule - обработка @on[eventName]="expression"
|
|
6
|
+
* Подписывает элемент на событие.
|
|
7
|
+
*/
|
|
8
|
+
export default class EventRule extends AttributeRule {
|
|
9
|
+
readonly name = "event";
|
|
10
|
+
readonly priority = 30;
|
|
11
|
+
find(template: string): RuleMatch[];
|
|
12
|
+
execute(match: RuleMatch, scope: Scope): RuleResult;
|
|
13
|
+
/**
|
|
14
|
+
* Постобработка: привязать события к элементам
|
|
15
|
+
*/
|
|
16
|
+
static bindEvents(element: Element, scope: Scope): (() => void)[];
|
|
17
|
+
/**
|
|
18
|
+
* Привязать событие с поддержкой Observable
|
|
19
|
+
*/
|
|
20
|
+
static bindEventWithObservable(element: Element, eventName: string, exprCode: string, scope: Scope): () => void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=EventRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/EventRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAWnC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,aAAa;IAChD,SAAgB,IAAI,WAAW;IAC/B,SAAgB,QAAQ,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAsDnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IAa1D;;OAEG;WACW,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE;IAkCxE;;OAEG;WACW,uBAAuB,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,GACb,MAAM,IAAI;CAqChB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { AttributeRule } from '../../Rule.js';
|
|
2
|
+
import Expression from '../../Expression.js';
|
|
3
|
+
/**
|
|
4
|
+
* EventRule - обработка @on[eventName]="expression"
|
|
5
|
+
* Подписывает элемент на событие.
|
|
6
|
+
*/
|
|
7
|
+
export default class EventRule extends AttributeRule {
|
|
8
|
+
name = 'event';
|
|
9
|
+
priority = 30;
|
|
10
|
+
find(template) {
|
|
11
|
+
const results = [];
|
|
12
|
+
// Match @on[eventName]="
|
|
13
|
+
const pattern = /@on\[([a-zA-Z]+)\]\s*=/gi;
|
|
14
|
+
let match;
|
|
15
|
+
while ((match = pattern.exec(template)) !== null) {
|
|
16
|
+
const idx = match.index;
|
|
17
|
+
// Check for @@ escape
|
|
18
|
+
if (idx > 0 && template[idx - 1] === '@') {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const eventName = match[1].toLowerCase();
|
|
22
|
+
// Find quote char after =
|
|
23
|
+
let pos = idx + match[0].length;
|
|
24
|
+
while (pos < template.length && /\s/.test(template[pos])) {
|
|
25
|
+
pos++;
|
|
26
|
+
}
|
|
27
|
+
const quoteChar = template[pos];
|
|
28
|
+
if (quoteChar !== '"' && quoteChar !== "'") {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// Find matching closing quote
|
|
32
|
+
const contentStart = pos + 1;
|
|
33
|
+
pos++;
|
|
34
|
+
while (pos < template.length && template[pos] !== quoteChar) {
|
|
35
|
+
pos++;
|
|
36
|
+
}
|
|
37
|
+
if (pos >= template.length)
|
|
38
|
+
continue;
|
|
39
|
+
const content = template.slice(contentStart, pos);
|
|
40
|
+
const fullMatch = template.slice(idx, pos + 1);
|
|
41
|
+
results.push({
|
|
42
|
+
fullMatch,
|
|
43
|
+
start: idx,
|
|
44
|
+
end: pos + 1,
|
|
45
|
+
data: {
|
|
46
|
+
eventName,
|
|
47
|
+
expression: content,
|
|
48
|
+
attributeMatch: fullMatch
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
execute(match, scope) {
|
|
55
|
+
const data = match.data;
|
|
56
|
+
// Generate data attribute for later DOM binding
|
|
57
|
+
// Actual event binding happens in postprocessing
|
|
58
|
+
const encodedExpr = encodeURIComponent(data.expression);
|
|
59
|
+
return {
|
|
60
|
+
output: `data-event-${data.eventName}="${encodedExpr}"`,
|
|
61
|
+
observables: []
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Постобработка: привязать события к элементам
|
|
66
|
+
*/
|
|
67
|
+
static bindEvents(element, scope) {
|
|
68
|
+
const unbinders = [];
|
|
69
|
+
// Find all data-event-* attributes
|
|
70
|
+
const attributes = Array.from(element.attributes);
|
|
71
|
+
for (const attr of attributes) {
|
|
72
|
+
if (attr.name.startsWith('data-event-')) {
|
|
73
|
+
const eventName = attr.name.slice('data-event-'.length);
|
|
74
|
+
const exprCode = decodeURIComponent(attr.value);
|
|
75
|
+
const handler = (event) => {
|
|
76
|
+
// Create local scope with event
|
|
77
|
+
const localScope = scope.createChild({ event });
|
|
78
|
+
const expr = new Expression(exprCode);
|
|
79
|
+
try {
|
|
80
|
+
expr.execute(localScope);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error(`[EventRule] Error executing handler for ${eventName}:`, error);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
element.addEventListener(eventName, handler);
|
|
87
|
+
unbinders.push(() => element.removeEventListener(eventName, handler));
|
|
88
|
+
// Optionally remove the data attribute
|
|
89
|
+
// element.removeAttribute(attr.name);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return unbinders;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Привязать событие с поддержкой Observable
|
|
96
|
+
*/
|
|
97
|
+
static bindEventWithObservable(element, eventName, exprCode, scope) {
|
|
98
|
+
let currentHandler = null;
|
|
99
|
+
const setupHandler = () => {
|
|
100
|
+
// Remove old handler if exists
|
|
101
|
+
if (currentHandler) {
|
|
102
|
+
element.removeEventListener(eventName, currentHandler);
|
|
103
|
+
}
|
|
104
|
+
currentHandler = (event) => {
|
|
105
|
+
const localScope = scope.createChild({ event });
|
|
106
|
+
const expr = new Expression(exprCode);
|
|
107
|
+
try {
|
|
108
|
+
const result = expr.execute(localScope);
|
|
109
|
+
// If result is Observable, handle it
|
|
110
|
+
if (result && typeof result === 'object' && typeof result.subscribe === 'function') {
|
|
111
|
+
// Re-setup handler when Observable changes
|
|
112
|
+
result.subscribe(() => setupHandler());
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error(`[EventRule] Error executing handler for ${eventName}:`, error);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
element.addEventListener(eventName, currentHandler);
|
|
120
|
+
};
|
|
121
|
+
setupHandler();
|
|
122
|
+
return () => {
|
|
123
|
+
if (currentHandler) {
|
|
124
|
+
element.removeEventListener(eventName, currentHandler);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=EventRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/EventRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAU7C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,aAAa;IAChC,IAAI,GAAG,OAAO,CAAC;IACf,QAAQ,GAAG,EAAE,CAAC;IAEvB,IAAI,CAAC,QAAgB;QACxB,MAAM,OAAO,GAAgB,EAAE,CAAC;QAChC,yBAAyB;QACzB,MAAM,OAAO,GAAG,0BAA0B,CAAC;QAC3C,IAAI,KAA6B,CAAC;QAElC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/C,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC;YAExB,sBAAsB;YACtB,IAAI,GAAG,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACvC,SAAS;YACb,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAEzC,0BAA0B;YAC1B,IAAI,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAChC,OAAO,GAAG,GAAG,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACvD,GAAG,EAAE,CAAC;YACV,CAAC;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBACzC,SAAS;YACb,CAAC;YAED,8BAA8B;YAC9B,MAAM,YAAY,GAAG,GAAG,GAAG,CAAC,CAAC;YAC7B,GAAG,EAAE,CAAC;YACN,OAAO,GAAG,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1D,GAAG,EAAE,CAAC;YACV,CAAC;YAED,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM;gBAAE,SAAS;YAErC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;YAE/C,OAAO,CAAC,IAAI,CAAC;gBACT,SAAS;gBACT,KAAK,EAAE,GAAG;gBACV,GAAG,EAAE,GAAG,GAAG,CAAC;gBACZ,IAAI,EAAE;oBACF,SAAS;oBACT,UAAU,EAAE,OAAO;oBACnB,cAAc,EAAE,SAAS;iBAC5B;aACJ,CAAC,CAAC;QACP,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAEM,OAAO,CAAC,KAAgB,EAAE,KAAY;QACzC,MAAM,IAAI,GAAI,KAAoB,CAAC,IAAI,CAAC;QAExC,gDAAgD;QAChD,iDAAiD;QACjD,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAExD,OAAO;YACH,MAAM,EAAE,cAAc,IAAI,CAAC,SAAS,KAAK,WAAW,GAAG;YACvD,WAAW,EAAE,EAAE;SAClB,CAAC;IACN,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,UAAU,CAAC,OAAgB,EAAE,KAAY;QACnD,MAAM,SAAS,GAAmB,EAAE,CAAC;QAErC,mCAAmC;QACnC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAElD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACtC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAEhD,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE;oBAC7B,gCAAgC;oBAChC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;oBAChD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;oBAEtC,IAAI,CAAC;wBACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBAC7B,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACb,OAAO,CAAC,KAAK,CAAC,2CAA2C,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;oBAClF,CAAC;gBACL,CAAC,CAAC;gBAEF,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAC7C,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;gBAEtE,uCAAuC;gBACvC,sCAAsC;YAC1C,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,uBAAuB,CACjC,OAAgB,EAChB,SAAiB,EACjB,QAAgB,EAChB,KAAY;QAEZ,IAAI,cAAc,GAAoC,IAAI,CAAC;QAE3D,MAAM,YAAY,GAAG,GAAG,EAAE;YACtB,+BAA+B;YAC/B,IAAI,cAAc,EAAE,CAAC;gBACjB,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAC3D,CAAC;YAED,cAAc,GAAG,CAAC,KAAY,EAAE,EAAE;gBAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAEtC,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBAExC,qCAAqC;oBACrC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;wBACjF,2CAA2C;wBAC3C,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;oBAC3C,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,2CAA2C,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;gBAClF,CAAC;YACL,CAAC,CAAC;YAEF,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC;QAEF,YAAY,EAAE,CAAC;QAEf,OAAO,GAAG,EAAE;YACR,IAAI,cAAc,EAAE,CAAC;gBACjB,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AttributeRule } from '../../Rule.js';
|
|
2
|
+
import type { RuleMatch, RuleResult } from '../../Rule.js';
|
|
3
|
+
import Scope from '../../Scope.js';
|
|
4
|
+
/**
|
|
5
|
+
* InjectionRule - обработка @injection[type]="expression"
|
|
6
|
+
* Инжектирует элемент в целевой элемент (найденный по @[ref]).
|
|
7
|
+
* type: 'head' = prepend, 'tail' = append
|
|
8
|
+
*/
|
|
9
|
+
export default class InjectionRule extends AttributeRule {
|
|
10
|
+
readonly name = "injection";
|
|
11
|
+
readonly priority = 200;
|
|
12
|
+
find(template: string): RuleMatch[];
|
|
13
|
+
execute(match: RuleMatch, scope: Scope): RuleResult;
|
|
14
|
+
supportsObservable(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Постобработка: выполнить инжекцию элементов
|
|
17
|
+
*/
|
|
18
|
+
static processInjections(root: Element | DocumentFragment, scope: Scope): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=InjectionRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InjectionRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/InjectionRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAYnC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,aAAa;IACpD,SAAgB,IAAI,eAAe;IACnC,SAAgB,QAAQ,OAAO;IAExB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAsDnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IAyBnD,kBAAkB,IAAI,OAAO;IAIpC;;OAEG;WACW,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;CA8BxF"}
|