@reidelsaltres/pureper 0.1.157 → 0.1.162
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/Triplet.d.ts.map +1 -1
- package/out/foundation/Triplet.js +4 -5
- package/out/foundation/Triplet.js.map +1 -1
- 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/component_api/Component.d.ts +2 -2
- package/out/foundation/component_api/Component.d.ts.map +1 -1
- package/out/foundation/component_api/Component.js.map +1 -1
- package/out/foundation/component_api/UniHtml.d.ts +4 -10
- package/out/foundation/component_api/UniHtml.d.ts.map +1 -1
- package/out/foundation/component_api/UniHtml.js +7 -15
- package/out/foundation/component_api/UniHtml.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 +85 -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 +61 -0
- package/out/foundation/engine/Scope.d.ts.map +1 -0
- package/out/foundation/engine/Scope.js +156 -0
- package/out/foundation/engine/Scope.js.map +1 -0
- package/out/foundation/engine/TemplateEngine.d.ts +96 -0
- package/out/foundation/engine/TemplateEngine.d.ts.map +1 -0
- package/out/foundation/engine/TemplateEngine.js +235 -0
- package/out/foundation/engine/TemplateEngine.js.map +1 -0
- package/out/foundation/engine/TemplateInstance.d.ts +241 -0
- package/out/foundation/engine/TemplateInstance.d.ts.map +1 -0
- package/out/foundation/engine/TemplateInstance.js +637 -0
- package/out/foundation/engine/TemplateInstance.js.map +1 -0
- package/out/foundation/engine/TemplateInstance.old.d.ts +219 -0
- package/out/foundation/engine/TemplateInstance.old.d.ts.map +1 -0
- package/out/foundation/engine/TemplateInstance.old.js +487 -0
- package/out/foundation/engine/TemplateInstance.old.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 +104 -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 +2 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +2 -0
- package/out/index.js.map +1 -1
- package/package.json +1 -1
- package/src/foundation/Triplet.ts +6 -6
- package/src/foundation/api/Observer.ts +60 -0
- package/src/foundation/component_api/Component.ts +2 -1
- package/src/foundation/component_api/UniHtml.ts +12 -22
- 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 +138 -0
- package/src/foundation/engine/Scope.ts +176 -0
- package/src/foundation/engine/TemplateEngine.ts +318 -0
- package/src/foundation/engine/TemplateInstance.md +110 -0
- package/src/foundation/engine/TemplateInstance.old.ts +673 -0
- package/src/foundation/engine/TemplateInstance.ts +843 -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 +126 -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 +8 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import Scope from './Scope.js';
|
|
2
|
+
import Expression from './Expression.js';
|
|
3
|
+
import TemplateInstance, { TemplateSection } from './TemplateInstance.js';
|
|
4
|
+
import Rule, { SyntaxRule, AttributeRule } from './Rule.js';
|
|
5
|
+
import Observable from '../api/Observer.js';
|
|
6
|
+
import ExpressionRule from './rules/syntax/ExpressionRule.js';
|
|
7
|
+
import IfRule from './rules/syntax/IfRule.js';
|
|
8
|
+
import ForRule from './rules/syntax/ForRule.js';
|
|
9
|
+
import RefRule from './rules/attribute/RefRule.js';
|
|
10
|
+
import EventRule from './rules/attribute/EventRule.js';
|
|
11
|
+
import InjectionRule from './rules/attribute/InjectionRule.js';
|
|
12
|
+
/**
|
|
13
|
+
* TemplateEngineOptions - настройки TemplateEngine
|
|
14
|
+
*/
|
|
15
|
+
export interface TemplateEngineOptions {
|
|
16
|
+
/** Оставлять синтаксис атрибутивных Rule в финальном HTML */
|
|
17
|
+
showAttributeRule?: boolean;
|
|
18
|
+
/** Включить предупреждения отладки */
|
|
19
|
+
debugWarnings?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* ProcessResult - результат обработки шаблона
|
|
23
|
+
*/
|
|
24
|
+
export interface ProcessResult {
|
|
25
|
+
output: string;
|
|
26
|
+
observables: Observable<any>[];
|
|
27
|
+
sections: TemplateSection[];
|
|
28
|
+
/** ID созданного фрагмента (если был создан) */
|
|
29
|
+
fragmentId?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* TemplateEngine - главный класс шаблонизатора.
|
|
33
|
+
* Обрабатывает HTML-шаблон с Rule и создаёт TemplateInstance.
|
|
34
|
+
*/
|
|
35
|
+
export default class TemplateEngine {
|
|
36
|
+
private readonly scope;
|
|
37
|
+
private readonly options;
|
|
38
|
+
private readonly syntaxRules;
|
|
39
|
+
private readonly attributeRules;
|
|
40
|
+
constructor(scope: Scope | object, options?: TemplateEngineOptions);
|
|
41
|
+
/**
|
|
42
|
+
* Зарегистрировать стандартные правила
|
|
43
|
+
*/
|
|
44
|
+
private registerDefaultRules;
|
|
45
|
+
/**
|
|
46
|
+
* Добавить пользовательское правило
|
|
47
|
+
*/
|
|
48
|
+
addRule(rule: Rule): void;
|
|
49
|
+
/**
|
|
50
|
+
* Получить Scope
|
|
51
|
+
*/
|
|
52
|
+
getScope(): Scope;
|
|
53
|
+
/**
|
|
54
|
+
* Обработать шаблон и вернуть TemplateInstance
|
|
55
|
+
*/
|
|
56
|
+
parse(template: string): TemplateInstance;
|
|
57
|
+
/**
|
|
58
|
+
* Обработать шаблон с созданием фрагментов
|
|
59
|
+
*/
|
|
60
|
+
private processTemplateWithFragments;
|
|
61
|
+
/**
|
|
62
|
+
* Обработать шаблон (внутренний метод, используется Rule для рекурсии)
|
|
63
|
+
*/
|
|
64
|
+
processTemplate(template: string, scope: Scope): ProcessResult;
|
|
65
|
+
/**
|
|
66
|
+
* Обработать одно правило
|
|
67
|
+
*/
|
|
68
|
+
private processRule;
|
|
69
|
+
/**
|
|
70
|
+
* Удалить синтаксис атрибутивных Rule из финального HTML
|
|
71
|
+
*/
|
|
72
|
+
private removeAttributeSyntax;
|
|
73
|
+
/**
|
|
74
|
+
* Добавить новый шаблон в существующий TemplateInstance.
|
|
75
|
+
* Обрабатывает шаблон и добавляет результат как новый фрагмент.
|
|
76
|
+
* Если instance привязан к контейнерам, DOM обновится автоматически.
|
|
77
|
+
*
|
|
78
|
+
* @param instance - существующий TemplateInstance
|
|
79
|
+
* @param template - новый шаблон для добавления
|
|
80
|
+
* @param customScope - опциональный scope для нового шаблона
|
|
81
|
+
* @returns ID созданного фрагмента
|
|
82
|
+
*/
|
|
83
|
+
appendTemplate(instance: TemplateInstance, template: string, customScope?: Scope | object): string;
|
|
84
|
+
/**
|
|
85
|
+
* Статический метод для быстрой обработки
|
|
86
|
+
*/
|
|
87
|
+
static process(template: string, scope: object, options?: TemplateEngineOptions): string;
|
|
88
|
+
/**
|
|
89
|
+
* Создать TemplateInstance из шаблона
|
|
90
|
+
*/
|
|
91
|
+
static create(template: string, scope: object, options?: TemplateEngineOptions): TemplateInstance;
|
|
92
|
+
}
|
|
93
|
+
export { Scope, Expression, TemplateInstance, Rule, SyntaxRule, AttributeRule };
|
|
94
|
+
export { ExpressionRule, IfRule, ForRule, RefRule, EventRule, InjectionRule };
|
|
95
|
+
export * from './exceptions/TemplateExceptions.js';
|
|
96
|
+
//# sourceMappingURL=TemplateEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateEngine.d.ts","sourceRoot":"","sources":["../../../src/foundation/engine/TemplateEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAEzC,OAAO,gBAAgB,EAAE,EAAE,eAAe,EAAmB,MAAM,uBAAuB,CAAC;AAC3F,OAAO,IAAI,EAAE,EAAyB,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACnF,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAG5C,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAC9D,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAC9C,OAAO,OAAO,MAAM,2BAA2B,CAAC;AAChD,OAAO,OAAO,MAAM,8BAA8B,CAAC;AACnD,OAAO,SAAS,MAAM,gCAAgC,CAAC;AACvD,OAAO,aAAa,MAAM,oCAAoC,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sCAAsC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;gBAE1C,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAYlE;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACI,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAUhC;;OAEG;IACI,QAAQ,IAAI,KAAK;IAIxB;;OAEG;IACI,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAwBhD;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAsBpC;;OAEG;IACI,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,aAAa;IAyCrE;;OAEG;IACH,OAAO,CAAC,WAAW;IA8CnB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;;;;;;;;OASG;IACI,cAAc,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM;IAiCzG;;OAEG;WACW,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAM/F;;OAEG;WACW,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,gBAAgB;CAI3G;AAGD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAC9E,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import Scope from './Scope.js';
|
|
2
|
+
import Expression from './Expression.js';
|
|
3
|
+
import EscapeHandler from './EscapeHandler.js';
|
|
4
|
+
import TemplateInstance from './TemplateInstance.js';
|
|
5
|
+
import Rule, { SyntaxRule, AttributeRule } from './Rule.js';
|
|
6
|
+
// Import rules
|
|
7
|
+
import ExpressionRule from './rules/syntax/ExpressionRule.js';
|
|
8
|
+
import IfRule from './rules/syntax/IfRule.js';
|
|
9
|
+
import ForRule from './rules/syntax/ForRule.js';
|
|
10
|
+
import RefRule from './rules/attribute/RefRule.js';
|
|
11
|
+
import EventRule from './rules/attribute/EventRule.js';
|
|
12
|
+
import InjectionRule from './rules/attribute/InjectionRule.js';
|
|
13
|
+
/**
|
|
14
|
+
* TemplateEngine - главный класс шаблонизатора.
|
|
15
|
+
* Обрабатывает HTML-шаблон с Rule и создаёт TemplateInstance.
|
|
16
|
+
*/
|
|
17
|
+
export default class TemplateEngine {
|
|
18
|
+
scope;
|
|
19
|
+
options;
|
|
20
|
+
syntaxRules = [];
|
|
21
|
+
attributeRules = [];
|
|
22
|
+
constructor(scope, options) {
|
|
23
|
+
this.scope = scope instanceof Scope ? scope : Scope.from(scope);
|
|
24
|
+
this.options = {
|
|
25
|
+
showAttributeRule: false,
|
|
26
|
+
debugWarnings: true,
|
|
27
|
+
...options
|
|
28
|
+
};
|
|
29
|
+
// Register default rules (sorted by priority)
|
|
30
|
+
this.registerDefaultRules();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Зарегистрировать стандартные правила
|
|
34
|
+
*/
|
|
35
|
+
registerDefaultRules() {
|
|
36
|
+
// Syntax rules
|
|
37
|
+
this.syntaxRules.push(new ForRule());
|
|
38
|
+
this.syntaxRules.push(new IfRule());
|
|
39
|
+
this.syntaxRules.push(new ExpressionRule());
|
|
40
|
+
// Attribute rules
|
|
41
|
+
this.attributeRules.push(new RefRule());
|
|
42
|
+
this.attributeRules.push(new EventRule());
|
|
43
|
+
this.attributeRules.push(new InjectionRule());
|
|
44
|
+
// Sort by priority
|
|
45
|
+
this.syntaxRules.sort((a, b) => a.priority - b.priority);
|
|
46
|
+
this.attributeRules.sort((a, b) => a.priority - b.priority);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Добавить пользовательское правило
|
|
50
|
+
*/
|
|
51
|
+
addRule(rule) {
|
|
52
|
+
if (rule.type === 'syntax') {
|
|
53
|
+
this.syntaxRules.push(rule);
|
|
54
|
+
this.syntaxRules.sort((a, b) => a.priority - b.priority);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.attributeRules.push(rule);
|
|
58
|
+
this.attributeRules.sort((a, b) => a.priority - b.priority);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Получить Scope
|
|
63
|
+
*/
|
|
64
|
+
getScope() {
|
|
65
|
+
return this.scope;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Обработать шаблон и вернуть TemplateInstance
|
|
69
|
+
*/
|
|
70
|
+
parse(template) {
|
|
71
|
+
const templateInstance = new TemplateInstance(this.scope);
|
|
72
|
+
const result = this.processTemplateWithFragments(template, this.scope, templateInstance, null);
|
|
73
|
+
// Устанавливаем корневой фрагмент
|
|
74
|
+
if (result.fragmentId) {
|
|
75
|
+
templateInstance.setRootFragment(result.fragmentId);
|
|
76
|
+
}
|
|
77
|
+
// Add sections and track observables
|
|
78
|
+
for (const section of result.sections) {
|
|
79
|
+
templateInstance.addSection(section);
|
|
80
|
+
// Track observables
|
|
81
|
+
for (const observable of section.result.observables || []) {
|
|
82
|
+
templateInstance.trackObservable(observable, section, (s) => {
|
|
83
|
+
return this.processTemplate(s.sourceTemplate, this.scope);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return templateInstance;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Обработать шаблон с созданием фрагментов
|
|
91
|
+
*/
|
|
92
|
+
processTemplateWithFragments(template, scope, instance, parentFragmentId) {
|
|
93
|
+
const result = this.processTemplate(template, scope);
|
|
94
|
+
// Создаём фрагмент для этого результата
|
|
95
|
+
const fragmentId = instance.createFragment(result.output, template, result.sections, parentFragmentId);
|
|
96
|
+
return {
|
|
97
|
+
...result,
|
|
98
|
+
fragmentId
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Обработать шаблон (внутренний метод, используется Rule для рекурсии)
|
|
103
|
+
*/
|
|
104
|
+
processTemplate(template, scope) {
|
|
105
|
+
const allObservables = [];
|
|
106
|
+
const allSections = [];
|
|
107
|
+
// Step 1: Handle @@ escape sequences
|
|
108
|
+
let processed = EscapeHandler.process(template, (escaped) => {
|
|
109
|
+
let result = escaped;
|
|
110
|
+
// Step 2: Process syntax rules (in priority order)
|
|
111
|
+
for (const rule of this.syntaxRules) {
|
|
112
|
+
result = this.processRule(rule, result, scope, allObservables, allSections);
|
|
113
|
+
}
|
|
114
|
+
// Step 3: Process attribute rules
|
|
115
|
+
for (const rule of this.attributeRules) {
|
|
116
|
+
// Skip injection - processed last
|
|
117
|
+
if (rule.name === 'injection')
|
|
118
|
+
continue;
|
|
119
|
+
result = this.processRule(rule, result, scope, allObservables, allSections);
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
});
|
|
123
|
+
// Step 4: Process injection rules last
|
|
124
|
+
const injectionRule = this.attributeRules.find(r => r.name === 'injection');
|
|
125
|
+
if (injectionRule) {
|
|
126
|
+
processed = this.processRule(injectionRule, processed, scope, allObservables, allSections);
|
|
127
|
+
}
|
|
128
|
+
// Step 5: Handle showAttributeRule option
|
|
129
|
+
if (!this.options.showAttributeRule) {
|
|
130
|
+
processed = this.removeAttributeSyntax(processed);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
output: processed,
|
|
134
|
+
observables: allObservables,
|
|
135
|
+
sections: allSections
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Обработать одно правило
|
|
140
|
+
*/
|
|
141
|
+
processRule(rule, template, scope, observables, sections) {
|
|
142
|
+
const matches = rule.find(template);
|
|
143
|
+
// Sort matches by position (reverse to process from end)
|
|
144
|
+
matches.sort((a, b) => b.start - a.start);
|
|
145
|
+
let result = template;
|
|
146
|
+
for (const match of matches) {
|
|
147
|
+
try {
|
|
148
|
+
const ruleResult = rule.execute(match, scope, this);
|
|
149
|
+
// Track observables
|
|
150
|
+
if (ruleResult.observables) {
|
|
151
|
+
observables.push(...ruleResult.observables);
|
|
152
|
+
}
|
|
153
|
+
// Create section
|
|
154
|
+
const section = {
|
|
155
|
+
rule,
|
|
156
|
+
match,
|
|
157
|
+
result: ruleResult,
|
|
158
|
+
sourceTemplate: match.fullMatch,
|
|
159
|
+
children: [],
|
|
160
|
+
subscriptions: []
|
|
161
|
+
};
|
|
162
|
+
sections.push(section);
|
|
163
|
+
// Replace in template
|
|
164
|
+
result = result.slice(0, match.start) + ruleResult.output + result.slice(match.end);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
console.error(`[TemplateEngine] Error processing rule "${rule.name}":`, error);
|
|
168
|
+
// Continue processing other rules
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Удалить синтаксис атрибутивных Rule из финального HTML
|
|
175
|
+
*/
|
|
176
|
+
removeAttributeSyntax(template) {
|
|
177
|
+
// Remove @[ref], @on[...], @injection[...] patterns that weren't processed
|
|
178
|
+
return template
|
|
179
|
+
.replace(/@\[ref\]\s*=\s*["'][^"']*["']/gi, '')
|
|
180
|
+
.replace(/@on\[[a-zA-Z]+\]\s*=\s*["'][^"']*["']/gi, '')
|
|
181
|
+
.replace(/@injection\[(head|tail)\]\s*=\s*["'][^"']*["']/gi, '');
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Добавить новый шаблон в существующий TemplateInstance.
|
|
185
|
+
* Обрабатывает шаблон и добавляет результат как новый фрагмент.
|
|
186
|
+
* Если instance привязан к контейнерам, DOM обновится автоматически.
|
|
187
|
+
*
|
|
188
|
+
* @param instance - существующий TemplateInstance
|
|
189
|
+
* @param template - новый шаблон для добавления
|
|
190
|
+
* @param customScope - опциональный scope для нового шаблона
|
|
191
|
+
* @returns ID созданного фрагмента
|
|
192
|
+
*/
|
|
193
|
+
appendTemplate(instance, template, customScope) {
|
|
194
|
+
const scope = customScope
|
|
195
|
+
? (customScope instanceof Scope ? customScope : Scope.from(customScope))
|
|
196
|
+
: instance.getScope();
|
|
197
|
+
// Обрабатываем шаблон
|
|
198
|
+
const result = this.processTemplate(template, scope);
|
|
199
|
+
// Создаём фрагмент
|
|
200
|
+
const fragmentId = instance.createFragment(result.output, template, result.sections, null // без родителя - это отдельный фрагмент
|
|
201
|
+
);
|
|
202
|
+
// Добавляем секции и отслеживаем Observable
|
|
203
|
+
for (const section of result.sections) {
|
|
204
|
+
instance.addSection(section);
|
|
205
|
+
for (const observable of section.result.observables || []) {
|
|
206
|
+
instance.trackObservable(observable, section, (s) => {
|
|
207
|
+
return this.processTemplate(s.sourceTemplate, scope);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Вставляем в привязанные контейнеры
|
|
212
|
+
instance.insertAppendedFragment(fragmentId);
|
|
213
|
+
return fragmentId;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Статический метод для быстрой обработки
|
|
217
|
+
*/
|
|
218
|
+
static process(template, scope, options) {
|
|
219
|
+
const engine = new TemplateEngine(scope, options);
|
|
220
|
+
const TemplateInstance = engine.parse(template);
|
|
221
|
+
return TemplateInstance.getTemplate();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Создать TemplateInstance из шаблона
|
|
225
|
+
*/
|
|
226
|
+
static create(template, scope, options) {
|
|
227
|
+
const engine = new TemplateEngine(scope, options);
|
|
228
|
+
return engine.parse(template);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Re-export useful types
|
|
232
|
+
export { Scope, Expression, TemplateInstance, Rule, SyntaxRule, AttributeRule };
|
|
233
|
+
export { ExpressionRule, IfRule, ForRule, RefRule, EventRule, InjectionRule };
|
|
234
|
+
export * from './exceptions/TemplateExceptions.js';
|
|
235
|
+
//# sourceMappingURL=TemplateEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateEngine.js","sourceRoot":"","sources":["../../../src/foundation/engine/TemplateEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import Scope from './Scope.js';
|
|
2
|
+
import Observable from '../api/Observer.js';
|
|
3
|
+
import Rule, { RuleMatch, RuleResult } from './Rule.js';
|
|
4
|
+
/**
|
|
5
|
+
* FragmentChangeEvent - событие изменения конкретного фрагмента
|
|
6
|
+
*/
|
|
7
|
+
export interface FragmentChangeEvent {
|
|
8
|
+
fragmentId: string;
|
|
9
|
+
oldNodes: Node[];
|
|
10
|
+
newNodes: Node[];
|
|
11
|
+
affectedObservables: Observable<any>[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* TemplateSection - секция шаблона, связанная с Rule
|
|
15
|
+
*/
|
|
16
|
+
export interface TemplateSection {
|
|
17
|
+
/** Rule который создал эту секцию */
|
|
18
|
+
rule: Rule;
|
|
19
|
+
/** Оригинальный match */
|
|
20
|
+
match: RuleMatch;
|
|
21
|
+
/** Текущий результат */
|
|
22
|
+
result: RuleResult;
|
|
23
|
+
/** Исходный шаблон секции (для пересоздания) */
|
|
24
|
+
sourceTemplate: string;
|
|
25
|
+
/** Дочерние секции */
|
|
26
|
+
children: TemplateSection[];
|
|
27
|
+
/** Observable подписки для отслеживания */
|
|
28
|
+
subscriptions: Array<{
|
|
29
|
+
observable: Observable<any>;
|
|
30
|
+
unsubscribe: () => void;
|
|
31
|
+
}>;
|
|
32
|
+
/** ID фрагмента, к которому принадлежит секция */
|
|
33
|
+
fragmentId?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* FragmentBinding - привязка фрагмента
|
|
37
|
+
*/
|
|
38
|
+
export interface FragmentBinding {
|
|
39
|
+
/** Уникальный ID фрагмента */
|
|
40
|
+
id: string;
|
|
41
|
+
/** Текущий HTML контент фрагмента (с placeholder-ами для дочерних) */
|
|
42
|
+
html: string;
|
|
43
|
+
/** Исходный шаблон (до обработки) */
|
|
44
|
+
sourceTemplate: string;
|
|
45
|
+
/** Секции, входящие в этот фрагмент */
|
|
46
|
+
sections: TemplateSection[];
|
|
47
|
+
/** Observable, от которых зависит фрагмент */
|
|
48
|
+
observables: Set<Observable<any>>;
|
|
49
|
+
/** ID родительского фрагмента (null для корневого) */
|
|
50
|
+
parentId: string | null;
|
|
51
|
+
/** ID дочерних фрагментов (placeholder-ы) */
|
|
52
|
+
childIds: string[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* ContainerBinding - привязка к DOM-контейнеру
|
|
56
|
+
*/
|
|
57
|
+
export interface ContainerBinding {
|
|
58
|
+
/** DOM-контейнер */
|
|
59
|
+
container: Element;
|
|
60
|
+
/** Маркеры фрагментов в этом контейнере: fragmentId -> { start, end, nodes } */
|
|
61
|
+
markers: Map<string, {
|
|
62
|
+
startMarker: Comment;
|
|
63
|
+
endMarker: Comment;
|
|
64
|
+
nodes: Node[];
|
|
65
|
+
}>;
|
|
66
|
+
/** Функции отписки событий для этого контейнера */
|
|
67
|
+
eventUnbinders: Array<() => void>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* TemplateInstance - динамический шаблон страницы.
|
|
71
|
+
*
|
|
72
|
+
* Поддерживает:
|
|
73
|
+
* - Множество мелких фрагментов, каждый обновляется независимо
|
|
74
|
+
* - Множество container bindings
|
|
75
|
+
* - Автоматическое обновление DOM при изменении Observable
|
|
76
|
+
* - bind/unbind для refs и events
|
|
77
|
+
*/
|
|
78
|
+
export default class TemplateInstance {
|
|
79
|
+
private scope;
|
|
80
|
+
private sections;
|
|
81
|
+
/** Все фрагменты шаблона */
|
|
82
|
+
private fragments;
|
|
83
|
+
/** ID корневого фрагмента */
|
|
84
|
+
private rootFragmentId;
|
|
85
|
+
/** Счётчик для генерации ID фрагментов */
|
|
86
|
+
private fragmentIdCounter;
|
|
87
|
+
/** Observers for fragment changes */
|
|
88
|
+
private fragmentChangeObserver;
|
|
89
|
+
/** Группировка секций по Observable */
|
|
90
|
+
private observableTrackings;
|
|
91
|
+
/** Привязки к контейнерам */
|
|
92
|
+
private containerBindings;
|
|
93
|
+
constructor(scope: Scope);
|
|
94
|
+
/**
|
|
95
|
+
* Получить Scope
|
|
96
|
+
*/
|
|
97
|
+
getScope(): Scope;
|
|
98
|
+
/**
|
|
99
|
+
* Получить все секции
|
|
100
|
+
*/
|
|
101
|
+
getSections(): TemplateSection[];
|
|
102
|
+
/**
|
|
103
|
+
* Получить все фрагменты
|
|
104
|
+
*/
|
|
105
|
+
getAllFragments(): Map<string, FragmentBinding>;
|
|
106
|
+
/**
|
|
107
|
+
* Получить фрагмент по ID
|
|
108
|
+
*/
|
|
109
|
+
getFragmentBinding(id: string): FragmentBinding | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Получить финальный HTML (собранный из всех фрагментов)
|
|
112
|
+
*/
|
|
113
|
+
getTemplate(): string;
|
|
114
|
+
/**
|
|
115
|
+
* Создать новый фрагмент и вернуть его ID
|
|
116
|
+
*/
|
|
117
|
+
createFragment(html: string, sourceTemplate: string, sections?: TemplateSection[], parentId?: string | null): string;
|
|
118
|
+
/**
|
|
119
|
+
* Установить корневой фрагмент
|
|
120
|
+
*/
|
|
121
|
+
setRootFragment(id: string): void;
|
|
122
|
+
/**
|
|
123
|
+
* Добавить секцию шаблона
|
|
124
|
+
*/
|
|
125
|
+
addSection(section: TemplateSection): void;
|
|
126
|
+
/**
|
|
127
|
+
* Вставить добавленный фрагмент во все привязанные контейнеры.
|
|
128
|
+
* Вызывается после appendTemplate.
|
|
129
|
+
*/
|
|
130
|
+
insertAppendedFragment(fragmentId: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Привязать события только для нового фрагмента
|
|
133
|
+
*/
|
|
134
|
+
private bindEventsForNewFragment;
|
|
135
|
+
/**
|
|
136
|
+
* Подписаться на изменения фрагментов
|
|
137
|
+
*/
|
|
138
|
+
onFragmentChange(listener: (event: FragmentChangeEvent) => void): () => void;
|
|
139
|
+
/**
|
|
140
|
+
* Подписаться на Observable и автоматически пересоздавать секцию
|
|
141
|
+
*/
|
|
142
|
+
trackObservable(observable: Observable<any>, section: TemplateSection, rebuild: (section: TemplateSection) => RuleResult): () => void;
|
|
143
|
+
/**
|
|
144
|
+
* Привязать к контейнеру.
|
|
145
|
+
* Вставляет DOM, вызывает bindRefs, processInjections и bindEvents.
|
|
146
|
+
*/
|
|
147
|
+
bind(container: Element): void;
|
|
148
|
+
/**
|
|
149
|
+
* Отвязать от контейнера.
|
|
150
|
+
* Отвязывает refs и events, но оставляет DOM.
|
|
151
|
+
*/
|
|
152
|
+
unbind(container: Element): void;
|
|
153
|
+
/**
|
|
154
|
+
* Привязать refs к элементам.
|
|
155
|
+
* Если есть контейнеры - привязывает для них.
|
|
156
|
+
* Если нет - создаёт временный DocumentFragment и привязывает refs из него.
|
|
157
|
+
*/
|
|
158
|
+
bindRefs(): void;
|
|
159
|
+
/**
|
|
160
|
+
* Привязать refs из DocumentFragment (без контейнера)
|
|
161
|
+
*/
|
|
162
|
+
private bindRefsForFragment;
|
|
163
|
+
/**
|
|
164
|
+
* Отвязать refs (для всех контейнеров)
|
|
165
|
+
*/
|
|
166
|
+
unbindRefs(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Привязать события (для всех контейнеров)
|
|
169
|
+
*/
|
|
170
|
+
bindEvents(): void;
|
|
171
|
+
/**
|
|
172
|
+
* Отвязать события (для всех контейнеров)
|
|
173
|
+
*/
|
|
174
|
+
unbindEvents(): void;
|
|
175
|
+
/**
|
|
176
|
+
* Очистить все подписки и bindings
|
|
177
|
+
*/
|
|
178
|
+
dispose(): void;
|
|
179
|
+
/**
|
|
180
|
+
* Вставить все фрагменты в контейнер с маркерами
|
|
181
|
+
*/
|
|
182
|
+
private insertFragmentsIntoContainer;
|
|
183
|
+
/**
|
|
184
|
+
* Рекурсивно вставить фрагмент и его дочерние
|
|
185
|
+
*/
|
|
186
|
+
private insertFragmentRecursive;
|
|
187
|
+
/**
|
|
188
|
+
* Создать ноды из HTML строки
|
|
189
|
+
*/
|
|
190
|
+
private createNodesFromHtml;
|
|
191
|
+
/**
|
|
192
|
+
* Собрать HTML из фрагмента (рекурсивно заменяя placeholder-ы)
|
|
193
|
+
*/
|
|
194
|
+
private buildHtmlFromFragment;
|
|
195
|
+
/**
|
|
196
|
+
* Привязать refs для конкретного контейнера
|
|
197
|
+
*/
|
|
198
|
+
private bindRefsForContainer;
|
|
199
|
+
/**
|
|
200
|
+
* Обработать инжекции для конкретного контейнера.
|
|
201
|
+
* Находит элементы с data-injection-* атрибутами и перемещает их в целевые элементы.
|
|
202
|
+
*/
|
|
203
|
+
private processInjectionsForContainer;
|
|
204
|
+
/**
|
|
205
|
+
* Отвязать refs для конкретного контейнера
|
|
206
|
+
*/
|
|
207
|
+
private unbindRefsForContainer;
|
|
208
|
+
/**
|
|
209
|
+
* Привязать события для конкретного контейнера
|
|
210
|
+
*/
|
|
211
|
+
private bindEventsForContainer;
|
|
212
|
+
/**
|
|
213
|
+
* Привязать события к одному элементу
|
|
214
|
+
*/
|
|
215
|
+
private bindEventsToElement;
|
|
216
|
+
/**
|
|
217
|
+
* Перестроить фрагменты при изменении Observable
|
|
218
|
+
*/
|
|
219
|
+
private rebuildFragmentsForObservable;
|
|
220
|
+
/**
|
|
221
|
+
* Обновить фрагмент во всех контейнерах
|
|
222
|
+
*/
|
|
223
|
+
private updateFragmentInAllContainers;
|
|
224
|
+
/**
|
|
225
|
+
* Отвязать события от нод
|
|
226
|
+
*/
|
|
227
|
+
private unbindEventsFromNodes;
|
|
228
|
+
/**
|
|
229
|
+
* Отписаться от вложенных Observable в секции
|
|
230
|
+
*/
|
|
231
|
+
private unsubscribeSectionNested;
|
|
232
|
+
/**
|
|
233
|
+
* Отписаться от всех Observable в секции
|
|
234
|
+
*/
|
|
235
|
+
private unsubscribeSection;
|
|
236
|
+
/**
|
|
237
|
+
* @deprecated Используйте bind(container)
|
|
238
|
+
*/
|
|
239
|
+
createDOMFragment(): DocumentFragment;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=TemplateInstance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateInstance.d.ts","sourceRoot":"","sources":["../../../src/foundation/engine/TemplateInstance.ts"],"names":[],"mappings":"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"}
|